3

我目前正在编写一些测试,以便通过 Windows 窗体提高我的 Internet 交互技能。其中一项测试是查找应由加拿大邮政网站返回的邮政编码。

  1. 我的默认 URL 设置设置为:http ://www.canadapost.ca/cpotools/apps/fpc/personal/findByCity?execution=e4s1
  2. 所需的表单字段是:streetNumberstreetNamecityprovince
  3. 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"

  • 另一个后来的代码被读作:

form 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; 字符集=utf-8”?

谢谢你的帮助!:-)

4

2 回答 2

1

我试图找出您不使用 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);

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

  1. 第一个字段以 & 为前缀,不应该存在。
  2. Uri.EscapeDataString您需要在每个字段值上调用使用。
  3. 您正在尝试围绕 的结果构建一个内存流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;
    }
}

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

于 2009-09-18T13:45:57.197 回答
1

HTTPWebRequest 将返回请求的 URL 的内容。如果是 HTML 页面,它将返回 HTML 标记。如果页面内容是 XML,那么它将返回 XML 标记。

听起来你需要的是一个 Web 服务。我会查看该站点是否有任何网络服务可用于处理该类型的请求。如果他们这样做,那么它将返回 XML、JSON 标记以响应您的查询。否则,您将不得不解析请求的输出。

于 2009-09-18T13:46:37.557 回答