Deserialisieren von XML-Daten von HttpWebResponse GetResponseStream mit verschiedenen Arten

Ich bin Aufruf eines web service. Akzeptiert er Http-Post. Es ist einfach, XML-über-Http. Sie senden eine XML-Anfrage-Dokument in den Körper der Anfrage, erhalten Sie eine XML-Antwort-Dokument in den Text der Antwort. Ich habe eine schöne Bibliothek in unserer code-Basis, die wir aufgebaut haben über die Jahre nicht stark typisiert Serialisierung sowohl die Anfrage-und Antwort-Dokumente. Alles normal funktioniert.

Nun ist der neue service, den ich bin die Integration mit nicht senden immer wieder die gleichen Objekt-Typ in der Antwort. Unter bestimmten Bedingungen Fehler gibt es einen speziellen Fehler-Dokument. Natürlich, in diesen Situationen mein Deserialisierung schlägt fehl, und die Antwort-Daten verloren gehen. Ich weiß, dass ich eine Deserialisierung errror, aber da die Antwort verloren gegangen ist, ich weiß nicht, was die Ursache war.

Ich denke, das problem ist, dass der stream zurückgegeben GetResponseStream() nicht unterstützt seek-Operationen, so dass, wenn ich einen Fehler ich kann nicht einfach Zurückspulen des Streams und re-die Daten Lesen und verarbeiten es anders.

Ich bin auf der Suche nach Strategien, um besser damit umgehen.

Was ich denke, ich werde zu tun ist, kopieren Sie den response-stream ein Speicher-stream, die ist seekable bevor ich Versuch zu Deserialisieren. Dann, wenn ein Fehler Auftritt, kann ich Zurückspulen des Speicher-stream und verarbeiten der Antwortdaten anders. Es war ein gutes Beispiel in https://stackoverflow.com/a/3434077/90236.

Gibt es einen besseren Weg, dies zu tun? Es scheint Art von Verschwendung zu kopieren Sie den response-stream ein Speicher-stream.

Vereinfachte versioin der original-code:

AccountRequest requestVal = new AccountRequest();
//initialize requestVal object

var request = (HttpWebRequest)WebRequest.Create("http://example.com/service");
request.Method = "POST";
request.ContentType = "text/xml";

using (Stream webStream = request.GetRequestStream())
{
    var serializer = new XmlSerializer(typeof(AccountRequest));
    serializer.Serialize(webStream, requestVal);
    webStream.Flush();
    webStream.Close();
}

AccountResponse returnVal;
using (var response = (HttpWebResponse)request.GetResponse())
{
    Stream responseStream = response.GetResponseStream();

    var serializer = new XmlSerializer(typeof(responseStream));

    try
    {
        returnVal = (AccountResponse)serializer.Deserialize(responseStream);
    }
    catch (Exception ex)
    {
      //if an exception occurs, the response stream data is lost. 
      //The responseStream is not seekable.
      logger.ErrorFormat("After Exception:\n{0}", ex.ToString());
      throw;
    }
}

Vereinfachte version des vorgeschlagenen code:

AccountRequest requestVal = new AccountRequest();
//initialize requestVal object

var request = (HttpWebRequest)WebRequest.Create("http://example.com/service");
request.Method = "POST";
request.ContentType = "text/xml";

using (Stream webStream = request.GetRequestStream())
{
    var serializer = new XmlSerializer(typeof(AccountRequest));
    serializer.Serialize(webStream, requestVal);
    webStream.Flush();
    webStream.Close();
}

AccountResponse returnVal;
using (var response = (HttpWebResponse)request.GetResponse())
{
    Stream responseStream = response.GetResponseStream();
    using (MemoryStream ms = new MemoryStream())
    {    
      //copy response stream to a seekable memorystream
      int count = 0;
      do
      {
          byte[] buf = new byte[1024];
          count = responseStream.Read(buf, 0, 1024);
          ms.Write(buf, 0, count);
      } while (responseStream.CanRead && count > 0);    
      ms.Position = 0;

      //now attempt to desrialize from the memory stream
      var serializer = new XmlSerializer(typeof(AccountResponse));

      try
      {
          returnVal = (AccountResponse)serializer.Deserialize(ms);
      }
      catch (Exception ex)
      {
        //if an exception occured, rewind the stream and write an error to the log
        ms.Position = 0;
        using (var reader = new StreamReader(ms, Encoding.UTF8))
        {
            logger.ErrorFormat("After Exception:\n{0}\n\nRespons:\n{1}", 
                  ex.ToString(), reader.ReadToEnd());
        }
        throw;
      }
    }
}
InformationsquelleAutor Michael Levy | 2014-02-12
Schreibe einen Kommentar