HttpWebRequest:如何通过带有x-www-form-enclosed的WebRequest在Canada Post上找到邮政编码? [英] HttpWebRequest: How to find a postal code at Canada Post through a WebRequest with x-www-form-enclosed?
问题描述
我目前正在编写一些测试,以便通过Windows Forms进行Internet交互来提高自己的技能.其中一种测试是找到应该由加拿大邮政网站返回的邮政编码.
I'm currently writing some tests so that I may improve my skills with the Internet interaction through Windows Forms. One of those tests is to find a postal code which should be returned by Canada Post website.
- 我的默认URL设置设置为: http://www.canadapost.ca/cpotools/apps/fpc/personal/findByCity?execution=e4s1
- 必填表格字段为:街道编号,街道名称,城市,省
- contentType是"application/x-www-form-enclosed"
- My default URL setting is set to: http://www.canadapost.ca/cpotools/apps/fpc/personal/findByCity?execution=e4s1
- The required form fields are: streetNumber, streetName, city, province
- The contentType is "application/x-www-form-enclosed"
编辑:请考虑将值"application/x-www-form-encoded"(而不是第3点的值)作为contentType. (感谢EricLaw-MSFT!)
Please consider the value "application/x-www-form-encoded" instead of point 3 value as the contentType. (Thanks EricLaw-MSFT!)
我得到的结果不是预期的结果.我获得了页面的HTML源代码,可以在其中手动输入信息以查找邮政编码,但是找不到包含已找到邮政编码的HTML源代码.知道我在做什么错吗?
The result I get is not the result expected. I get the HTML source code of the page where I could manually enter the information to find the postal code, but not the HTML source code with the found postal code. Any idea of what I'm doing wrong?
我应该考虑采用XML方式吗?首先可以匿名搜索《加拿大邮政》吗?
Shall I consider going the XML way? Is it first of all possible to search on Canada Post anonymously?
这里有一个代码示例,可以提供更好的描述:
Here's a code sample for better description:
public static string FindPostalCode(ICanadadianAddress address) {
var postData = string.Concat(string.Format("&streetNumber={0}", address.StreetNumber)
, string.Format("&streetName={0}", address.StreetName)
, string.Format("&city={0}", address.City)
, string.Format("&province={0}", address.Province));
var encoding = new ASCIIEncoding();
byte[] postDataBytes = encoding.GetBytes(postData);
request = (HttpWebRequest)WebRequest.Create(DefaultUrlSettings);
request.ImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Anonymous;
request.Container = new CookieContainer();
request.Timeout = 10000;
request.ContentType = contentType;
request.ContentLength = postDataBytes.LongLength;
request.Method = @"post";
var senderStream = new StreamWriter(request.GetRequestStream());
senderStream.Write(postDataBytes, 0, postDataBytes.Length);
senderStream.Close();
string htmlResponse = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd();
return processedResult(htmlResponse); // Processing the HTML source code parsing, etc.
}
从我的角度看,我似乎陷入了瓶颈.我找不到出路的理想结果.
I seem stuck in a bottle neck in my point of view. I find no way out to the desired result.
编辑:似乎必须为此站点的ContentType设置参数.让我解释一下.
There seems to have to parameters as for the ContentType of this site. Let me explain.
- 其中一个带有元"变量的变量规定如下:
- 然后是另一个,其代码如下:
元http-equiv ="Content-Type" content ="application/xhtml + xml, text/xml,text/html; charset = utf-8"
meta http-equiv="Content-Type" content="application/xhtml+xml, text/xml, text/html; charset=utf-8"
form id ="fpcByAdvancedSearch:fpcSearch" name ="fpcByAdvancedSearch:fpcSearch" method ="post" action ="/cpotools/apps/fpc/personal/findByCity?execution = e1s1" enctype ="application/x-www-表单编码"
form id="fpcByAdvancedSearch:fpcSearch" name="fpcByAdvancedSearch:fpcSearch" method="post" action="/cpotools/apps/fpc/personal/findByCity?execution=e1s1" enctype="application/x-www-form-urlencoded"
我的问题如下:我必须坚持哪一个?
My question is the following: With which one do I have to stick?
让我猜想,第一个ContentType被认为是第二个ContentType仅用于对函数的另一个请求,或者在发布数据时是这样吗?
Let me guess, the first ContentType is to be considered as the second is only for another request to a function or so when the data is posted?
编辑:根据要求,在该问题下列出了与我更接近的解决方案: WebRequest:如何查找针对此ContentType =" application/xhtml + xml,text/xml,text/html使用WebRequest的邮政编码; charset = utf-8"?
As per request, the closer to the solution I am is listed under this question: WebRequest: How to find a postal code using a WebRequest against this ContentType="application/xhtml+xml, text/xml, text/html; charset=utf-8"?
感谢您的帮助! :-)
Thanks for any help! :-)
推荐答案
我正在尝试查看不使用WebClient类的原因:-
I'm trying to see a reason why you are not using the WebClient class:-
var fields = new NameValueCollection();
fields.Add("streetnumber", address.StreetNumber);
fields.Add("streetname", address.StreetName);
fields.Add("city", address.City);
fields.Add("province", address.Province);
var wc = new WebClient();
byte[] resultData = wc.UploadValues(url, fields);
string result = Encoding.Default.GetString(resultData);
发送结果时,您可能要检查服务器使用的编码,如果它使用UTF-8,则将最后一行更改为:-
You might want to check the encoding used by the server when sending the results, if it uses UTF-8 change the last line to:-
string result = Encoding.UTF8.GetString(resultData);
我在您的原始代码中发现了一些问题:-
Some issues I spot in your orginal code:-
- 第一个字段以&为前缀,不应在该字段出现.
- 您需要在每个字段值上使用
Uri.EscapeDataString
调用. - 您正在尝试围绕
GetRequestStream
的结果构造一个内存流,即使MemoryStream
具有这样的构造函数,我也看不到能实现什么,但无论如何都没有.只需直接写入GetRequestStream
返回的流即可
- The first field is prefixed with &, that shouldn't be there.
- You need call use
Uri.EscapeDataString
on each field value. - You are attempting to construct a memory stream around the result of
GetRequestStream
, I can't see what that would achieve even ifMemoryStream
had such a constructor but it doesn't anyway. Just write directly to the stream returned byGetRequestStream
如果您已这样做,请获取一份 fiddler 的副本,以便您观察标准时出现的情况表单成功请求数据以及您的代码在做什么.
If you have already done so get yourself a copy of fiddler so you can observe what occurs when a standard form requests the data sucessfully and what your code is doing.
编辑:如果您有证据表明缺少Cookie容器是导致WebClient无法正常工作的原因,则可以尝试以下方法:-
Edit: If you have evidence that the lack of a cookie container is what causes WebClient not to work then you could try this approach:-
public class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest (Uri address)
{
WebRequest request = (WebRequest) base.GetWebRequest (address);
request.Container = new CookieContainer();
return request;
}
}
现在使用上面的代码来代替实例化WebClient
实例MyWebClient
.
Now use my code above to but instead od instancing WebClient
instance MyWebClient
instead.
这篇关于HttpWebRequest:如何通过带有x-www-form-enclosed的WebRequest在Canada Post上找到邮政编码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!