I first posted this: HttpWebRequest: How to find a postal code at Canada Post through a WebRequest with x-www-form-enclosed?.
Following AnthonyWJones suggestions, I changed my code following his suggestions.
On a continuation of my inquiry, I have noticed with time that the content-type of Canada Post is more likely to be "application/xhtml+xml, text/xml, text/html; charset=utf-8".
My questions are:
- How do we webrequest against such a content-type website?
- Do we have to keep on going with the NameValueCollection object?
- According to Scott Lance who generously provided me with precious information within my preceding question, the WebRequest shall return the type of information whatever the content-type may be, am I missing something here?
- Do I have to change my code because of the content-type change?
Here is my code so that it might be easier to understand my progress.
internal class PostalServicesFactory {
/// <summary>
/// Initializes an instance of GI.BusinessSolutions.Services.PostalServices.Types.PostalServicesFactory class.
/// </summary>
internal PostalServicesFactory() {
}
/// <summary>
/// Finds a Canadian postal code for the provided Canadian address.
/// </summary>
/// <param name="address">The instance of GI.BusinessSolutions.Services.PostalServices.ICanadianCityAddress for which to find the postal code.</param>
/// <returns>The postal code found, otherwise null.</returns>
internal string FindPostalCode(ICanadianCityAddress address) {
if (address == null)
throw new InvalidOperationException("No valid address specified.");
using (ServicesWebClient swc = new ServicesWebClient()) {
var values = new System.Collections.Specialized.NameValueCollection();
values.Add("streetNumber", address.StreetNumber.ToString());
values.Add("numberSuffix", address.NumberSuffix);
values.Add("suite", address.Suite);
values.Add("streetName", address.StreetName);
values.Add("streetDirection", address.StreetDirection);
values.Add("city", address.City);
values.Add("province", address.Province);
byte[] resultData = swc.UploadValues(@"http://www.canadapost.ca/cpotools/apps/fpc/personal/findByCity", "POST", values);
return Encoding.UTF8.GetString(resultData);
}
}
private class ServicesWebClient : WebClient {
public ServicesWebClient()
: base() {
}
protected override WebRequest GetWebRequest(Uri address) {
var request = (HttpWebRequest)base.GetWebRequest(address);
request.CookieContainer = new CookieContainer();
return request;
}
}
}
This code actually returns the HTML source code of the form one must fill with the required information in order to process with the postal code search. What I wish is to get the HTML source code or whatever it may be with the found postal code.
EDIT: Here's the WebException I get now: "Unable to send a content body with this type of verb." (This is a translation from the French exception "Impossible d'envoyer un corps de contenu avec ce type de verbe.")
Here's my code:
internal string FindPostalCode(string url, ICanadianAddress address) {
string htmlResult = null;
using (var swc = new ServiceWebClient()) {
var values = new System.Collections.Specialized.NameValueCollection();
values.Add("streetNumber", address.StreetNumber.ToString());
values.Add("numberSuffix", address.NumberSuffix);
values.Add("suite", address.Suite);
values.Add("streetName", address.StreetName);
values.Add("streetDirection", address.StreetDirection);
values.Add("city", address.City);
values.Add("province", address.Province);
swc.UploadValues(url, @"POST", values);
string redirectUrl = swc.ResponseHeaders.GetValues(@"Location")[0];
=> swc.UploadValues(redirectUrl, @"GET", values);
}
return htmlResult;
}
The line that causes the exception is pointed with "=>". It seems that I can't use GET as the method, yet this is what has been told me me to do...
Any idea what I'm missing here? I try to do what Justin (see answer) recommended me to do.
Thanks in advance for any help! :-)