【问题标题】:C# How to deserialize the Json to a generic entity use base-class?C#如何将Json反序列化为通用实体使用基类?
【发布时间】:2018-06-10 06:11:52
【问题描述】:

我需要将 JSON 对象转换为实体, 我有很多实体,有时我不想编写代码,所以我构建了一个实体基类,我想对实体进行反序列化(不知道哪个派生实体调用基实体)。

我可以吗?

这是我的基类(它是抽象类)

  public abstract class AbstractEntity
{
    EntityState EntityState { get; set; }
    DateTime CreatedDate { get; set; }
    DateTime? ModifiedDate { get; set; }
    string CreatedBy { get; set; }
    string ModifiedBy { get; set; }

    public EntityState getEntityState()
    {
        return EntityState;
    }
    public void SetEntityState(EntityState entityState)
    {
        EntityState = entityState;
    }            
}

第一个条目:

public class TABLE1: AbstractEntity
{
    public TABLE1();

    public string ID{ get; set; }

    public string ADDRESS{ get; set; }
    public virtual ICollection<TABLE2> TABLE2 { get; set; }
}

第二个词:

public class TABLE2: AbstractEntity
{
    public TABLE2();

    public string ID{ get; set; }

    public string ADDRESS{ get; set; }
    public virtual TABLE1 TABLE1{ get; set; }
}

【问题讨论】:

标签: c# json asp.net-mvc entity-framework-6


【解决方案1】:

重复链接可能是更好的通用解决方案:

public class AbstractEntityConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(AbstractEntity);
    }

    public override object ReadJson(JsonReader reader,
        Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject item = JObject.Load(reader);
        var type = item["TYPE"].Value<string>();
        switch (type)
        {
            case "TABLE1":
                return item.ToObject<TABLE1>();
            case "TABLE2":
                return item.ToObject<TABLE2>();
            default:
                return null;
        }
    }

    public override void WriteJson(JsonWriter writer,
        object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

用法:

string json = "{\"TYPE\":\"TABLE1\",\"CreatedDate\":\"2018-06-10T08:00:00.000Z\",\"CreatedBy\":\"John\",\"ID\":\"1\",\"ADDRESS\":\"1 Road Street\",\"TABLE2\":[{\"CreatedDate\":\"2018-06-10T08:00:00.000Z\",\"CreatedBy\":\"John\",\"ID\":\"2\",\"ADDRESS\":\"2 Road Street\"}]}";
var settings = new JsonSerializerSettings()
{
    Converters = new List<JsonConverter>()
    {
        new AbstractEntityConverter()
    }
};
var obj = JsonConvert.DeserializeObject<AbstractEntity>(json, settings);

当然,您可以在一个中心位置定义您的 JsonSettings,这样您就不必在每次使用时都编写声明。

附:我选择假设一个“类型”属性,因为您没有显示您的 JSON,或者您确定要反序列化到哪个类的方法。根据需要替换为您自己的逻辑。

Try it online

【讨论】:

    【解决方案2】:

    您可以使用来自Newtonsoft.Json 库的JObject。这是网站https://www.newtonsoft.com/json 以了解如何使用它。而且,很多代码示例也可以在这里找到https://www.newtonsoft.com/json/help/html/Samples.htm

    例如:

    using Newtonsoft.Json.Serialization;
    
        public void Foo(string jsonData){
        var objData = (JObject)JsonConvert.DeserializeObject(jsonData); // Deserialize json data
    
        dynamic jObject = new JObject();
    jObject.ID = objData.Value<string>("ID");
    jObject.Address = objData.Value<string>("Address");
    jObject.TABLE2 = objData.Value<JArray>("TABLE2");
        }
    

    在上面的代码示例中,jObject 有一个动态类型,可以转换成你想要的类型。

    希望这会有所帮助。

    【讨论】:

    • 朱尼厄斯,谢谢!所以我不需要对基类进行任何更改?
    • 不用担心@user1012506,如果你想要的话,你不必改变你的基类。很简单,您可以通过使用 dynamic 关键字来实例化类型对象而无需实际类型。有关dynamicstackoverflow.com/questions/2690623/…的更多详细信息,您可以参考这个SO答案
    • 好的,所以我不能写一个通用的反序列化,这就是答案! (我要求在基类中反序列化,故意不写重复代码)
    • @user1012506,是的,您可以使用 T 类型来反序列化您的 json 数据。例如:var fooBar = JsonConvert.DeserializeObject&lt;dynamic&gt;(jsonData);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    • 2012-06-22
    • 2021-09-27
    • 1970-01-01
    • 2018-09-19
    • 1970-01-01
    相关资源
    最近更新 更多