2016-04-02 10 views
5

Ich sende eine einfache Json-Nachricht an eine WCF-Server-Anwendung.Warum bekomme ich eine schlechte Anfrage (Code 400) mit HttpWebReponse?

Json Nachricht:

{"Name":"Julian", "Id":123} 

Seitencode Auftraggeber:

public string MakeRequest(string parameters) 
{ 
     Console.WriteLine("parameters:" + parameters); 

     var request = (HttpWebRequest)WebRequest.Create(EndPoint); 
     request.Method = Method.ToString(); 
     request.ContentLength = 0; 
     request.ContentType = ContentType; 

     Console.WriteLine("request: " + request.Headers.ToString()); 

     if (PostData != null && Method == HttpVerb.POST) 
     { 
      var encoding = new UTF8Encoding(); 
      var bytes = ObjectToByteArray(PostData); 
      request.ContentLength = bytes.Length; 
      Console.WriteLine("Content length: " + request.ContentLength); 

      using (var writeStream = request.GetRequestStream()) 
      { 
       writeStream.Write(bytes, 0, bytes.Length); 
      } 
     } 

     try 
     { 
      using (var response = (HttpWebResponse)request.GetResponse()) 
      { 
       var responseValue = string.Empty; 

       if (response.StatusCode != HttpStatusCode.OK) 
       { 
        var message = String.Format("Request failed. Received HTTP {0}", response.StatusCode); 
        throw new ApplicationException(message); 
       } 

       // grab the response 
       using (var responseStream = response.GetResponseStream()) 
       { 
        if (responseStream != null) 
         using (var reader = new StreamReader(responseStream)) 
         { 
          responseValue = reader.ReadToEnd(); 
         } 
       } 

       return responseValue; 
      } 
     } 
     catch (WebException exception) 
     { 
      string responseText; 

      using (var reader = new StreamReader(exception.Response.GetResponseStream())) 
      { 
       responseText = reader.ReadToEnd(); 
       return responseText; 
      } 
     } 

private byte[] ObjectToByteArray(object obj) 
{ 
     if (obj == null) 
      return null; 
     BinaryFormatter bf = new BinaryFormatter(); 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      bf.Serialize(ms, obj); 
      return ms.ToArray(); 
     } 
} 

Server-Side-Code:

[WebInvoke(Method = "POST", 
       ResponseFormat = WebMessageFormat.Json, 
       RequestFormat =WebMessageFormat.Json, 
       UriTemplate = "/postdata")] 
    public Person PostData(Person data) 
    { 
     //Return new person with data inputted from json message 
     return new Person() 
     { 
      Id = data.Id, 
      Name = data.Name 
     }; 
    } 

Server Config-Datei

<?xml version="1.0"?> 
<configuration> 
    <system.serviceModel> 

    <services> 
     <service name="WcfJsonRestService.Service1" behaviorConfiguration="Metadata"> 
     <host> 
     <baseAddresses> 
      <add baseAddress="http://localhost:8732/service1"/> 
     </baseAddresses> 
     </host> 
      <endpoint address="http://localhost:8732/service1" 
        binding="webHttpBinding" 
        contract="WcfJsonRestService.IService1"/> 
     </service> 
    </services> 

    <behaviors> 
    <serviceBehaviors> 
     <behavior name="Metadata"> 
     <serviceMetadata httpGetEnabled="true" policyVersion="Policy15"/> 
     <serviceDebug includeExceptionDetailInFaults="true"/> 
     </behavior> 
    </serviceBehaviors> 

    <endpointBehaviors> 
      <behavior> 
      <webHttp /> 
      </behavior> 
     </endpointBehaviors> 
    </behaviors> 

    </system.serviceModel> 
    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> 
    </startup> 
</configuration> 

über den Code:

  • (Client-Seite) Die Eingabe in das Verfahren ist nur macherequest die oben gezeigt json Daten.
  • (Client-Seite) Die URI, die gepostet wird, ist nur "localhost: 8732/service1/postdata" (ja einschließlich http: // kann es hier einfach nicht enthalten, da es als Link zählt und ich kann anscheinend nur zwei haben)
  • (Server-Seite) der Server-Code ist eine Implementierung dieser Lösung, die ich auf Code Project gefunden:

http://www.codeproject.com/Articles/167159/How-to-create-a-JSON-WCF-RESTful-Service-in-sec?fid=1614381&fr=1&df=90&mpp=25&prof=False&sort=Position&view=Normal&spc=Relaxed#xx0xx

Was habe ich versucht:

  • Ich habe Postman verwendet, um eine JSON-Nachricht an das obige URI zu senden und eine Antwort erhalten (für den Moment gibt es nur ein Paket mit den gleichen Daten zurück), so dass ich Probleme habe, in der URI zu finden.
  • Ich habe das JSON-Paket mit JSONLint validiert.
  • Ich habe verschiedene try/catch-Blöcke hinzugefügt, um mehr Fehlerinformationen zu erhalten, aber sie alle sind Protokollfehler/schlechte Anfrage Fehlercode 400.
  • Ich habe auch Dinge in meinem Kopf zertrümmert (es ist billiger und weniger alarmierend für meinen Mitbewohner
  • )

Stromausgang:

ich eine schlechte Anfrage Antwort vom Server ohne Daten zu bekommen.

Update 1:

ich die Datenkonvertierung, um falsch habe immer müssen.Bevor I:

  • erstellt Person Objekt
  • umgewandelte Person Objekt json
  • bestanden json zu macherequest Methode
  • (in macherequest) WebRequest Umwandeln json auf Byte-Array erstellt

der erste If-Anweisung der MakeRequest() -Methode (Client-Seite) wurde mit einem Code-Segment aktualisiert, das die Anfrage mit dem JSON wie macht. Ich erhalte nun eine Protokollverletzung Fehler, wenn write.Flush() führt:

Aktualisiert Client-Seite Code (macherequest Methode)

if (PostData != null && Method == HttpVerb.POST) 
    { 
     //var encoding = new UTF8Encoding(); 
     //var bytes = ObjectToByteArray(PostData); 
     //request.ContentLength = bytes.Length; 
     //Console.WriteLine("Content length: " + request.ContentLength); 

     //using (var writeStream = request.GetRequestStream()) 
     //{ 
     // writeStream.Write(bytes, 0, bytes.Length); 
     //} 


     using (var streamWriter = new StreamWriter(request.GetRequestStream())) 
     { 
      streamWriter.Write(json); 
      streamWriter.Flush(); 
      streamWriter.Close(); 
     } 

     var httpResponse = (HttpWebResponse)request.GetResponse(); 
     using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) 
     { 
      var result = streamReader.ReadToEnd(); 
     } 

    } 

Update 2:

Die Protokollverletzung Fehler aus Der Aufruf von streamWriter.Flush() erfolgte, weil ich die Anforderung nicht eingestellt hatte.ContentLenth. Ich habe jetzt die Content.Length zu json.Length gesetzt und ich jetzt diesen Fehler:

System.ArgumentException: Stream was not readable

Das Bild ist etwas klein, aber die Fehlermeldung lautet:

"System.ArgumentException: Stream was not readable." 

Antwort

0

Ich denke das Problem war in den ersten Zeilen des try-Blocks. Ich versuche, die Antwort von der Anfrage Objekt zu lesen ... ehem ... Obwohl ich versuchte, die Antwort von der Antwortobjekt weiter unten zu lesen, wurde der Schaden bereits getan. Ich habe den untenstehenden Funktionscode zusammen mit dem auskommentierten Code, der das Problem verursacht hat, eingefügt. Ich habe die problematische Anfrage markiert. GetResponse() mit **** sowie die richtige Antwort. GetResponseStream(), die Sie gerne hören, ist jetzt frei, um seine Arbeit zu machen.

Hoffe das spart jemand viel Zeit!

Alle relevanten Teile der Methode macherequest:

var request = (HttpWebRequest)WebRequest.Create(EndPoint); 
     request.Method = Method.ToString(); 
     request.ContentLength = 0; 
     request.ContentType = ContentType; 


     Console.WriteLine("request: " + request.Headers.ToString()); 

     if (PostData != null && Method == HttpVerb.POST) 
     { 
      Console.WriteLine("json length: " + json.Length); 
      Console.WriteLine(json); 
      request.ContentLength = json.Length; 
      var encoding = new UTF8Encoding();    

      using (var streamWriter = new StreamWriter(request.GetRequestStream())) 
      { 
       streamWriter.Write(json); 
       streamWriter.Flush(); 
       streamWriter.Close(); 
      } 
     } 

     try 
     { 
      // **** FIRST READ USING request.GetResponse() **** 
      //var httpResponse = (HttpWebResponse)request.GetResponse(); 
      //using (var streamReader = new StreamReader(httpResponse.GetResponseStream())) 
      //{ 
      // streamReader.ReadToEnd(); 
      //} 

      using (var response = (HttpWebResponse)request.GetResponse()) 
      { 
       var responseValue = string.Empty; 

       if (response.StatusCode != HttpStatusCode.OK) 
       { 
        var message = String.Format("Request failed. Received HTTP {0}", response.StatusCode); 
        throw new ApplicationException(message); 
       } 

       // grabs the response 
       using (var responseStream = response.GetResponseStream()) 
       { 
        if (responseStream != null) 
         using (var reader = new StreamReader(responseStream)) 
         { 
          // **** SECOND READ USING response.GetResponseStream() **** 
          responseValue = reader.ReadToEnd(); 
         } 
       } 
       return responseValue; 
      } 
     } 
0

Wenn Sie gelesen Ein Stream bis zum Ende, Sie müssen es zurück zum Anfang suchen.

Sie können dies versuchen:

StreamReader sr = new StreamReader(stream); 
sr.ReadToEnd(); 
stream.Seek(0, SeekOrigin.Begin); 
sr.ReadToEnd(); // This should work now 
+0

Haben das Problem nicht beheben - bekam eine Ausnahme, etwas über Suchoperationen nicht durch den Strom unterstützt? Ich habe aber jetzt eine Lösung! –

Verwandte Themen