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

C# 如何为特定类型而不是全局设置Json.NET ContractSerializer?,c#,asp.net-web-api,json.net,C#,Asp.net Web Api,Json.net,我想为ASP.NET Web API应用程序中的某些类型设置一个协定序列化程序。我可以在App_Start/FormatterConfig.cs中全局设置如下: public static void RegisterGlobalFormatters(MediaTypeFormatterCollection formatters) { jsonSerializerSettings.ContractResolver = new CriteriaContractResolver(new Lis

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

public static void RegisterGlobalFormatters(MediaTypeFormatterCollection formatters)
{
    jsonSerializerSettings.ContractResolver = new CriteriaContractResolver(new List<string>(new string[]{"mdData", "name", "label"})); 
publicstaticvoidregisterGlobalFormatters(MediaTypeFormatterCollection格式化程序)
{
jsonSerializerSettings.ContractResolver=新的CriteriaContractResolver(新列表(新字符串[]{“mdData”、“name”、“label”}));

但是,我如何将其应用于一个或多个特定的类类型呢

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


您有几个选择:

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

    • 我会尝试创建这样的东西

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

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

      我最终使用了一个JsonConverter,它只写入“属性”列表中指定的参数。它的级别比ContractResolver或formatter低,但我认为无法为特定类型配置任何一个

      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();
          }
      }
      

      这看起来像是一种黑客行为,但我认为我应该使用契约解析器来获取要序列化的属性列表,而不是直接使用反射,但我不确定如何使用。

      似乎每个请求只根据要序列化的根对象的类型选择一次格式化程序。在我的情况下,它不起作用,因为我有一个wrapp我不想对其应用设置的JsonConverter对象。您的第一个选项使我创建了一个自定义JsonConverter,它的级别比格式化程序低,但我不知道如何为特定类型指定格式化程序。
      [JsonConverter(typeof(ResourceConverter))]