Deserializing TimeSpan using JSON.net and .net WebApi
Asked Answered
S

1

6

I have an ASP.NET WebApi project that utilizes Entity Framework 4.1. I am attempting to return an entity and leveraging JSON.net for deserialization. All is working well however when attempting to deserialize entities with TimeSpan properties I run accross the following exception:

Could not cast or convert from System.String to System.TimeSpan.

Looking at the stack trace reveals:

JsonSerializationException: Error converting value "PT17H9M43.1671969S" to type 'System.TimeSpan'. Path 'TimeIn', line 1, position 890.

The output from response.Content.ReadAsStringAsync().Result is:

{"CreatedDate":"/Date(1329851383157-0500)/","ServicerUserId":6,"TimeIn":"PT17H9M43.1671969S","TimeOut":"PT17H28M43.1671969S"}

Before using JSON.net I have successfully deserialized using System.Runtime.Serialization.JsonDataContractJsonSerializer however would prefer to not use this approach.

Code used to get entity from WebApi

public T Get<T>(object id)
{
    using (var httpClient = NewHttpClient())
    {
        var response = httpClient.GetAsync(_endpoint + id.ToString()).Result;
        return JsonConvert.DeserializeObject<T>(response.Content.ReadAsStringAsync().Result);
    }
}

Code used to in WebApi controller to return entity:

// GET /api/services/5
public Service Get(Guid id)
{
    var entry = db.Services.Find(id);
    if (entry == null)
        throw new HttpResponseException(HttpStatusCode.NotFound);
    return entry;
}

Any ideas on how to deserialize TimeSpan's would be greatly appreciated.

Stane answered 11/5, 2012 at 14:26 Comment(3)
Can you update your question with the value of response.Content.ReadAsStringAsync().Result?Cheque
Also, since you don't explicitly show your server HttpConfiguration, I'm going to assume that you are using the default formatters. Yet you want to deserialize the response using Json.NET. Ideally, you would have a Json.NET media type formatter and would both configure the server to use it and ensure that your client uses it when reading content like: response.Content.ReadAsAsync<T>(new[] { new JsonNetFormatter() }).Cheque
Added example content from response.Content.ReadAsStringAsync().ResultStane
S
2

The solution was in configuring the WebApi project to leverage JSON.net for serialization by default in the global.asax Application_Start event as referenced at http://blogs.msdn.com/b/henrikn/archive/2012/02/18/using-json-net-with-asp-net-web-api.aspx

 // Create Json.Net formatter serializing DateTime using the ISO 8601 format
            JsonSerializerSettings serializerSettings = new JsonSerializerSettings();
            serializerSettings.Converters.Add(new IsoDateTimeConverter());
            GlobalConfiguration.Configuration.Formatters[0] = new JsonNetFormatter(serializerSettings);
Stane answered 23/5, 2012 at 20:17 Comment(1)
You accepted your own answer which is only partially right. The real answer to your question lies in my comment above. Deserialization is handled by the client, not the server. You need to use the Json.NET formatter in both cases. Clients are unaffected by server configuration.Cheque

© 2022 - 2024 — McMap. All rights reserved.