簡體   English   中英

序列化和反序列化HttpRequestMessage對象

[英]Serialize and deserialize HttpRequestMessage objects

任何人都有序列化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
}); 

我建議只序列化您在自己的代碼庫中維護實現的那些對象。

對於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消息。

可以使用以下示例代碼序列化/反序列化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;  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM