C#中使用Newtonsoft.Json多态正反序列化

发布于:2025-03-01 ⋅ 阅读:(11) ⋅ 点赞:(0)

一、在通讯中,使用json字符串作为命令进行传递,发送接收方都需要序列化。

常见方法有两种,

1)使用TypeNameHandling = TypeNameHandling.All ,但是这种序列化的内容中包含命令空间信息,这种不利于两个应用统一。

JsonSerializerSettings jsonSet = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
string testStr = Newtonsoft.Json.JsonConvert.SerializeObject(cmd0, jsonSet);

2)重载JsonConverter类.

二、这里讲第2种方法

有三个命令类



    public class VMCmdBase
    {
        [JsonProperty(Order =-99)]
        public string mType = typeof(VMCmdBase).Name;

        [JsonProperty(Order = -98)]
        public int mCmdID = 1;

        public int mPara1 = 0;
        public int mPara2 = 0;
        public int mPara3 = 0;
        public int mPara4 = 0;
        public int mPara5 = 0;


        public virtual string ToJsonStr()
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(this);
        }

        public virtual void GetAllValue(object theObj)
        {
            Type thisTy = this.GetType();
            Type canTy = theObj.GetType();

            if (!thisTy.IsAssignableFrom(canTy)) {
                throw new ArgumentException("参数类型不正确");
            }
            VMCmdBase tempC = (VMCmdBase)theObj;
            mType = tempC.mType;
            mCmdID = tempC.mCmdID;
            mPara1 = tempC.mPara1;
            mPara2 = tempC.mPara2;
            mPara3 = tempC.mPara3;
            mPara4 = tempC.mPara4;
            mPara5 = tempC.mPara5;
        }
    }

    public class VMCmdResp1 : VMCmdBase
    {
        public bool mOKNG = false;

        public VMCmdResp1()
        {
            mType = this.GetType().Name;
        }
        public override string ToJsonStr()
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(this);
        }

        public override void GetAllValue(object theObj)
        {
            Type thisTy = this.GetType();
            Type canTy = theObj.GetType();

            if (!thisTy.IsAssignableFrom(canTy)) {
                throw new ArgumentException("参数类型不正确");
            }
            VMCmdResp1 tempC = (VMCmdResp1)theObj;
            base.GetAllValue(tempC);
            mOKNG = tempC.mOKNG;
        }
    }

    public class VMCmdResp2 : VMCmdBase
    {
        public bool mOKNG = false;
        public string mSN = "";

        public VMCmdResp2()
        {
            mType = this.GetType().Name;
        }

        public override string ToJsonStr()
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(this);
        }

        public override void GetAllValue(object theObj)
        {
            Type thisTy = this.GetType();
            Type canTy = theObj.GetType();

            if (!thisTy.IsAssignableFrom(canTy)) {
                throw new ArgumentException("参数类型不正确");
            }
            VMCmdResp2 tempC = (VMCmdResp2)theObj;
            base.GetAllValue(tempC);
            mOKNG = tempC.mOKNG;
            mSN = tempC.mSN;
        }
    }

重载类

public abstract class FHJsonCreationConverter<T> : JsonConverter
{
    protected abstract T Create(Type objectType, JObject jsonObject);
    public override bool CanConvert(Type objectType)
    {
        return typeof(T).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jsonObject = JObject.Load(reader);
        var target = Create(objectType, jsonObject);
        serializer.Populate(jsonObject.CreateReader(), target);
        return target;
    }

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

public class FHJsonConverter_VMCmd : FHJsonCreationConverter<VMCmdBase>
{
    protected override VMCmdBase Create(Type objectType, JObject jsonObject)
    {
        var typeName = jsonObject["mType"].ToString();
        switch (typeName) {
            case "VMCmdBase":
                return new VMCmdBase();
            case "VMCmdResp1":
                return new VMCmdResp1();
            case "VMCmdResp2":
                return new VMCmdResp2();
            default: return null;
        }
    }
}

最后主体使用

//=================================
VMCmdBase cmd0 = new VMCmdBase() { mCmdID = 1, mPara1 = 11 };
VMCmdResp1 cmd1 = new VMCmdResp1() { mCmdID = 2, mPara1 = 22, mOKNG=false };
VMCmdResp2 cmd2 = new VMCmdResp2() { mCmdID = 3, mPara1=33, mOKNG = true , mSN="abc"};

string cmd0Json = "";
string cmd1Json = "";
string cmd2Json = "";
 
//1.序列化
cmd0Json = Newtonsoft.Json.JsonConvert.SerializeObject(cmd0);
cmd1Json = Newtonsoft.Json.JsonConvert.SerializeObject(cmd1);
cmd2Json = Newtonsoft.Json.JsonConvert.SerializeObject(cmd2);

JsonSerializerSettings jsonSet = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
string testStr = Newtonsoft.Json.JsonConvert.SerializeObject(cmd0, jsonSet);

//2.反序列化 
VMCmdBase baseCmd = null; 
try {
    baseCmd = Newtonsoft.Json.JsonConvert.DeserializeObject<VMCmdBase>(cmd1Json, new FHJsonConverter_VMCmd());
} catch (Exception e) {
    baseCmd = null;
}
string asdf = baseCmd.GetType().Name;


网站公告

今日签到

点亮在社区的每一天
去签到