30. May 2011 · Write a comment · Categories: C#, Misc

Никогда не стоит преуменьшать опасность гугления кода. Вас может увлечь за толпой леммингов. Например, попытавшись найти пример отправки POST-запроса из C# вы получите кучу примеров использования HttpWebRequest. В 95% случаев ручная работа с WebRequest не оправдана ничем, кроме незнания стандартной библиотеки. WebRequest обычно тянет за собой:

  • 10-20 строк кода на каждый запрос.
  • Ручное выставление Cookie Container для каждого запроса.
  • Неочевидную последовательность using-ов (для тех, кто знает о IDisposable).
  • Ссылку на System.Web, и отказ от клиентcкого профиля.
  • В то же время стандарный класс WebClient умеет практически все, ради чего вы пишете код с WebRequest/Response/Stream и прочим шаманством. Он даже умеет энкодить отправляемые значения без HttpUtility.

    Отправка GET-запросов:

    С WebRequest (без using, мне повезет):

    System.Net.WebRequest reqGET = System.Net.WebRequest.Create("http://site.ru/");
    System.Net.WebResponse resp = reqGET.GetResponse();
    System.IO.Stream stream = resp.GetResponseStream();
    System.IO.StreamReader sr = new System.IO.StreamReader(stream);
    string s = sr.ReadToEnd();
    Console.WriteLine(s);

    С WebClient:

    using (var client = new System.Net.WebClient())
    {
        string s = client.DownloadString("http://site.ru/");
        Console.WriteLine(s);
    }

    Отправка POST-запросов:

    С WebRequest (опять без using):

    System.Net.WebRequest reqPOST = System.Net.WebRequest.Create("http://site.ru/send.php");
    reqPOST.Method = "POST";
    reqPOST.ContentType = "application/x-www-form-urlencoded";
    byte[] sentData = Encoding.Unicode.GetBytes("message=" + System.Web.HttpUtility.UrlEncode("some data"));
    reqPOST.ContentLength = sentData.Length;
    System.IO.Stream sendStream = reqPOST.GetRequestStream();
    sendStream.Write(sentData, 0, sentData.Length);
    sendStream.Close();
    System.Net.WebResponse result = reqPOST.GetResponse();

    С WebClient:

    using (var client = new System.Net.WebClient())
    {
        var values = new System.Collections.Specialized.NameValueCollection();
        values.Add("message", "some data");
        client.UploadValues("http://site.ru/send.php", values);
    }

    Сохранение Cookies между запросами:

    WebClient по умолчанию не сохраняет cookies между запросами. Это легко лечится наследованием от него, и переопределением одного метода:

    public class CookieAwareWebClient : WebClient
    {
        private CookieContainer m_container = new CookieContainer();

        protected override WebRequest GetWebRequest(Uri address)
        {
            WebRequest request = base.GetWebRequest(address);
            if (request is HttpWebRequest)
            {
                (request as HttpWebRequest).CookieContainer = m_container;
            }
            return request;
        }
    }

    (подсмотрено у Yuriy Solodkyy)

    Вместо заключения:

    Тонка и неразличима грань между тупым копипастом и повторным использованием кода.