.Net 中關於序列化和反序列化Json的方法

.Net SDK中關於序列化和反序列化Json的方法
項目中遇到和服務端交互時需要傳遞數據包爲json格式的包,所以在服務端和SDK中都需要對json進行解析和組合的操作, 並且對一些複雜結構的json格式的解析和序列化比較麻煩, 幸好,.Net提供一些方法的庫可以幫助我們完成一些工作,下面介紹一下利用.Net中的Newtonsoft.Json.dll庫對json進行序列化和反序列化操作。

Json操庫的介紹:
.NET自身有System.Runtime.Serialization.dll與System.Web.Extensions.dll,使用這兩個DLL可以把對象序列化和反序列化成Json數據。
也可以使用第三方的Newtonsoft.Json.dll來操作Json數據,使用它會更方便的操作Json數據,其功能也跟強一些。
但是:使用System.Web.Extensions.dll的限序列化, 一般不怎麼使用,因爲:要使用System.Web.Extensions.dll必須是在Web項目中,只有在Web項目中才能引用此DLL。
並且前兩種方式在項目中也沒怎麼用過,所以主要介紹第三種方式,利用Newtonsoft.Json.dll來操作json.
首先要將該動態庫加入到項目中,在.Net項目中直接添加引用即可。
1、 序列化
1.1 一般格式
要想得到一個最正常的以下格式的json結構:

{
        "status": "create",
        "subject": "envelope demo,sent recipients",
        "message": "demo sign...",
        "senderId": "0638bb2d-74c1-494b-ba50-e7caaf09ca77",
        "projectKey": "10000006"
}  

以下方法實現:
直接給json逐個字段構造

public class Json
    {
        JObject json { get; set; }
        public string GetJson()
        {
            this.json = new JObject();
            this.json["status"] = "create"; 
            this.json["subject"] = "envelope demo";
            this.json["message"] = "demo";
            this.json["senderId"] = "0638bb2d";
            this.json["projectKey"] = "10000006";
            return this.json.ToString();
        }
}

返回結果:

 Json objjson = new Json();
 string json = objjson.GetJson();

返回json爲上面我們指定格式的字符串。
1.2 對象
將對象直接格式化爲json字符串。
Eg:public class Json
{
public string status { set; get; }
public string subject { set; get; }
public string message { set; get; }
public string senderId { set; get; }
public string projectKey { set; get; }
}

直接序列化:
Json objjson = new Json();
objjson.status = "create";………
string jsonData = JsonConvert.SerializeObject(objjson);

返回結果和上面一樣的字符串, 前提是先給對象賦值, 如果不復制返回下面內容:

{"status":null,"subject":null,"message":null,"senderId":null,"projectKey":null}

注意:json key的名稱和對象中的一樣。 按照這樣的邏輯,發序列化對象的名稱要和json一樣才能將其反序列化出來。
1.3 數組
使用List構造數組進行序列化,首先定義對象,構造格式;
如果想得到下列格式的json:

"documents":    [
        { 
            "name": "demo.pdf",
            "fileKey": "$08ac5875-345a-4339-a6a3-fca02a85ba92$180375027",
            "templateRequired": "false",
            "templateId": "",
            "type": "pdf"
        }, 
        { 
            "name": "demo2.pdf", 
            "fileKey": "$08ac5875-325a-4339-a6a3-fca02a85ba92$180375046", 
            "templateRequired": "false", 
            "templateId": "", 
            "type": "pdf"
        }
    ]

則使用對象序列化;

  public class DocInfo 
    {
        public string Name { set; get; }
        public string FileKey { set; get; }
        public string  TemplateRequired { set; get; }
        public string TemplateId { set; get; }
        public string Type { set; get; }  
}
Void Main()
{
List<DocInfo> list = new List<DocInfo>();
            DocInfo info = new DocInfo();
            info.Name = "demo.pdf";
            info.FileKey = "$08ac5875 - 325a - 4339 - a6a3 - fca02a85ba92$180375046";
            info.TemplateRequired = "false";
            info.Type = "pdf";
            list.Add(info);

            info.Name = "demo2.pdf";
            info.FileKey = "$08ac5875-325a-4339-a6a3-fca02a85ba92$180375046";
        list.Add(info);

string jsonStr = JsonConvert.SerializeObject(list);//將對象轉換成json存儲
this.Json["documents"] = JArray.Parse(strRecipients);
}

得到的便是以上我們定義的結構了;
1.4 嵌套格式
對於嵌套格式,通常都是由以上的三點的簡單格式組成的,將其拆分合成後,組合到一起便可以了,或者定義對應結構的對象, 直接進行序列化即可完成。
2、 反序列化
2.1一般格式
解析如下格式:

string jsonText = "{\"zone\":\"海淀\",\"zone_en\":\"haidian\"}";
void main()
{
JObject jo = JObject.Parse(jsonData);
或者JObject jo = (JObject)JsonConvert.DeserializeObject(jsonData);

string zone = jo["zone"].ToString();
string zone_en = jo["zone_en"].ToString();
}

