Reputation: 2207
I want to set a contract serializer just for certain types in my ASP.NET Web API application. I can set the settings globally in the App_Start/FormatterConfig.cs like this:
public static void RegisterGlobalFormatters(MediaTypeFormatterCollection formatters)
{
jsonSerializerSettings.ContractResolver = new CriteriaContractResolver(new List<string>(new string[]{"mdData", "name", "label"}));
...
but how can I just apply this to one or more specific class types?
The reason I want to do this is because I need to be able to set what fields should be serialized at runtime based on configuration or parameters to the web service similar to these examples:
http://json.codeplex.com/discussions/347610
Upvotes: 9
Views: 6009
Reputation: 2207
I ended up using a JsonConverter that only writes the parameters that are specified in the "properties" list. It's more low level than a ContractResolver or a formatter, but I don't think it's possible to configure either one for a specific type.
public class ResourceConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(Resource));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
List<string> properties = new List<string>(new string[] { "Name", "Label" });
writer.WriteStartObject();
foreach (MemberInfo mi in value.GetType().GetMembers(BindingFlags.GetField | BindingFlags.Instance | BindingFlags.Public) )
{
PropertyInfo p = mi as PropertyInfo;
if (p != null && p.GetCustomAttributes(typeof(JsonIgnoreAttribute), true).Length == 0 && properties.Contains(p.Name))
{
writer.WritePropertyName(p.Name);
serializer.Serialize(writer, p.GetValue(value, new object[] { }));
}
}
writer.WriteEndObject();
}
}
This can be applied to a class using the attribute:
[JsonConverter(typeof(ResourceConverter))]
This seems like a hack though, I think I should use the contract resolver to get the list of properties to serialize instead of using reflection directly, but I'm not sure how.
Upvotes: 2
Reputation: 142014
I would try creating something like this
public class MyJsonFormatter : JsonMediaTypeFormatter
{
public override bool CanWriteType(Type type)
{
return type == typeof(MyClass);
}
}
and then insert this into the beginning of the formatters collection
Upvotes: 0
Reputation: 772
You have a few options:
Upvotes: 4