2010-11-12 11 views
9

in un progetto Silverlight-Windows Phone 7 Sto creando una HttpWebRequest, ottengo il RequestStream, scrivo qualcosa nello Stream e provo a ottenere la risposta, ma ottengo sempre una NotSupportedException : "System.Net.Browser.OHWRAsyncResult.AsyncWaitHandle ha generato un'eccezione di tipo 'System.NotSupportedException'HttpWebRequest.EndGetResponse lancia una NotSupportedException in Windows Phone 7

mio codice di produzione è molto più complicato, ma posso restringere il campo a questo piccolo pezzo di codice:

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

}

Qualcuno sa che cosa c'è di sbagliato in questo codice?

risposta

3

Il problema è di come hai a che fare con l'accesso alle richieste originali nella richiamata da BeginGetResponse.

piuttosto che mantenere un riferimento ot lo stato, ottenere un riferimento alla richiesta originale con:

var request = (HttpWebRequest)asynchronousResult.AsyncState; 

Date un'occhiata a questo esempio molto semplice (ma di lavoro) di attuare login inviando e-mail e credenziali password per un sito web.

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

Ciao Matt, che sto affrontando problema simile. Si prega di aiuto, http://stackoverflow.com/questions/13598666/how-to-fix-system-argumentexception-in-httpwebresponse –

-1

Modifica questo:

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

A tal:

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

Nah, "nuova AsyncCallback()" non fa nulla in questo caso, può essere omesso in generale. –

22

Il NotSupportedException può essere generata quando il flusso di richiesta non viene chiuso prima della chiamata a EndGetResponse. Il flusso WebRequest è ancora aperto e invia i dati al server quando stai cercando di ottenere la risposta. Dal flusso implementa l'interfaccia IDisposable, una soluzione semplice è quello di avvolgere il codice utilizzando il flusso di richiesta in un blocco using:

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

Il utilizzando blocco farà in modo che il flusso sia chiuso prima di tentare di ottenere la risposta da parte del server web.

1

NotSupportedException può essere generato anche quando string url è troppo lungo. Avevo incasinato e attaccato i dati dei post in url invece di post-body. Quando i dati è stato breve, ha funzionato bene, ma una volta che è cresciuto troppo grande - EndGetResponse si è schiantato.