Search code examples
c#jsondatacontractserializer

How to use DataContractJsonSerializer with auth token


I have a JSON text that looks like this:

{
    "access_token":"really-long-string-here",
    "token_type":"bearer",
    "expires_in":1234567,
    "userName":"GlenH7@Foo.com",
    ".issued":"Mon, 09 Nov 2015 23:02:04 GMT",
    ".expires":"Mon, 23 Nov 2015 23:02:04 GMT"
}

and an AuthToken class that looks like this:

[DataContract]
public class AuthToken
{
    [DataMember]
    public string access_token { get; set; }
    [DataMember]
    public string token_type { get; set; }
    [DataMember]
    public long expires_in { get; set; }
    [DataMember]
    public string userName { get; set; }
    [DataMember]
    public DateTime issued { get; set; }
    [DataMember]
    public DateTime expires { get; set; }
}

However, when I examine the authToken in the following code, the issued and expires DateTime values are set to the min datetime value (i.e. 1/1/0001 12:00:00 AM). The other values come back as expected, and the authorization attempt was successful.

HttpResponseMessage response = await httpClient.PostAsync("/MyAuthPath", authContent);
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(AuthToken));
Stream responseStream = await response.Content.ReadAsStreamAsync();
AuthToken authToken = (AuthToken)jsonSerializer.ReadObject(responseStream);

My suspicion is that because of the mismatch in variable names (.expires vs expires) that the JSON serializer isn't able to parse those fields. Specifically, the dot or period in the .expires is throwing things off.

What I'd like to do is take the .expires value from the JSON text and use that within my application to keep track of when the token expires. If the token has expired, I want to automatically request a new token before making my other web service calls.

I can't name AuthToken.expires as .expires as that's invalid syntax within C#.

How can I extract the .expires information from the returned JSON object? My preference would be to have the DataContractJsonSerializer handle this automatically for me, but I'm open to alternatives.


Solution

  • Use

        [DataMember(Name = "json_name")]
    

    like this:

    [DataContract]
    public class AuthToken 
    {
        [DataMember(Name = ".expires")]
        public long expires_in { get; set; }
    }
    

    And if you want to set default values, use this:

        [OnDeserializing]
        public void OnDeserializing(StreamingContext context)
        {
            expires_in = blabla
        }
    

    As you have a non-standard date format, you'll want to specify a serializer settings object in order to allow the datetimes to be processed. If you're using .NET 4.5 or later, you can use:

    DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(AuthToken),
        new DataContractJsonSerializerSettings
        {
            DateTimeFormat = new DateTimeFormat("ddd, dd MMM yyyy HH:mm:ss Z")
        });