Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I customize JSON serialization?

Currently I have a class that looks something like this:

public class TestSerilizer
{
    public int IntValue;
    public DateTime DTValue;
}

and a controller that returns that class serialized to JSON that looks something like this:

public ActionResult TestJson()
{
    TestSerilizer testDT = new TestSerilizer();
    return Json(testDT);
}

It is well known that this produces a date that looks something like /Date(123456)/ in the JSON which is less than desirable. For my purposes I'd like to be able to add an attribute that would format my dates in a way that makes sense for my view. Ideally I'd like to change my view model to look something like this:

public class TestSerilizer
{
    public int IntValue;
    [JSONDateFormatter("hh:mm tt")]
    public DateTime DTValue;
}

Which would produce a JSON data with the formatted date. Is there a way to hijack the JSON serialization to do something like that? It should be noted that this is a large code base that has both this implicit JSON serialization and explicit use of the JavaScriptSerializer class so I'd prefer a method that would work for both situations but I understand that may not be possible.

like image 445
Mykroft Avatar asked Feb 28 '13 16:02

Mykroft


People also ask

How do you serialize JSON?

NET objects as JSON (serialize) To write JSON to a string or to a file, call the JsonSerializer. Serialize method. The JSON output is minified (whitespace, indentation, and new-line characters are removed) by default.

How do I make an object JSON serializable?

Use toJSON() Method to make class JSON serializable So we don't need to write custom JSONEncoder. This new toJSON() serializer method will return the JSON representation of the Object. i.e., It will convert custom Python Object to JSON string.

How is custom serialization implemented in Java?

Customized serialization can be implemented using the following two methods: private void writeObject(ObjectOutputStream oos) throws Exception: This method will be executed automatically by the jvm(also known as Callback Methods) at the time of serialization.


1 Answers

This is generally how I manage serialization of dates for my objects. Note that this uses dataMember properties because it needs to be serializable by both binary and json:

[DataContract]
[Serializable]
public class YourClass
{
        [DataMember]
        private long timeStampLong;


        [IgnoreDataMember]
        public DateTime TimeStamp
        {
            get { return new DateTime(timeStampLong); }
            set { timeStampLong = value.Ticks; }
        }
}

Now this may not make the datetime as readable in json, but it will make it consistent. Different json libraries handle serializing datetime's differently, so you want to be able to force them all to serialize the same way.

Edit: Note that this is not a second property in the sense of C# properties but is just the underlying field for the property. You could make the underlying field a string instead, and that underlying field is never exposed outside of the object. Because of the IgnoreDataMember you are also still only serializing a single value.

Edit2: Added class declaration for a more complete answer when someone needs to implement this.

Edit: For a more complete example I thought I would include the other option I have used(with a string as the backing field)

    /// <summary>
    /// Representations of the TimeStamp used for serialization
    /// </summary>
    [DataMember(Name = "TimeStamp")]
    private String timeStamp;

    /// <summary>
    /// timestamp when the request is sent
    /// </summary>
    [IgnoreDataMember]
    public DateTime TimeStamp
    {
        get { return DateTime.Parse(timeStamp, null, DateTimeStyles.RoundtripKind); }
        set { timeStamp = value.ToUniversalTime().ToString("o"); }
    }
like image 79
jzworkman Avatar answered Oct 17 '22 13:10

jzworkman