簡體   English   中英

反序列化集合中的匿名類型

[英]Deserialize an Anonymous Type From a Collection

我有以下格式的序列化JSON:

string json = @"[{"Name": "std_id","Value": "111"}, {"Name": "cust_id","Value": "444"}]"

如何將其反序列化為單個匿名對象,如下所示:

var paramObj = new {"std_id" = 111, "cust_id" = 444}

為什么要匿名對象? 您應該反序列化為如下類型

public class RootObject
{
    public string Name { get; set; }
    public string Value { get; set; }
} 

然后,您實際擁有的是IEnumerable<RootObjct> 您可以使用use Linq並從中選擇First()

RootObject = RootObjects.FirstOrDefault()

您可以將其反序列化為動態。 像這樣:

var serializer = new JavaScriptSerializer();
var deserializedResult = serializer.Deserialize<dynamic>(json);

參考:

由於您說的是JSON對象中NameValue屬性的值可以變化,因此您將無法反序列化為匿名對象。 匿名類型是在編譯時定義的,這意味着您需要提前知道屬性名稱才能定義它們。 解決該問題的唯一方法是代碼生成,我認為在這種情況下這會顯得過分殺傷力。 相反,我建議您反序列化為帶有動態變量的JObject 這將使您非常接近所需的內容。 這是如何做:

string json = @"[
  { ""Name"": ""std_id"", ""Value"": ""111"" },
  { ""Name"": ""cust_id"", ""Value"": ""444"" }
]";

dynamic obj = new JObject(JArray.Parse(json)
                  .Select(t => new JProperty((string)t["Name"], t["Value"])));

從那里,您可以像訪問匿名類型一樣訪問屬性(假設您知道它們是什么):

Console.WriteLine(obj.std_id);
Console.WriteLine(obj.cust_id);

如果您不知道屬性是什么,則可以像字典一樣枚舉它們:

foreach (var prop in obj)
{
    Console.WriteLine(prop.Name + ": " + prop.Value);
}

小提琴: https : //dotnetfiddle.net/MRY2ny

var definition = new { Name = "" };
string json1 = @"{'Name':'James'}";
var customer1 = JsonConvert.DeserializeAnonymousType(json1, definition);
Console.WriteLine(customer1.Name);
string json2 = @"{'Name':'Mike'}";
var customer2 = JsonConvert.DeserializeAnonymousType(json2, definition);
Console.WriteLine(customer2.Name);

來源http://www.newtonsoft.com/json/help/html/DeserializeAnonymousType.htm

我知道此解決方案並不完美,但它可用於您提供的示例,並返回類似於您示例中的paramObj結果。

這個想法是創建一個自定義的Json轉換器。

首先,讓我們創建一個DTO類,以顯示傳入的JSON的名稱-值項。

public class NameValueJsonItem
{
    public string Name { get; set; }

    public string Value { get; set; }
}

轉換器實現:

public class DynamicJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, 
        object existingValue, JsonSerializer serializer)
    {        
        JToken token = JToken.Load(reader);

        if (token == null || token.Type != JTokenType.Array)
        {
            return null;
        }

        List<NameValueJsonItem> parsedJson = token.ToObject<List<NameValueJsonItem>>();

        ExpandoObject result = new ExpandoObject();

        foreach (NameValueJsonItem item in parsedJson)
        {
            if (!String.IsNullOrEmpty(item.Name))
            {
                (result as IDictionary<string, object>)[item.Name] = item.Value;
            }
        }

        return result;
    }

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

當然,如果需要,您可以通過在方法內部添加一些異常處理等來使其更加安全。

您可以像這樣使用此轉換器:

dynamic result = JsonConvert.DeserializeObject<dynamic>(json, new DynamicJsonConverter());

希望它會有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM