I'm calling the web service. He accepts the Http message. This is plain XML over Http. You send him an XML request document to the request body, you return an XML response document in the main part of the response. I have a good library in our code base that we have built over the years, which is gaining a lot of serialization for both request documents and responses. Everything is working fine.
Now a new service with which I integrate does not always return the same type of object in response. Under certain error conditions, a special document with an error is returned. Of course, in these situations, my deserialization fails and the response data is lost. I know that I have a deserialization errror, but since the answer is lost, I don't know what the reason was.
I think the problem is that the stream returned by GetResponseStream () does not support search operations, so when I get an error, I cannot just rewind the stream and re-read the data and process it differently.
I am looking for strategies to better deal with this.
I think what I'm going to do is copy the response stream to the memory stream that can be found before I try to deserialize. Then, if an error occurs, I can rewind the memory stream and process the response data in different ways. There was a good example in https://stackoverflow.com> .
Is there a better way to do this? It seems wasteful to copy the response stream to the memory stream.
A simplified version of the source code:
AccountRequest requestVal = new AccountRequest();
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)
{
logger.ErrorFormat("After Exception:\n{0}", ex.ToString());
throw;
}
}
A simplified version of the proposed code:
AccountRequest requestVal = new AccountRequest();
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())
{
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;
var serializer = new XmlSerializer(typeof(AccountResponse));
try
{
returnVal = (AccountResponse)serializer.Deserialize(ms);
}
catch (Exception ex)
{
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;
}
}
}