9

в Silverlight-Windows Phone 7-project Я создаю HttpWebRequest, получаю RequestStream, пишу что-то в Stream и пытаюсь получить ответ, но всегда получаю исключение NotSupportedException : «System.Net.Browser.OHWRAsyncResult.AsyncWaitHandle бросил исключение типа„System.NotSupportedException“HttpWebRequest.EndGetResponse вызывает исключение NotSupportedException в Windows Phone 7

Мой код продукции гораздо сложнее, но я могу сократить его до этой небольшой кусок кода:

public class HttpUploadHelper 
{ 
    private HttpWebRequest request; 
    private RequestState state = new RequestState(); 

    public HttpUploadHelper(string url) 
    { 
     this.request = WebRequest.Create(url) as HttpWebRequest; 
     state.Request = request; 
    } 

    public void Execute() 
    { 
     request.Method = "POST"; 
     this.request.BeginGetRequestStream(
      new AsyncCallback(BeginRequest), state); 
    } 

    private void BeginRequest(IAsyncResult ar) 
    { 
     Stream stream = state.Request.EndGetRequestStream(ar); 
     state.Request.BeginGetResponse(
      new AsyncCallback(BeginResponse), state); 
    } 

    private void BeginResponse(IAsyncResult ar) 
    { 
     // BOOM: NotSupportedException was unhandled; 
     // {System.Net.Browser.OHWRAsyncResult} 
     // AsyncWaitHandle = 'ar.AsyncWaitHandle' threw an 
     // exception of type 'System.NotSupportedException' 
     HttpWebResponse response = state.Request.EndGetResponse(ar) as HttpWebResponse; 
     Debug.WriteLine(response.StatusCode); 
    } 
} 

public class RequestState 
{ 
    public WebRequest Request; 
} 

Кто-нибудь знает, что не так с этим кодом?

ответ

3

Проблема заключается в том, как вы имеете дело с доступом к исходным запросам в обратном вызове от BeginGetResponse.

Вместо проведения ссылка Ot состояние, получить обратную ссылку на оригинальный запрос с:

var request = (HttpWebRequest)asynchronousResult.AsyncState; 

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

public static string Email; 

public static string Password; 


private void LoginClick(object sender, RoutedEventArgs e) 
{ 
    Email = enteredEmailAddress.Text.Trim().ToLower(); 

    Password = enteredPassword.Password; 

    var request = (HttpWebRequest)WebRequest.Create(App.Config.ServerUris.Login); 

    request.ContentType = "application/x-www-form-urlencoded"; 
    request.Method = "POST"; 
    request.BeginGetRequestStream(ReadCallback, request); 
} 

private void ReadCallback(IAsyncResult asynchronousResult) 
{ 
    var request = (HttpWebRequest)asynchronousResult.AsyncState; 

    using (var postStream = request.EndGetRequestStream(asynchronousResult)) 
    { 
     using (var memStream = new MemoryStream()) 
     { 
      var content = string.Format("Password={0}&Email={1}", 
             HttpUtility.UrlEncode(Password), 
             HttpUtility.UrlEncode(Email)); 

      var bytes = System.Text.Encoding.UTF8.GetBytes(content); 

      memStream.Write(bytes, 0, bytes.Length); 

      memStream.Position = 0; 
      var tempBuffer = new byte[memStream.Length]; 
      memStream.Read(tempBuffer, 0, tempBuffer.Length); 

      postStream.Write(tempBuffer, 0, tempBuffer.Length); 
     } 
    } 

    request.BeginGetResponse(ResponseCallback, request); 
} 

private void ResponseCallback(IAsyncResult asynchronousResult) 
{ 
    var request = (HttpWebRequest)asynchronousResult.AsyncState; 

    using (var resp = (HttpWebResponse)request.EndGetResponse(asynchronousResult)) 
    { 
     using (var streamResponse = resp.GetResponseStream()) 
     { 
      using (var streamRead = new StreamReader(streamResponse)) 
      { 
       string responseString = streamRead.ReadToEnd(); 

       // do something with responseString to check if login was successful 
      } 
     } 
    } 
} 
+0

Привет, Мэтт, я столкнулся с подобной проблемой. Пожалуйста, помогите, http://stackoverflow.com/questions/13598666/how-to-fix-system-argumentexception-in-httpwebresponse –

-1

Изменить это:

state.Request.BeginGetResponse(
     new AsyncCallback(BeginResponse), state); 

Для этого:

state.Request.BeginGetResponse(BeginResponse, state); 
+0

Nah, «новый AsyncCallback()« ничего не делает в этом случае, его вообще можно опустить. –

22

NotSupportedException может быть выброшен, когда поток запроса не закрывается перед вызовом EndGetResponse. Поток WebRequest все еще открыт и отправляет данные на сервер, когда вы пытаетесь получить ответ. Поскольку поток реализует интерфейс IDisposable, простое решение, чтобы обернуть ваш код, используя поток запроса в using блоке:

private void BeginRequest(IAsyncResult ar) 
{ 
    using (Stream stream = request.EndGetRequestStream(ar)) 
    { 
     //write to stream in here. 
    } 
    state.Request.BeginGetResponse(
     new AsyncCallback(BeginResponse), state); 
} 

с помощью блока гарантирует, что поток закрыт, прежде чем пытаться получить ответ от веб сервер.

1

NotSupportedException также может быть выброшен, если string url слишком длинный. Я перепутал и добавил данные сообщения в url вместо почтового тела. Когда данные были короткими, он работал нормально, но как только он стал слишком большим - EndGetResponse разбился.