我目前正在编写一些测试,以便通过Windows Forms进行Internet交互来提高自己的技能。这些测试之一是查找应该由加拿大邮政网站返回的邮政编码。


我的默认URL设置设置为:http://www.canadapost.ca/cpotools/apps/fpc/personal/findByCity?execution=e4s1
所需的表单字段为:streetNumber,streetName,城市,省
contentType是“ application / x-www-form-enclosed”



  编辑:请考虑将值“ application / x-www-form-encoded”而不是第3点的值作为contentType。 (感谢EricLaw-MSFT!)
  
  我得到的结果不是预期的结果。我获得了页面的HTML源代码,可以在其中手动输入信息以查找邮政编码,但是找不到包含已找到邮政编码的HTML源代码。有什么想法我做错了吗?
  
  我应该考虑采用XML方式吗?首先可以匿名搜索《加拿大邮政》吗?


这是一个代码示例,可以提供更好的描述:

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.
}


从我的角度看,我似乎陷入了瓶颈。我找不到出路的理想结果。


  编辑:似乎必须为该站点的ContentType参数。让我解释。



有一个带有“元”变量的变量,它规定了以下内容:



  meta http-equiv =“ Content-Type” content =“ application / xhtml + xml,
  text / xml,text / html; charset = utf-8“



后来的另一个代码为:



  表单id =“ fpcByAdvancedSearch:fpcSearch” name =“ fpcByAdvancedSearch:fpcSearch” method =“ post” action =“ / cpotools / apps / fpc / personal / findByCity?execution = e1s1” enctype =“ application / x-www-form-urlencoded ”


我的问题如下:我必须坚持哪一个?

让我猜测一下,第一个ContentType被认为是第二个,仅当另一个函数请求请求时才发布数据?


  编辑:根据要求,在这个问题下列出了更接近我的解决方案:
  WebRequest: How to find a postal code using a WebRequest against this ContentType=”application/xhtml+xml, text/xml, text/html; charset=utf-8”?


谢谢你的帮助! :-)

最佳答案

我正在尝试查看您不使用WebClient类的原因:-

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,请将最后一行更改为:-

string result = Encoding.UTF8.GetString(resultData);


我在您的原始代码中发现了一些问题:


第一个字段以&开头,不应存在。
您需要在每个字段值上调用use Uri.EscapeDataString
您正在尝试围绕GetRequestStream的结果构造一个内存流,即使MemoryStream具有这样的构造函数,我也看不到能实现什么,但是无论如何都没有。只需直接写入GetRequestStream返回的流


如果您已经这样做了,请给自己一份fiddler的副本,这样您可以观察到标准表单成功请求数据时会发生什么以及代码在做什么。

编辑:如果有证据表明缺少cookie容器是导致WebClient无法正常工作的原因,则可以尝试以下方法:

public class MyWebClient : WebClient
{

    protected override WebRequest GetWebRequest (Uri address)
    {
      WebRequest request = (WebRequest) base.GetWebRequest (address);

      request.Container = new CookieContainer();
      return request;
    }
}


现在,使用上面的代码来代替实例化WebClient实例MyWebClient

关于c# - HttpWebRequest:如何通过带有x-www-form-enclosed的WebRequest在Canada Post上找到邮政编码?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1444563/

10-10 21:40