c# - 在 JSON 通用属性序列化中包含类名

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

我创建了以下类来表示对 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
}

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

最佳答案

如果它能帮助任何人,我会发布我的解决方法

我已经创建了一个自定义 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; }

这就是吹捧!

关于c# - 在 JSON 通用属性序列化中包含类名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41969671/

相关文章:

c# - 如何获得相同时间的日期时间?

python - 如何以 xml 节点的有序方式序列化 python ElementTree?

.net - 为什么 CLR 对象类型是可序列化的?

java - Map 子类的 Gson 序列化,也具有显式定义的属性

c# - 使用 View 模型的WPF MVVM更新模型

c# - 在 WPF C# 中将值从一个窗口传递到另一个窗口时出现问题

json - Coldfusion 无法显示正确的 JSON 对象

javascript - 将 jQuery 包装集写入 JSON 文件

c# - Facebook 喜欢 Ext3 按钮的通知图标

android - 在 Android 上将 JSON 从 String 加载到 JSONArray