Skip to content

Instantly share code, notes, and snippets.

@MeirionHughes
Last active January 19, 2016 09:01
Show Gist options
  • Save MeirionHughes/6a5de2ea6304b73fcdf0 to your computer and use it in GitHub Desktop.
Save MeirionHughes/6a5de2ea6304b73fcdf0 to your computer and use it in GitHub Desktop.
Use DisplayNameAttribute value for exported $type when using Json.Net (DisplayNameSerializationBinder)
public class DisplayNameSerializationBinder : DefaultSerializationBinder
{
private Dictionary<string, Type> _nameToType;
private Dictionary<Type, string> _typeToName;
public DisplayNameSerializationBinder()
{
var customDisplayNameTypes =
this.GetType()
.Assembly
//concat with references if desired
.GetTypes()
.Where(x => x
.GetCustomAttributes(false)
.Any(y => y is DisplayNameAttribute));
_nameToType = customDisplayNameTypes.ToDictionary(
t => t.GetCustomAttributes(false).OfType<DisplayNameAttribute>().First().DisplayName,
t => t);
_typeToName = _nameToType.ToDictionary(
t => t.Value,
t => t.Key);
}
public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
if (false == _typeToName.ContainsKey(serializedType))
{
base.BindToName(serializedType, out assemblyName, out typeName);
return;
}
var name = _typeToName[serializedType];
assemblyName = null;
typeName = name;
}
public override Type BindToType(string assemblyName, string typeName)
{
if (_nameToType.ContainsKey(typeName))
return _nameToType[typeName];
return base.BindToType(assemblyName, typeName);
}
}
@MeirionHughes
Copy link
Author

usage:

var parameters = new Parameter[]
        {
            new BooleanParameter() {Name = "alive"},
            new StringParameter() {Name = "name", MinLength = 0, MaxLength = 10},
            new NumberParameter() {Name = "age", Min = 0, Max = 120},
            new EnumParameter() {Name = "status", Values = new[] {"Single", "Married"}}
        };

        JsonConvert.DefaultSettings = () => new JsonSerializerSettings
        {
            Binder = new DisplayNameSerializationBinder(),
            TypeNameHandling = TypeNameHandling.Auto,
            NullValueHandling = NullValueHandling.Ignore,
            DefaultValueHandling = DefaultValueHandling.Ignore,
            Formatting = Formatting.Indented,
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };

        var json = JsonConvert.SerializeObject(parameters);
        var loadedParams = JsonConvert.DeserializeObject<Parameter[]>(json);
        Console.WriteLine(JsonConvert.SerializeObject(loadedParams));

output:

[
  {
    "$type": "bool",
    "name": "alive"
  },
  {
    "$type": "string",
    "maxLength": 10,
    "name": "name"
  },
  {
    "$type": "number",
    "max": 120.0,
    "name": "age"
  },
  {
    "$type": "enum",
    "values": [
      "Single",
      "Married"
    ],
    "name": "status"
  }
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment