WebRequest: Как найти почтовый код, используя WebRequest против этого ContentType = «Application/xhtml+XML, Text/XML, Text/HTML; charset = utf-8 ”?

StackOverflow https://stackoverflow.com/questions/1455567

Вопрос

Я впервые опубликовал это: Httpwebrequest: Как найти почтовый код в Канаде пост через WebRequest с информированным X-WWW-Form?.

Следуя предложениям Энтонивджонса, я изменил свой код после его предложений.

В продолжении моего расследования я со временем заметил, что контент-тип канадского поста с большей вероятностью будет "Application/xhtml+xml, text/xml, text/html; charset = utf-8".

Мои вопросы:

  1. Как нам WebRequest против такого веб-сайта контента?
  2. Должны ли мы продолжать идти с объектом namevalueCollection?
  3. По словам Скотта Ланса, который щедро предоставил мне драгоценную информацию в моем предыдущем вопросе, WebRequest должен вернуть тип информации, какой бы ни был тип контента, я что-то здесь упускаю?
  4. Должен ли я изменить свой код из-за изменения типа контента?

Вот мой код, чтобы было бы легче понять мой прогресс.

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

Линия, которая вызывает исключение, указана с "=>". Кажется, что я не могу использовать как метод, но это то, что мне сказали, чтобы я делал ...

Есть идеи, что мне здесь не хватает? Я пытаюсь сделать то, что Джастин (см. Ответ) рекомендовал мне сделать.

Заранее благодарю за любую помощь! :-)

Это было полезно?

Решение

Как введение в мир экрана, вы выбрали очень сложный обоснование! Страница поиска постов Канады работает так:

  1. Первая страница - это форма, которая принимает значения адреса
  2. Эта страница публикует второй URL.
  3. Этот второй URL, в свою очередь, перенаправляет (с использованием перенаправления HTTP 302) на третий URL, который фактически показывает вам ответ HTML, содержащий почтовый код.

Что еще хуже, страница на шаге № 3 должна знать, что файлы cookie установлены на шаге № 1. Итак, вам нужно использовать то же самое CookieContainer Для всех трех запросов (хотя может быть достаточно, чтобы отправить то же самое CookieContainer Только к #2 и #3).

Кроме того, вам также может потребоваться отправить дополнительные заголовки HTTP в этих запросах, например, принять. Я подозреваю, где вы сталкиваетесь с проблемами, что это то, что HttpwebRequest по умолчанию перенаправляется прозрачно для вас- но когда он прозрачно перенаправляет, это может не добавить правильные заголовки HTTP, необходимые для выдачи браузера.

Решение состоит в том, чтобы установить HttpWebRequestS. AllowAutoRedirect Свойство, чтобы ложь, и обрабатывать перенаправление самостоятельно. Другими словами, как только первый запрос вернет перенаправление, вам нужно вытащить URL в HttpWebResponseS. Location: заголовок. Тогда вам нужно будет создать новый HttpWebRequest (На этот раз регулярный запрос получить, а не пост) для этого URL. Помните, чтобы отправить тот же файл cookie! ( CookieContainer Класс делает это очень легким)

Вам также может потребоваться дополнительный запрос (#1 в моем списке выше), чтобы настроить файл cookie. Если бы я был вами, я бы предположил, что это требуется, просто для того, чтобы устранить ее как проблему и попытаться удалить этот шаг позже и посмотреть, работает ли ваше решение.

Вы захотите скачать и использовать Fiddler (www.fiddlertool.com) помочь вам со всем этим. Fiddler позволяет вам смотреть HTTP -запросы, проходящие через проволоку, и позволяет вам (через функцию Builder) позволяет создавать HTTP -запросы, чтобы вы могли видеть, какие заголовки фактически требуются.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top