2017-07-30

從 Json String 中取得物件的屬性值

之前文章 使用 string 建立 instance 及反序列化 json 為 class 介紹到如何使用 string 產生 instance 及反序列化 json 為 class,後來同事看到寫法建議可以用 json.net 的 JObject.Parse 語法

後來試了一下,覺得滿方便的,但用途不太一樣,順手紀錄一下


基本設定

本文會延續 使用 string 建立 instance 及反序列化 json 為 class 來進行比較,詳細資訊可以參考 使用 string 建立 instance 及反序列化 json 為 class 內容

  1. 共用的 model class
    public class User
    {
     public Guid _internalId { get; set; }
     public string Id { get; set; }
     public string Name { get; set; }
     public string Addr { get; set; }
     public string Phone { get; set; }
     public int BirthMonth { get; set; }
    }
    
  2. 呼叫遠端方法時,一併提供
    • class 的 AssemblyQualifiedName
    • model instance 的 json string
  3. 遠端需要取得 json string 的屬性值進行操作

將 json string 反序列化指定 class

void Deserialize(string typename, string jsonstr)
{
 Type dataType = Type.GetType(typename);
 var obj = JsonConvert.DeserializeObject(jsonstr, dataType);
 // do something
}

改使用 JObject.Parse

  1. 發送端程式碼
    void Main()
    {
     var typename = typeof(User).AssemblyQualifiedName;
    
     User dto = new User() { _internalId = Guid.NewGuid(), Name = "Yowko", Addr = "Taipei", BirthMonth = 7, Id = "A123456789", Phone = "09123456789" };
     var jsonstr = JsonConvert.SerializeObject(dto);
     SendObj(typename, jsonstr);
    }
    void SendObj(string typename, string jsonstr)
    {
     //web request
    }
    public class PstData
    {
     public string typename { get; set; }
    
     public string jsonstr { get; set; }
    }
    
  2. 接收端程式碼
    public IHttpActionResult Post([FromBody]PstData value)
    {
     Deserialize(value.typename, value.jsonstr);
    }
    
    void Deserialize(string typename, string jsonstr)
    {
     JObject.Parse(jsonstr).Dump();
     // do something
    }
    
  3. 實際效果

    1jobjectparse

兩者效果比較

2compare

  • 結果型別不同
    • JsonConvert.DeserializeObject 會在執行時期將 json string 轉型為目標型別
    • JObject.Parse 會將 json string 轉為 JObject
  • 特定屬性操作
    • JsonConvert.DeserializeObject 在開發時間僅擁有 object 的相關 api 可用

      只能使用 reflection

      • obj.GetType().GetProperties().Skip(1).Take(1).FirstOrDefault().GetValue(obj);
    • JObject.Parse 可以使用 JObject 功能

      可以指定屬性名稱或是屬性位置取得實際值

      • obj.Property("Name")
      • obj.Properties().AsJEnumerable().Skip(1).Take(1)

心得

如果需要完整將 json string 還原為特定 class,就使用 JsonConvert.DeserializeObject,可以取得完整的屬性名稱及值

如果只需取得值來進行操作,就使用 JObject.Parse 相對方便,也不用擔心,class 名稱錯誤或是轉型失敗的問題

參考資訊

  1. 使用 string 建立 instance 及反序列化 json 為 class
  2. JObject
  3. JObject.Parse Method

沒有留言:

張貼留言