如何为某个特定类型而不是全局设置Json.NET ContractSerializer?

我想在我的ASP.NET Web API应用程序中为某些类型设置一个契约序列化程序。 我可以在App_Start / FormatterConfig.cs中全局设置设置,如下所示:

public static void RegisterGlobalFormatters(MediaTypeFormatterCollection formatters) { jsonSerializerSettings.ContractResolver = new CriteriaContractResolver(new List(new string[]{"mdData", "name", "label"})); 

但是我怎样才能将它应用于一个或多个特定的类类型?

我想这样做的原因是因为我需要能够根据Web服务的配置或参数设置在运行时应该序列化哪些字段,类似于这些示例:

使用JSON.net,在基类上下文中使用时,如何防止派生类的属性序列化?

http://json.codeplex.com/discussions/347610

你有几个选择:

  • 创建由自定义格式化程序处理的自定义类型。 此自定义类型可以指定(以某种方式)需要序列化的字段(然后将该信息提供给Json序列化程序)
  • 查看每个控制器配置(请参阅此处 )以尝试设置格式化程序为requried

我最终使用的JsonConverter只写了“属性”列表中指定的参数。 它比ContractResolver或格式化程序更低级别,但我认为不可能为特定类型配置任何一个。

 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 properties = new List(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(); } } 

这可以应用于使用属性的类:

 [JsonConverter(typeof(ResourceConverter))] 

这似乎是一个黑客,我想我应该使用合约解析器来获取序列化的属性列表,而不是直接使用reflection,但我不知道如何。

我会尝试创建这样的东西

 public class MyJsonFormatter : JsonMediaTypeFormatter { public override bool CanWriteType(Type type) { return type == typeof(MyClass); } } 

然后将其插入到formatters集合的开头