2013-06-19 2 views
1

Я пытаюсь перенести свой проект с Xamarin Studio на Mac в Visual Studio 2012 в Windows 7. На Mac и XS все работает отлично. На VisualStudio 2012 я имею эти 2 проблемы:WebHeaderCollection & HttpWebRequest на Xamarin

Ошибка 3 «System.Net.WebHeaderCollection» не содержит определение для «Добавить», а метод расширения «Добавить» принимать первый аргумент типа ' System.Net.WebHeaderCollection '(вам не хватает с помощью директивы или сборки ссылка?) C: \ Users \ user \ Documents \ Visual Studio 2012 \ Projects \ MyProject \ MyProject.Core \ Services \ MyProjectService. cs

Ошибка 4 'System.Net.HttpWebRequest' не содержит определения для 'GetResponse' и никакого расширения метод «GetResponse», принимающий первый аргумент типа типа «System.Net.HttpWebRequest», может быть найден (вы используете без указания использования или сборки ссылка?) C: \ Users \ user \ Documents \ Visual Studio 2012 \ Проекты \ MyProject \ MyProject.Core \ Services \ MyProjectService.cs

по этому коду:

var request = WebRequest.Create("https://www.myaddress.com/test/") as HttpWebRequest; 
    request.Method = "GET"; 
    request.Accept = "application/json"; 
    request.Headers.Add(HttpRequestHeader.Cookie,"mycookievalue"); 

    // Get response 
    using (var response = request.GetResponse() as HttpWebResponse) 
    { 
     // Get the response stream 
     var reader = new StreamReader(response.GetResponseStream()); 
     content = reader.ReadToEnd(); 
    } 

Как я мог решить эту проблему?

+0

Одна идея: «Заголовки [« ключ »] = значение' работают? – Stuart

+1

Я не знаю ключ ... как я могу его проверить (через RestClient?) –

+0

Является ли ключ не 'HttpRequestHeader.Cookie'? – Stuart

ответ

6

Существует нет реализации вещей, упомянутых вами до сих пор. Но все в порядке. Они все еще отлично работают!

Ответы на ваши вопросы.

Ошибка 3. Да. В настоящее время вы можете использовать только заголовки ["key"] = значение. Но. Не для каждого заголовка. Я пытался поставить «Content-Length» там (так как не было реализовано свойство ContentLength), но получил исключение «ограниченных заголовков». Однако запрос POST успешно обработан для меня, поэтому я отпустил его.

Ошибка 4. Да. Такого метода нет. (Точно так же, как нет «GetRequestStream» (Например, если вы хотите написать данные POST для запроса потока)). Хорошей новостью является то, что есть BeginGetResponse и BeginGetRequestStream соответственно, и C# методы действий упрощают всю эту кухню.

(плюс, я уверен, это очень полезно для общего понимания асинхронной практики).

Базовый образец можно найти на Microsoft official docs.

Но делать это с действиями я использовал следующее:

public void MakeRequest(string url, string verb, Dictionary<string, string> requestParams, 
     Action<string> onSuccess, Action<Exception> onError) 
    { 
     string paramsFormatted; 

     if (verb == "GET") 
     { 
      paramsFormatted = string.Join("&", requestParams.Select(x => x.Key + "=" + Uri.EscapeDataString(x.Value))); 
      url = url + (string.IsNullOrEmpty(paramsFormatted) ? "" : "?" + paramsFormatted); 
     } 
     else 
     { 
      // I don't escape parameters here, 
      // as Uri.EscapeDataString would throw exception if the parameter length 
      // is too long, so you must control that manually before passing them here 
      // for instance to convert to base64 safely 
      paramsFormatted = string.Join("&", requestParams.Select(x => x.Key + "=" + (x.Value))); 
     } 

     var request = (HttpWebRequest)WebRequest.Create(url); 
     request.Method = verb; 

     requestParams = requestParams ?? new Dictionary<string, string>(); 

     Action goRequest =() => MakeRequest(request, 
      response => 
      { 
       onSuccess(response); 
      }, 
      error => 
      { 
       if (onError != null) 
       { 
        onError(error); 
       } 
      }); 

     if (request.Method == "POST") 
     { 
      request.BeginGetRequestStream(ar => 
      { 
       using (Stream postStream = request.EndGetRequestStream(ar)) 
       { 
        byte[] byteArray = Encoding.UTF8.GetBytes(paramsFormatted); 
        postStream.Write(byteArray, 0, paramsFormatted.Length); 
       } 
       goRequest(); 
      }, request); 
     } 
     else // GET 
     { 
      goRequest(); 
     } 
    } 

    private void MakeRequest(HttpWebRequest request, Action<string> onSuccess, Action<Exception> onError) 
    { 
     request.BeginGetResponse(token => 
     { 
      try 
      { 
       using (var response = request.EndGetResponse(token)) 
       { 
        using (var stream = response.GetResponseStream()) 
        { 
         var reader = new StreamReader(stream); 
         onSuccess(reader.ReadToEnd()); 
        } 
       } 
      } 
      catch (WebException ex) 
      { 
       onError(ex); 
      } 
     }, null); 
    } 
1

Чтобы ответить на ошибку 4, я сделал два методы расширения, так что я могу иметь GetRespone() и GetRequestStream() метода в классе WebRequest и работают как их оригинальные версии, т.е. блокируют поток.Так вот:

public static class ExtensionMethods 
{ 
    public static WebResponse GetResponse(this WebRequest request){ 
     ManualResetEvent evt = new ManualResetEvent (false); 
     WebResponse response = null; 
     request.BeginGetResponse ((IAsyncResult ar) => { 
      response = request.EndGetResponse(ar); 
      evt.Set(); 
     }, null); 
     evt.WaitOne(); 
     return response as WebResponse; 
    } 

    public static Stream GetRequestStream(this WebRequest request){ 
     ManualResetEvent evt = new ManualResetEvent (false); 
     Stream requestStream = null; 
     request.BeginGetRequestStream ((IAsyncResult ar) => { 
      requestStream = request.EndGetRequestStream(ar); 
      evt.Set(); 
     }, null); 
     evt.WaitOne(); 
     return requestStream; 
    } 
} 

Просто убедитесь, чтобы поместить это в другом пространстве имен, чем ваш обычный код и импортировать пространство имен. Затем у вас будет метод GetResponse() для экземпляров WebRequest. Oh, а также GetRequestStream(), который полезен для отправки POST-данных

Смежные вопросы