2014-10-28 4 views
4

У кого-нибудь есть опыт в сериализации объектов HttpRequestMessage? Попытка с Json.net и частично работает. Тем не менее, JsonConvert.DeserializeObject сбой из-за проблем с конструкцией StringContent: «Невозможно найти конструктор для использования для типа System.Net.Http.StringContent».Сериализация и десериализация объектов HttpRequestMessage

Прецедент здесь короче, что я хочу, чтобы сохранить веб-запрос и выдать его позже, в случае проблем временных сетей или услуг недоступность и т.д ..

Пример кода, который не удается:

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 
}); 

ответ

0

Возможно сериализовать/десериализовать соответствующие части 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; 
2

Я бы предложил сериализацию только тех объектов, для которых вы поддерживаете реализацию в своей собственной кодовой базе.

Для 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 
} 
0

Проблема заключается в том, что 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 в своем собственном классе.

Смежные вопросы