-1

In order to log some HTTP traffic I'm trying to serialize an instance of System.Net.HttpWebRequest. The application uses MVC 3 and the problem code is in an action method in a controller class.

In .NET Framework 4 it the class is documented as serializable:

[SerializableAttribute]
  public class HttpWebRequest : WebRequest, 
      ISerializable

The following test code fails at the indicated statement:

...
HttpWebRequest preapprovalRequest = (HttpWebRequest)WebRequest.Create("http://big.URL.here");
...
HttpWebResponse preapprovalResponse = (HttpWebResponse)preapprovalRequest.GetResponse();


// Serialize the request context.
IFormatter formatter = new BinaryFormatter();
MemoryStream msRequest = new MemoryStream();
formatter.Serialize(msRequest, preapprovalRequest); //<<<<< Error here.
// Reset the stream and deserialize.
msRequest.Seek(0, SeekOrigin.Begin);
HttpWebRequest duplicateRequest = (HttpWebRequest)formatter.Deserialize(msRequest);
msRequest.Close();

// Serialize the response context.
MemoryStream msResponse = new MemoryStream();
formatter.Serialize(msResponse, preapprovalResponse);
// Reset the stream and deserialize.
msResponse.Seek(0, SeekOrigin.Begin);
HttpWebResponse duplicateResponse = (HttpWebResponse)formatter.Deserialize(msResponse);
msResponse.Close();

The error reported is:

Type 'System.Net.WebRequest+WebProxyWrapper' in Assembly
'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
is not marked as serializable.

I've tried chasing WebProxyWrapper with no joy. Just a bit of unhelpful baggage. Explicitly casting the HttpWebRequest to a WebRequest doesn't alter the error:

formatter.Serialize(msRequest, (WebRequest)preapprovalRequest);

On the bright side, the code does properly serialize and deserialize the instance of HttpWebResponse.

How can I lose the wrapper? Is there a better approach?

Cœur
  • 37,241
  • 25
  • 195
  • 267
HABO
  • 15,314
  • 5
  • 39
  • 57
  • The answer is *you cannot serialize HttpWebRequest and you shouldn't be doing that.* The **real** question involves *why* you are trying to do this. –  Aug 15 '11 at 15:44
  • It didn't seem unreasonable to log my request and PayPal's response when an error occurs or something unexpected, e.g. a new name/value pair, comes back in the response. It also didn't seem unreasonable to attempt to serialize something documented as having [SerializableAttribute]. Are you suggesting, perhaps, that Microsoft might have erred in their documentation? – HABO Aug 15 '11 at 20:22
  • But you aren't serializing that class, as you have found. You are serializing something else. It is possible to get the bytes from the request and save *those*, which would be essentially what you wish to do without the overhead of serializing a request/response object. –  Aug 16 '11 at 14:04
  • Possible duplicate of [HttpWebRequest Won't Serialize](https://stackoverflow.com/questions/351265/httpwebrequest-wont-serialize) – Cœur Jul 13 '18 at 14:04
  • 1
    @Cœur The accepted answer to the proposed duplicate question leads to "Serialization is obsoleted for this type." That question includes "Using .Net Framework 2.0". _This_ question is specific to ".NET Framework 4" and includes a link to the version 4 documentation which showed the `[SerializableAttribute]` had been restored. The answer, provided by Microsoft, was that the New & Improved documentation was wrong. – HABO Jul 13 '18 at 18:03
  • @HABO close vote retracted: note that old links to a wrong duplicate need to be manually removed. – Cœur Jul 14 '18 at 05:58

2 Answers2

2

The official answer from Microsoft:

Thank you for your feedback. Unfortunately HttpWebRequest dropped support for serialization after .NET 1.1. See http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.httpwebrequest(v=VS.100).aspx

We’ll see if we can get that attribute removed to avoid this confusion in the future.

They changed the documentation to include the [ObsoleteAttribute] attribute.

HABO
  • 15,314
  • 5
  • 39
  • 57
0

Give this a shot:

[Serializable()]
public class MyClass
{
    //your serializable class
}
James Johnson
  • 45,496
  • 8
  • 73
  • 110
  • The problem instance is a variable in a method, not a property of another class. (HttpWebRequest preapprovalRequest = (HttpWebRequest)WebRequest.Create("http://horrific.URL.here"); ) The method is an action in an MVC controller. Trying [Serializable] on the controller class doesn't alter the outcome. Nor do I expect it to actually be serializable. – HABO Aug 12 '11 at 19:28
  • The error seems to indicate that the wrapper was not marked as serializable. Can you provide a little more context? – James Johnson Aug 12 '11 at 19:34
  • To narrow the universe of discourse I moved the test code to a minimal console application. The error is unchanged, which leads me to believe that it is unlikely to be a problem with one of my classes. By way of context: The code builds an HTTP request which is sent to PayPal where, if it is not found wanting, a response is generated and returned. Since PayPal sometimes does unpredicatable things I'd like to be able to log some of the exhcnages. That's about it. – HABO Aug 12 '11 at 20:08