2.2對象
解析如下格式json:

string strJson = 
{
    "data":
    {
        "signedFileKey":"$f605cb35-2c4e-41f3-a16a-3eee41b39556$1638665701",
        "signLogId": "02f1a5ff-d3e4-48df-9684-aed92081d6a7"
    },
    "errCode": 0,
    "errShow": true,
    "msg": ""
}
定義一個對象:
namespace JsonOper
{
public class JSON
{
    public int ErrCode { get; set; }
    public bool ErrShow { get; set; }
    public string Msg { get; set; }
    public DATA data { set; get; }
}

public class DATA
{
    public string SignedFileKey { set; get; }
    public string SignLogId { set; get; }
}
}

JSON jo = JsonConvert.DeserializeObject<JSON>(strJson);

得到的結果便是一個反序列化好了的對象。
注:定義發序列化對象時,要對象json格式定義, 比如有嵌套, 對象格式也要嵌套, 否則無法反序列化成功, 並且定義時,對象中的變量名稱要和json中一直, 大小寫沒關係。
Eg:以上例子中

"errCode": 0,
"errShow": true,
"msg": ""

定義時可以定義爲:

public class JSON
{
    public int ErrCode { get; set; }
    public bool ErrShow { get; set; }
    public string Msg { get; set; }
}

因爲反序列化是對屬性的。 對象默認有一個小寫字母開頭的屬性;總之這個無傷大雅。 一般首字母大寫。
2.3數組
說來奇怪,項目中反序列化一個嵌套格式的json,定義了一個嵌套對象,但是竟然不成功, 一怒之下, 換了一種方法, 因爲懶的去查什麼原因了。
大體如下:

Json:
{
    "data": {
        "envelope": {
            "status": "Sent",
            "subject": "envelope demo,sent recipients",
            "message": "demo sign...",
             "redirectUrl": "http://xxxx.xxx.xxx/xxx",
             "notifyUrl": "http://xxxx.xxx.xxx/xxx",
            "senderId": "0638bb2d-74c1-494b-ba50-e7caaf09ca77",
            "senderName": "Wesley",
            "sentDateTime": "2017-08-17T06:55:48.6800000Z",
            "document": {
                "docUUID": "07ec608d-6840-4856-b599-783843efcdb6",
                "signFileKey": "08ec608d-6840-4856-b599-783843efcdb6",
                "name": "demo.pdf",
                "templateRequired": "false",
                "templateId": "",
                "type": "Pdf"
            },
            "recipients": [{
                "recipientId": "07ec608d-6840-4856-b599-783843efcdb6",
                "flowId": "44ec608d-6840-4856-b599-783843efcbc6",
                "currentHandlerFlag":"true",
                "licenseType": "IDCard",
                "licenseID": "362389xxxxxxxx8766",
                "routingOrder": "1",
                "type": "Signers",
                "email": "123@123.com",
                "phone": "12389978998",
                "accountUniqueId": "23344555",
                "departmentId": "dkdksjj",
                "departmentName": "department A",
                "autoSignFlag": "N",
                "signType": "PatientSign",
                "recipientType": "Personal",
                "status": "Signed",
                "predefineSign": {
                    "posType":"Free",
                    "key": "",
                    "posX": 0,
                    "posY": 0,
                    "posPage": "1"
                }
            },
            {
                "recipientId": "07ec608d-6840-4856-b599-783843efcdb6",
                "flowId": "",
                "currentHandlerFlag":"false",
                "licenseType": "IDCard",
                "licenseID": "362389xxxxxxxx8766",
                "routingOrder": "2",
                "type": "CC",
                "email": "123@123.com",
                "phone": "12389978998",
                "accountUniqueId": "23344555",
                "departmentId": "dkdksjj",
                "departmentName": "department B",
                "autoSignFlag": "N",
                "signType": "PatientSign",
                "recipientType": "Personal",
                "status": "Sent",
                "predefineSign": {
                    "posType":"Free",
                    "key": "",
                    "posX": 0,
                    "posY": 0,
                    "posPage": "1"
                }
            }]
        },
        "errCode": 0,
        "errShow": true,
        "msg": ""
    }
}

以上結構中,有嵌套對象, 有嵌套數組, 數組中嵌套對象。
解析方法:
定義對象:

namespace xxxx
{
    public class EnvelopInfoResult : Result
    {
        public EnvelopeDataResult EnvelopData { set; get; }

}
    public class EnvelopeDataResult
    {
        public string Status { set; get; }
        public String SubJect { set; get; }
        public String Message { set; get; }
        public String SenderId { set; get; }
        public String SenderName { set; get; }
        public string SentDateTime { set; get; }
        public DocInfoResult Document { set; get; }
        public List<RecipientsInfoPersonResult> PersonRecipientsInfos { set; get; }
        public List<RecipientsInfoDepartResult> DepartRecipientsInfos { set; get; }
    }
    public class DocInfoResult
    {
        public string DocUUID { set; get; }
        public string SignFileKey { set; get; }
        public string Name { set; get; }
        public string TemplateRequired { set; get; }
        public string TemplateId { set; get; }
        public string Type { set; get; }
    }

