如何创建 C# 类以反序列化以方括号开头和结尾的 JSON 字符串

我从 API 收到一个 JSON 字符串,想将其反序列化为 C# 对象,但无法正确获取类。

我尝试使用http://json2csharp.com/创建类,但它无法解析 JSON,但是https://jsonlint.com/表示 JSON 有效。

我也试过运行JsonClassGeneratorLib但那说

无法将 Newtonsoft.Json.Linq.JValue 类型的对象转换为 Newtonsoft.Json.Linq.JObject

这似乎是一个问题,因为 JSON 包含在[]方括号中。我相信这是有效的,但将其放入数组中。我想我需要在课堂上的某个地方使用一个数组。

您可能需要使用显式映射来实现此目的:


在您的上下文的 OnModelCreating() 中:


modelBuilder.Entity<User>()

   .HasOptional(u => u.Promotion)

   .WithRequired(p => p.Pilote)

   .Map(u => u.MapKey("PiloteId"); // EF6

   // .HasForeignKey("PilotId") // EF Core

这假设用户可能有促销活动,也可能没有促销活动,但所有促销活动都有试点。Promotion.Users 可能会按照惯例在促销表上使用 UserId 进行映射,但如果存在任何问题:


但是,这种方法有一个很大的警告,它与模式有关,而不是 EF。没有任何限制/保护措施可以确保飞行员是与促销相关的用户之一。PiloteId 可以指向任何用户,并且该用户的 promotionId 可能不同。


在任何情况下,管理谁是飞行员的逻辑都需要通过代码来完成,但这意味着要么检查有效组合的 ID,要么像这样:


如果一个用户只能与 1 个促销相关联,并且该促销中的一个用户可以是试点,那么您可以考虑向用户添加一个名为“IsPilot”的标志。


然后在促销中:


public virtual ICollection<User> Users { get; set; } = new List<User>();

[NotMapped]

public User Pilote

{

   get { return Users.SingleOrDefault(u => u.IsPilote); }

   set 

   {   

      var newPilote = Users.Single(u => u.UserId == value.UserId); // Ensure the user nominated for Pilote is associated with this Promotion.

      var existingPilote = Pilote;

      if (existingPilote != null)

          existingPilote.IsPilote = false;

      newPilote.IsPilote = true;

   }

}string Json = @"[""error"",{""code"":2,""msg"":""This API Key is invalid""}]";


var obj = JsonConvert.DeserializeObject<RootObject>(Json);



public class CodeMsg

{

    [JsonProperty("code")]

    public long Code { get; set; }


    [JsonProperty("msg")]

    public string Msg { get; set; }

}



我总是得到错误


无法将当前 JSON 数组(例如 [1,2,3])反序列化为类型“ConsoleApp1.RootObject”,因为该类型需要 JSON 对象(例如 {"name":"value"})才能正确反序列化。要修复此错误,要么将 JSON 更改为 JSON 对象(例如 {"name":"value"}),要么将反序列化类型更改为数组或实现集合接口的类型(例如 ICollection、IList),就像List<T>这样从 JSON 数组反序列化

如果可以将用户分配给多个促销活动,那么您需要更新架构和映射以支持用户和促销活动之间的多对多关系,例如包含 UserId 和 PromotionId 的 UserPromotions 表。在这种情况下,我会考虑在此表/链接实体中分配 IsPilote,但这同样需要逻辑来确保每次促销围绕 1 个试点进行规则,以及用户是否可以成为多个促销的试点。


Qyouu
浏览 135回答 3
3回答

桃花长相依

试试这个:var&nbsp;obj&nbsp;=&nbsp;JsonConvert.DeserializeObject<List<Result>>(Json);说明:如果 JSON 是数组,则 C# RootObject 必须从 List/IEnumerable 本身派生,或者将其反序列化为类型的列表/数组。你可以转储你的RootObject班级。如果您想使用该RootObject类型,请使其派生自 List。但这不值得麻烦。

ITMISS

您的 JSON 是一个异构数组,包含一个字符串和一个对象。没有一点帮助,这不会干净地反序列化为强类型的类结构。一种可能的解决方案是使用这样的自定义JsonConverter:public class ResultConverter : JsonConverter{&nbsp; &nbsp; public override bool CanConvert(Type objectType)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return objectType == typeof(Result);&nbsp; &nbsp; }&nbsp; &nbsp; public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; JArray array = JArray.Load(reader);&nbsp; &nbsp; &nbsp; &nbsp; Result result = new Result&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String = array[0].Value<string>(),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cm = array[1].ToObject<CodeMsg>(serializer)&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; return result;&nbsp; &nbsp; }&nbsp; &nbsp; public override bool CanWrite&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; get { return false; }&nbsp; &nbsp; }&nbsp; &nbsp; public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; throw new NotImplementedException();&nbsp; &nbsp; }}然后使用如下属性将转换器绑定到您的Result类:[JsonConverter][JsonConverter(typeof(ResultConverter))]public class Result{&nbsp; &nbsp; public string String { get; set; }&nbsp; &nbsp; public CodeMsg cm { get; set; }}最后,将 JSON 反序列化到Result类中,如下所示:var result = JsonConvert.DeserializeObject<Result>(Json);工作演示:https ://dotnetfiddle.net/RLpm5W注意:您可以删除RootObject班级;这里不需要。

MM们

请确保您的 json 字符串必须具有与 JsonHolder 类相同的属性。public class JsonHolder{&nbsp; &nbsp; public string Id {get;set;}&nbsp; &nbsp; public string Name {get;set;}&nbsp; &nbsp; public string Gender {get;set;}}var jsonHolderList = new JsonConvert.DeserializeObject<List<JsonHolder>>(jsonString);var jsonHolder = jsonHolderList.Single()您还可以将 json 字符串转换为 c# 对象作为动态对象。请确保您的 json 字符串必须具有与 JsonHolder 类相同的属性。dynamic obj= new JsonConver.DeserializeObject<List<JsonHolder>>(StrJson);
打开App,查看更多内容
随时随地看视频慕课网APP