【问题标题】:include Class Name in JSON Generic Property Serialization在 JSON 通用属性序列化中包含类名
【发布时间】:2017-01-31 23:54:41
【问题描述】:

我创建了以下类来表示 REST API 请求的任何服务器响应:

[DataContract]
public class ServerResponse<T>
{
    [DataMember(Name = "error")]
    public string ErrorMessage { get; set; }

    [DataMember(Name = "data")]
    public T Data { get; set; }

    [DataMember(Name = "success")]
    public bool Success { get; set; } 
}

将它与像这样的简单类一起使用时

[DataContract(Name = "category")]
public class Category
{
    [DataMember(Name = "id")]
    public int Id { get; set; }

    [DataMember(Name = "name")]
    public string Name { get; set; }
}

我收到以下回复

{
  "error": "",
  "data": {
      "id": 3,
      "name": "Top"
   },
  "success": true
}

我想在序列化中包含泛型类型类名称。想要的结果:

{
  "error": "",
  "data": {
      "category": {
          "id": 3,
          "name": "Top"
      }
   },
  "success": true
}

我该怎么做? (我在类似帖子中看到过答案,但没有一个适用于像这样的通用场景)

【问题讨论】:

    标签: c# json serialization asp.net-web-api asp.net-web-api2


    【解决方案1】:

    如果对任何人都有帮助,我将发布我的解决方法

    我创建了一个自定义的 Json 转换器

    public class GenericTypeJsonSerializer : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            // Parse data object
            var dataObject = JToken.FromObject(value);
    
            // Extract generic type class serialization name
            var className = ExtractClassName(value);
    
            // Create wrapper object that includes generic class name
            JObject wrapperObject = new JObject();
            wrapperObject.Add(className, dataObject);
    
            // write object
            wrapperObject.WriteTo(writer);
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    
        public override bool CanConvert(Type objectType)
        {
            return true;
        }
    
        public string ExtractClassName(object value)
        {
            // extract data contract attribute
            var dataContractAttribute = value.GetType()
                .GetCustomAttribute(typeof(DataContractAttribute)) as DataContractAttribute;
            // return name declared in attribute
            if (dataContractAttribute?.Name != null)
                return dataContractAttribute.Name;
    
            // return default class name
            return value.GetType().Name;
        }
    }
    

    我已经用JsonConverter 属性修饰了通用的Data 属性

        [JsonConverter(typeof(GenericTypeJsonSerializer))]
        [DataMember(Name = "data")]
        public T Data { get; set; }
    

    吹嘘!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多