序列化和反序列化HttpRequestMessage对象



任何人都有序列化HttpRequestMessage对象的经验吗?尝试使用Json.net,它部分起作用。也就是说,JsonConvert.DeserializeObject由于构造问题StringContent而失败:"无法找到用于类型System.Net.Http.StringContent的构造函数"。

简而言之,这里的用例是,我想保存web请求,并在以后发布,以防出现临时网络问题或服务不可用等。

失败的示例代码:

var request = new HttpRequestMessage(HttpMethod.POST, "http://www.something.com");
request.Headers.Date = DateTimeOffset.UtcNow;
request.Headers.AcceptLanguage.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("en-US"));
request.Content = new StringContent("Hello World!");
request.Content.Headers.Add("x-some", "thing");                       
var result = JsonConvert.SerializeObject(request, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Objects,
    TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Full
});
var deserializeRequest = JsonConvert.DeserializeObject<HttpRequestMessage>(result, new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Objects
}); 

使用以下示例代码可以序列化/反序列化HttpRequest的相关部分。

var request = new HttpRequestMessage(HttpMethod.Post, "http://www.something.com");
request.Content = new StringContent("Hello World!");
var serializedRequestByteArray = new HttpMessageContent(request).ReadAsByteArrayAsync().Result;
var tmpRequest = new HttpRequestMessage();
tmpRequest.Content = new ByteArrayContent(serializedRequestByteArray);
tmpRequest.Content.Headers.Add("Content-Type", "application/http;msgtype=request");
var deserializedRequest = tmpRequest.Content.ReadAsHttpRequestMessageAsync().Result;  

我建议只序列化那些在自己的代码库中维护实现的对象。

对于HttpRequestMessage,不尝试序列化它的原因之一是它实现了IDisposable,这意味着它可以保存对非托管资源的引用。使用序列化程序很难预测它的行为。

在这种情况下,我最好使用构建器模式:

var builder = new MyRequestBuilder()
    .SetUrl("http://www.something.com")
    .SetMethod("POST")
    .SetStringContent("My content")
    .DefaultRequestSettings() // One benefit you can encapsulate some logic in builder.
// ...
using(HttpRequestMessage requestMessage = builder.Build(DateTime.UtcNow)) // probably need to renew Date header upon issuing the actual request
{
   // issue request
}

问题是StringContent没有默认的构造函数。因此,当Json.Net试图创建一个新的StringContent时,它做不到。我试着写了一个自定义的JsonConverter来处理这个问题,但这也不起作用,因为你似乎无法获得分配给StringContent的值。即

public class StringContentConverter :JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(HttpContent).IsAssignableFrom(objectType);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jObject = JObject.Load(reader); //There's nothing in here that says "Hello World!".  The string content hides it.
    }
}

本质上,您需要将HttpRequest消息的输入存储在自己的自定义类中。

相关内容

  • 没有找到相关文章

最新更新