Nikolai Koudelia
Nikolai Koudelia

Reputation: 2639

Custom JSON serialization in ServiceStack

I'm trying to customize JSON serialization in ServiceStack (version 4.0.21.0). According to ServiceStack documentation here JSON serialization can be customized using a certain kind of struct.

The problem is that serialization upon a web service call appears to happen only one way and not the other. The ParseJson method is never called:

public struct Time
{
    private const string FORMAT = "yyyy-MM-dd HH:mm:ss";

    public DateTime Value { get; set; }

    public override string ToString()
    {
        return Value.ToString(FORMAT);
    }

    public static Time ParseJson(string json)
    {
        var d = DateTime.ParseExact(json, FORMAT, CultureInfo.InvariantCulture);

        return new Time{Value = d};
    }
}

Is this a bug or am I doing it wrong?

Upvotes: 2

Views: 1100

Answers (2)

Steven Song
Steven Song

Reputation: 51

It is not good idea.

JsConfig<DateTime>.SerializeFn = t => t.ToString(FORMAT);
JsConfig<DateTime>.DeSerializeFn = s => DateTime.ParseExact(s, FORMAT, CultureInfo.InvariantCulture);

this solution is for global settings, but requirements of datetime format are different. if birthday is "yyyy-MM-dd", but dateCreated is "yyyy-MM-dd HH:mm:ss".

public string Updatetime { get; set; }

datetime property is string, I convert it manually. I read datetime from datebase and format for web api.so it Serialize, but not DeSerialize, This is a bad idea, but it is very easy to use.

can ToJson() from ServiceStack.Text support ToJson(new DateTimeConverter { DateTimeFormat = "yyyy/MM/dd" })? so, we can convert datetime to a specific format.it is a good idea.

Upvotes: 0

Nikolai Koudelia
Nikolai Koudelia

Reputation: 2639

Yep, this seems to be a bug. I got it working by changing struct to class (although the documentation claims it should be a struct). Now the ParseJson gets called but the ToString doesn't :)

Adding a configuration setting fixed that one:

JsConfig<Time>.SerializeFn = t => t.ToString();

which, in turn, led to a proper solution, ie. configuring DateTime serialization and using it directly instead of the Time class:

JsConfig<DateTime>.SerializeFn = t => t.ToString(FORMAT);
JsConfig<DateTime>.DeSerializeFn = s => DateTime.ParseExact(s, FORMAT, CultureInfo.InvariantCulture);

Upvotes: 4

Related Questions