25

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

kay.one
  • 7,622
  • 6
  • 55
  • 74

2 Answers2

36

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 });
mythz
  • 141,670
  • 29
  • 246
  • 390
  • I've tried that and I don't see that opt-in behaviour either, it seems like service stack completely ignores the DataContract/Member Attribute. I'm using the attributes in System.Runtime.Serialization. – kay.one Apr 11 '12 at 21:32
  • 1
    Ok this works for ServiceStack's JSON and JSV text serializers, I've just commited the change where the above also works for the QueryString and HTML Form POST parsing routine at: https://github.com/ServiceStack/ServiceStack/commit/e1d48d9d7e9e17c506e3759bfd0712cbad58280d - available on next release of ServiceStack on NuGet in a few days. You can use JSON or Request model binder in the meantime https://github.com/ServiceStack/ServiceStack/wiki/Serialization-deserialization – mythz Apr 11 '12 at 21:49
  • Is [DataContract] still the only way to customize the Property Name? As its not optimal when applying on a Base class, in a POCO env. – Daniel Halan Aug 30 '14 at 15:35
  • @mythz - The [documentation](https://github.com/ServiceStack/ServiceStack.Text) says, "At the moment it is not possible to customize the Property Name." May I assume that line in the documentation is out of date? – dbc May 04 '15 at 06:35
5

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);
    }
}
Community
  • 1
  • 1
Andrew Chaa
  • 6,120
  • 2
  • 45
  • 33