WebRequest: Как найти почтовый код, используя WebRequest против этого ContentType = «Application/xhtml+XML, Text/XML, Text/HTML; charset = utf-8 ”?
-
12-09-2019 - |
Вопрос
Я впервые опубликовал это: Httpwebrequest: Как найти почтовый код в Канаде пост через WebRequest с информированным X-WWW-Form?.
Следуя предложениям Энтонивджонса, я изменил свой код после его предложений.
В продолжении моего расследования я со временем заметил, что контент-тип канадского поста с большей вероятностью будет "Application/xhtml+xml, text/xml, text/html; charset = utf-8".
Мои вопросы:
- Как нам WebRequest против такого веб-сайта контента?
- Должны ли мы продолжать идти с объектом namevalueCollection?
- По словам Скотта Ланса, который щедро предоставил мне драгоценную информацию в моем предыдущем вопросе, 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, которое я получаю сейчас: «Невозможно отправить тело контента с этим типом глагола». (Это перевод из французского исключения "невозможно D'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, который фактически показывает вам ответ HTML, содержащий почтовый код.
Что еще хуже, страница на шаге № 3 должна знать, что файлы cookie установлены на шаге № 1. Итак, вам нужно использовать то же самое CookieContainer
Для всех трех запросов (хотя может быть достаточно, чтобы отправить то же самое CookieContainer
Только к #2 и #3).
Кроме того, вам также может потребоваться отправить дополнительные заголовки HTTP в этих запросах, например, принять. Я подозреваю, где вы сталкиваетесь с проблемами, что это то, что HttpwebRequest по умолчанию перенаправляется прозрачно для вас- но когда он прозрачно перенаправляет, это может не добавить правильные заголовки HTTP, необходимые для выдачи браузера.
Решение состоит в том, чтобы установить HttpWebRequest
S. AllowAutoRedirect
Свойство, чтобы ложь, и обрабатывать перенаправление самостоятельно. Другими словами, как только первый запрос вернет перенаправление, вам нужно вытащить URL в HttpWebResponse
S. Location:
заголовок. Тогда вам нужно будет создать новый HttpWebRequest
(На этот раз регулярный запрос получить, а не пост) для этого URL. Помните, чтобы отправить тот же файл cookie! ( CookieContainer
Класс делает это очень легким)
Вам также может потребоваться дополнительный запрос (#1 в моем списке выше), чтобы настроить файл cookie. Если бы я был вами, я бы предположил, что это требуется, просто для того, чтобы устранить ее как проблему и попытаться удалить этот шаг позже и посмотреть, работает ли ваше решение.
Вы захотите скачать и использовать Fiddler (www.fiddlertool.com) помочь вам со всем этим. Fiddler позволяет вам смотреть HTTP -запросы, проходящие через проволоку, и позволяет вам (через функцию Builder) позволяет создавать HTTP -запросы, чтобы вы могли видеть, какие заголовки фактически требуются.