Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反序列化集合中的匿名类型_C#_Json_Json.net - Fatal编程技术网

C# 反序列化集合中的匿名类型

C# 反序列化集合中的匿名类型,c#,json,json.net,C#,Json,Json.net,我的序列化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 Nam

我的序列化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
。您可以使用Linq并从中选择
First()
,如下所示

RootObject = RootObjects.FirstOrDefault()

为什么是匿名对象?您应该反序列化为如下类型

public class RootObject
{
    public string Name { get; set; }
    public string Value { get; set; }
} 
那么您实际拥有的是
IEnumerable
。您可以使用Linq并从中选择
First()
,如下所示

RootObject = RootObjects.FirstOrDefault()

您可以将其反序列化为动态。像这样:

var serializer = new JavaScriptSerializer();
var deserializedResult = serializer.Deserialize<dynamic>(json);
var serializer=newJavaScriptSerializer();
var deserializedResult=serializer.Deserialize(json);
参考:


    • 您可以将其反序列化为动态。像这样:

      var serializer = new JavaScriptSerializer();
      var deserializedResult = serializer.Deserialize<dynamic>(json);
      
      var serializer=newJavaScriptSerializer();
      var deserializedResult=serializer.Deserialize(json);
      
      参考:

      来源


      source

      我知道此解决方案并不完美,但它适用于您提供的示例,并返回类似于示例中的
      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();
          }
      }
      
      公共类DynamicJsonConverter:JsonConverter
      {
      公共覆盖布尔CanConvert(类型objectType)
      {
      返回true;
      }
      公共重写对象ReadJson(JsonReader reader,类型objectType,
      对象存在值,JsonSerializer序列化程序)
      {        
      JToken令牌=JToken.Load(读卡器);
      if(token==null | | token.Type!=JTokenType.Array)
      {
      返回null;
      }
      List parsedJson=token.ToObject();
      ExpandoObject结果=新的ExpandoObject();
      foreach(parsedJson中的NameValueJsonItem项)
      {
      如果(!String.IsNullOrEmpty(item.Name))
      {
      (结果为IDictionary)[item.Name]=item.Value;
      }
      }
      返回结果;
      }
      公共重写void WriteJson(JsonWriter writer,对象值,
      JsonSerializer(序列化程序)
      {
      抛出新的NotImplementedException();
      }
      }
      
      当然,如果需要,可以通过在方法中添加一些异常处理等来提高安全性

      您可以这样使用此转换器:

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

      希望它能有所帮助。

      我知道这个解决方案并不完美,但它适用于您提供的示例,并且返回的结果与您的示例中的
      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();
          }
      }
      
      公共类DynamicJsonConverter:JsonConverter
      {
      公共覆盖布尔CanConvert(类型objectType)
      {
      返回true;
      }
      公共重写对象ReadJson(JsonReader reader,类型objectType,
      对象存在值,JsonSerializer序列化程序)
      {        
      JToken令牌=JToken.Load(读卡器);
      if(token==null | | token.Type!=JTokenType.Array)
      {
      返回null;
      }
      List parsedJson=token.ToObject();
      ExpandoObject结果=新的ExpandoObject();
      foreach(parsedJson中的NameValueJsonItem项)
      {
      如果(!String.IsNullOrEmpty(item.Name))
      {
      (结果为IDictionary)[item.Name]=item.Value;
      }
      }
      返回结果;
      }
      公共重写void WriteJson(JsonWriter writer,对象值,
      JsonSerializer(序列化程序)
      {
      抛出新的NotImplementedException();
      }
      }
      
      当然,如果需要,可以通过在方法中添加一些异常处理等来提高安全性

      您可以这样使用此转换器:

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

      希望这会有所帮助。

      因为您说过JSON对象中的
      名称
      属性的值可能不同,所以您将无法反序列化到匿名对象。匿名类型是在编译时定义的,这意味着您需要提前知道属性名称才能定义它们。唯一的解决方法是代码生成,我认为在这种情况下,代码生成是一种过火的行为。相反,我建议您使用动态变量反序列化到
      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"])));
      
      从那里,您可以像访问匿名类型一样访问属性(假设您知道它们是什么):

      如果不知道属性是什么,可以像字典一样枚举它们:

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

      Fiddle:

      因为您说过JSON对象中的
      名称
      属性的值可能会不同,所以您将无法反序列化到匿名对象。匿名类型是在编译时定义的,这意味着您需要提前知道属性名称才能定义它们。唯一的解决方法是代码生成,我认为在这种情况下,代码生成是一种过火的行为。相反,我建议您使用动态变量反序列化到
      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"])));
      
      从那里,您可以像访问匿名类型一样访问属性(假设您知道它们是什么):

      如果不知道属性是什么,可以像字典一样枚举它们:

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

      Fiddle:

      。看看这个:JSON是固定的还是动态的?换句话说,名称的值是否可以更改,或者它们是否总是
      std_id
      cust_id
      ?如果它们可以更改,则反序列化