kay.one
kay.one

Reputation: 7692

Override field name deserialization in ServiceStack

I'm using ServiceStack to deserialize some HTML form values but can't figure out how to override the value that each field should be read from.

For example, the form posts a value to first_name but the property on my POCO is called FirstName. how would I do mapping like that in ServiceStack

Upvotes: 25

Views: 10170

Answers (2)

mythz
mythz

Reputation: 143319

The ServiceStack Text serializers support [DataMember] aliases where you can use the Name parameter to specify what alias each field should be, e.g:

[DataContract]
public class Customer
{
    [DataMember(Name="first_name")]
    public string FirstName { get; set; }

    [DataMember(Name="last_name")]
    public string LastName { get; set; }
}

Note: Once you add [DataContract] / [DataMember] attributes to your DTOs then the behavior becomes opt-in and you will have add [DataMember] on each of the properties you want serialized.

Emitting idiomatic JSON for all DTOs

You can instruct JSON serialization to follow a different convention by specifying the following global settings:

//Emit {"firstName":"first","lastName":"last"}
JsConfig.Init(new Config { TextCase = TextCase.CamelCase });

//Emit {"first_name":"first","last_name":"last"}
JsConfig.Init(new Config { TextCase = TextCase.SnakeCase });

Upvotes: 38

Andrew Chaa
Andrew Chaa

Reputation: 6378

In order to serialise C# class with underscore convention, you need to set JsConfig.EmitLowercaseUnderscoreNames to true as mythz said.

JsConfig.EmitLowercaseUnderscoreNames = true; 

But, in my experience, Deserialising would fail, as it expect CamelCased values. To enable underscore json value deserialisation, you need to set JsConfig's PropertyConvention.

JsConfig.PropertyConvention = PropertyConvention.Lenient;

I use a simple helper method to resolve the serialisation and deserialisation issue.

public static class JsonHelpers
{
    public static string ToUnderscoredJson<T>(this T obj)
    {
        JsConfig.EmitLowercaseUnderscoreNames = true;

        return JsConfig.PreferInterfaces
            ? JsonSerializer.SerializeToString(obj, AssemblyUtils.MainInterface<T>())
            : JsonSerializer.SerializeToString(obj);
    }

    public static T FromUnderscoredJson<T>(this string json)
    {
        JsConfig.PropertyConvention = PropertyConvention.Lenient;
        return JsonSerializer.DeserializeFromString<T>(json);
    }
}

Upvotes: 5

Related Questions