为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
Qyouu 2022-12-31 09:41:12
我从 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 个试点进行规则,以及用户是否可以成为多个促销的试点。
查看完整描述

3 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

试试这个:

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

说明:如果 JSON 是数组,则 C# RootObject 必须从 List/IEnumerable 本身派生,或者将其反序列化为类型的列表/数组。

你可以转储你的RootObject班级。如果您想使用该RootObject类型,请使其派生自 List。但这不值得麻烦。


查看完整回答
反对 回复 2022-12-31
?
ITMISS

TA贡献1871条经验 获得超8个赞

您的 JSON 是一个异构数组,包含一个字符串和一个对象。没有一点帮助,这不会干净地反序列化为强类型的类结构。一种可能的解决方案是使用这样的自定义JsonConverter:


public class ResultConverter : JsonConverter

{

    public override bool CanConvert(Type objectType)

    {

        return objectType == typeof(Result);

    }


    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)

    {

        JArray array = JArray.Load(reader);

        Result result = new Result

        {

            String = array[0].Value<string>(),

            cm = array[1].ToObject<CodeMsg>(serializer)

        };

        return result;

    }


    public override bool CanWrite

    {

        get { return false; }

    }


    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)

    {

        throw new NotImplementedException();

    }

}

然后使用如下属性将转换器绑定到您的Result类:[JsonConverter]


[JsonConverter(typeof(ResultConverter))]

public class Result

{

    public string String { get; set; }

    public CodeMsg cm { get; set; }

}

最后,将 JSON 反序列化到Result类中,如下所示:


var result = JsonConvert.DeserializeObject<Result>(Json);

工作演示:https ://dotnetfiddle.net/RLpm5W


注意:您可以删除RootObject班级;这里不需要。


查看完整回答
反对 回复 2022-12-31
?
MM们

TA贡献1886条经验 获得超2个赞

请确保您的 json 字符串必须具有与 JsonHolder 类相同的属性。


public class JsonHolder

{

    public string Id {get;set;}

    public string Name {get;set;}

    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);


查看完整回答
反对 回复 2022-12-31
  • 3 回答
  • 0 关注
  • 133 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信