    public class PositionBeanResult
    {
        public string posType { set; get; }
        public string PosPage { set; get; }
        public string Key { get; set; }
        public float PosX { get; set; }
        public float PosY { get; set; }
        public float Width { get; set; }
    }

    public class RecipientsReturn : Recipients
{
        public string licenseType { set; get; } 
        public string licenseID { set; get; }        
       public string email { set; get; }
        public string phone { set; get; }
        public string accountUniqueId { set; get; }       
        public string recipientType { set; get; }          
        public string departmentId { set; get; }          
        public string autoSignFlag { set; get; }
        public string signType { set; get; }   
        public string ReciepientId { set; get; }
        public string FlowId { set; get; }
        public string CurrentHanderFlag { set; get; }  
        public string DepartmentName { set; get; }
        public string Status { set; get; }
    }
}

將json解析到以上定義對象中:

  JObject json = (JObject)JsonConvert.DeserializeObject(strJson);//轉換爲對象
  EnvelopInfoResult  result = EnvelopInfoResult.ParseJson(json);
   public static EnvelopInfoResult ParseJson(JObject json)
        {
            EnvelopInfoResult res = new EnvelopInfoResult();
            EnvelopeDataResult data = new EnvelopeDataResult();
            res.EnvelopData = data;

            res.ErrCode = int.Parse(json["errCode"].ToString());
            res.ErrShow = Convert.ToBoolean(json["errShow"].ToString());
            res.Msg = json["msg"].ToString();
            //Parse obj
        //轉換爲對象
            var obj = json["data"]["envelope"].ToObject<JObject>();
    //獲取對應字段值 
                 res.EnvelopData.Status = obj.GetValue("status").ToString();            res.EnvelopData.SubJect = obj.GetValue("subject").ToString();
            res.EnvelopData.Message = obj.GetValue("message").ToString();
            res.EnvelopData.SenderId = obj.GetValue("senderId").ToString();
            res.EnvelopData.SenderName = obj.GetValue("senderName").ToString();
            res.EnvelopData.SentDateTime = obj.GetValue("sentDateTime").ToString();
        //將document對象直接轉換爲定義的對象
            res.EnvelopData.Document = obj.GetValue("document").ToObject<DocInfoResult>();
        // recipients對應的數組部分是一個對象, 獲取json將其轉換成JArray數組,然後遍歷數組獲取每個字段對應的值。
            string strListJson = obj.GetValue("recipients").ToString();
            JArray jar = JArray.Parse(strListJson);

            foreach (var nobj in jar)
            {
                RecipientsReturn rec = nobj.ToObject<RecipientsReturn>();
                if ("Personal" == rec.recipientType)
                {
                    res.EnvelopData.PersonRecipientsInfos = new List<RecipientsInfoPersonResult>(); 
                    RecipientsInfoPersonResult Recp = new RecipientsInfoPersonResult();

                    Recp.ReciepientId = rec.ReciepientId;
                    Recp.FlowId = rec.FlowId;
                    Recp.CurrentHanderFlag = Convert.ToBoolean(rec.CurrentHanderFlag);
                    Recp.licenseType = GetType<LicenseType>(rec.licenseType);                      Recp.LicenseId = rec.licenseID;
                    Recp.RoutingOrder = rec.routingOrder;
                    Recp.Type = GetType<SendType>(rec.type);
                    Recp.Email = rec.email;
                    Recp.Phone = rec.phone;
                    Recp.AccountUniqueId = rec.accountUniqueId;
                    Recp.SignType = GetType<SignType>(rec.signType);
                    Recp.status = GetType<RecipientStatus>(rec.Status);
                    Recp.PredefineSign = SetPos(rec.predefineSign);
                    res.EnvelopData.PersonRecipientsInfos.Add(Recp);
                }
                else
                {
                    res.EnvelopData.DepartRecipientsInfos = new List<RecipientsInfoDepartResult>();
                    RecipientsInfoDepartResult Recd = new RecipientsInfoDepartResult();
                    Recd.RecipientId = rec.ReciepientId;
                    Recd.FlowId = rec.FlowId;
                    Recd.CurrentHandlerFlag = Convert.ToBoolean(rec.CurrentHanderFlag);
                    Recd.RoutingOrder = rec.routingOrder;
                    Recd.AccountUniqueId = rec.accountUniqueId;
                    Recd.DepartmentId = rec.departmentId;
                    Recd.AutoSignFlag = Convert.ToBoolean(rec.autoSignFlag);
                    Recd.status = GetType<RecipientStatus>(rec.Status);
                    Recd.PredefineSign = SetPos(rec.predefineSign);
                    res.EnvelopData.DepartRecipientsInfos.Add(Recd);
                }

            }
            return res;
        }

好了,打完收工。

發佈了79 篇原創文章 · 獲贊 91 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章