WebRequest:如何使用此contentType =“ application/xhtml+xml,text/xml,text/xml,text/html; charset = utf-8“?
-
12-09-2019 - |
题
我首先发布了: httpwebrequest:如何通过X-WWW形式封闭的WebRequest在加拿大邮政上找到邮政编码?.
按照Anthonywjones的建议,我按照他的建议更改了代码。
在继续我的询问时,我注意到随着时间的推移,加拿大邮政的内容类型更可能是 “应用程序/xhtml+xml,text/xml,text/html; charset = utf-8”.
我的问题是:
- 我们如何与这样的内容类型网站进行网络限制?
- 我们是否必须继续使用名称valuecollection对象?
- 根据斯科特·兰斯(Scott Lance)的说法,他在我的先前问题中向我提供了宝贵的信息,WebRequest将返回内容类型的信息类型,我在这里错过了什么吗?
- 由于内容类型的更改,我必须更改代码吗?
这是我的代码,以便更容易理解我的进度。
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;
}
}
}
该代码实际上返回表单的HTML源代码,必须填写所需的信息,以便使用邮政编码搜索处理。我希望获得HTML源代码或所发现的邮政编码的任何内容。
编辑: 这是我现在得到的WebException:“无法用这种动词发送内容主体。” (这是法国例外的翻译,“ Envoyer Un Corps de contenu avec ce type de verbe。”)
这是我的代码:
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;
}
导致异常的线指向“ =>”。看来我不能用作方法,但是这就是告诉我我要做的...
知道我在这里缺少什么吗?我尝试做贾斯汀(见答案)建议我做的事情。
在此先感谢您的任何帮助! :-)
解决方案
为了介绍屏幕剪彩的世界,您选择了一个非常困难的箱子!加拿大邮政的查找页面这样工作:
- 第一页是接受地址值的表格
- 此页面发布到第二个URL。
- 第二个URL依次重定向(使用HTTP 302重定向)到第三个URL,该URL实际上向您显示了包含邮政编码的HTML响应。
更糟糕的是,步骤#3中的页面需要知道步骤1中的cookie设置。因此,您需要使用相同的 CookieContainer
对于所有三个请求(尽管可能足以发送相同的 CookieContainer
仅到#2和#3)。
此外,您可能还需要在这些请求中发送其他HTTP标头,例如接受。我怀疑您遇到问题的地方是,默认情况下,httpwebrequest会为您透明地处理重定向 - 但是当它透明地重定向时,它可能不会添加正确的HTTP标头来模仿浏览器。
解决方案是设置 HttpWebRequest
' AllowAutoRedirect
财产为错误,并处理重定向自己。换句话说,一旦第一个请求返回重定向,您需要在 HttpWebResponse
' Location:
标题。那么您需要创建一个新的 HttpWebRequest
(这次是常规获取请求,而不是帖子)对于该URL。 remeber发送同一个饼干! (这 CookieContainer
课程使这很容易)
您可能还需要提出附加请求(上面的列表中的#1)才能设置会话cookie。如果我是您,我会假设这是必需的,只是为了消除问题,然后尝试以后删除该解决方案,看看您的解决方案是否仍然有效。
您需要下载和使用提琴手(www.fiddlertool.com)帮助您完成所有这些。 Fiddler允许您观看越过电线的HTTP请求,并允许您(通过请求构建器功能)允许您创建HTTP请求,以便您可以查看实际需要哪些标头。