繁体   English   中英

使用JSON.Net的C#JSON字符串反序列化

[英]C# JSON String Deserialization using JSON.Net

我将有如下的JSON字符串,需要将其反序列化为以下类

{
    "Id":"1",
    "Names":{
        "string":"Surya"
    },
    "ClassTypes":{
        "Types":[
            {
                "TypeId":"1",
                "TypeName":"First Name"
            },
            {
                "TypeId":"2",
                "TypeName":"Last Name"
            }
        ]
    },
    "Status":"1",
    "DOB":"23/12/2014"
}

类定义

public class MyClass
{
    public int Id { get; set; }
    public IList<string> Names { get; protected set; }
    public IList<Types> ClassTypes { get; protected set; }
    public StatusType Status { get; set; }
    public DateTime DOB { get; set; }

    public MyClass()
    {
        Names = new List<string>();
        ClassTypes = new List<Types>();
        Status = StatusType.Active;
    }
}
public class Types
{
    public int TypeId { get; set; }
    public string TypeName { get; set; }
}

public enum StatusType
{
    Active = 0,
    InActive = 1
}

我已使用以下代码进行反序列化,但出现错误

var serializerSettings = new JsonSerializerSettings();
serializerSettings.ContractResolver = new IncludeNonPublicMembersContractResolver();
JsonConvert.DeserializeObject<MyClass>(jsonString, serializerSettings);

public class IncludeNonPublicMembersContractResolver : DefaultContractResolver
{
    public IncludeNonPublicMembersContractResolver()
    {
        DefaultMembersSearchFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
    }
    protected override List<MemberInfo> GetSerializableMembers(Type objectType)
    {
        var members = base.GetSerializableMembers(objectType);
        return members.Where(m => !m.Name.EndsWith("k__BackingField")).ToList();
    }

}

错误详情

无法将当前JSON对象(例如{“ name”:“ value”})反序列化为类型'System.Collections.Generic.IList`1 [System.String]',因为该类型需要JSON数组(例如[1,2, 3])正确反序列化。

要解决此错误,可以将JSON更改为JSON数组(例如[1,2,3]),也可以更改反序列化类型,使其成为普通的.NET类型(例如,不像整数这样的原始类型,也不像这样的集合类型)数组或列表),可以从JSON对象反序列化。 还可以将JsonObjectAttribute添加到类型中,以强制其从JSON对象反序列化。

路径“ Names.string”,第1行,位置28。

注意-我无法通过JSON字符串和解决方案进行更改以使其更通用,如果其他类也需要这样做:(

Names不是数组,而是对象:

public class Names
{
    public string @string { get; set; }
}

public class Type
{
    public string TypeId { get; set; }
    public string TypeName { get; set; }
}

public class ClassTypes
{
    public List<Type> Types { get; set; }
}

public class MyClass
{
    public int Id { get; set; }
    public Names Names { get; set; }
    public ClassTypes ClassTypes { get; set; }
    public string Status { get; set; }
    public string DOB { get; set; }
}
...

var result = JsonConvert.DeserializeObject<MyClass>(jsonString);

http://json2csharp.com/创建的类

一种方法是使用JsonConverter:

  public class MyClass
    {
        public int Id { get; set; }
        [JsonProperty("Names"), JsonConverter(typeof(NamesConverter))]
        public IList<string> Names { get; protected set; }
        [JsonProperty("ClassTypes"), JsonConverter(typeof(TypesConverter))]
        public IList<Types> ClassTypes { get; protected set; }
        public StatusType Status { get; set; }
        [JsonProperty("DOB"), JsonConverter(typeof(DateTimeConverter))]
        public DateTime DOB { get; set; }

        public MyClass()
        {
            Names = new List<string>();
            ClassTypes = new List<Types>();
            Status = StatusType.Active;
        }

        public override string ToString()
        {
            return
                string.Format("ID: {0}\nNames:\n{1}\nClassTypes:\n{2}Status: {3}\nDOB: {4}",
                Id, string.Join("\n", Names), string.Join("\n", ClassTypes), Status, DOB);
        }
    }
    public class Types
    {
        public int TypeId { get; set; }
        public string TypeName { get; set; }

        public override string ToString()
        {
            return string.Format("\tTypeId: {0}\n\tTypeName: {1}\n", TypeId, TypeName);
        }
    }

    public enum StatusType
    {
        Active = 0,
        InActive = 1
    }

    class NamesConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return typeof(Dictionary<string, string>).IsAssignableFrom(objectType);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            return serializer.Deserialize<Dictionary<string, string>>(reader).Values.ToList();
        }

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

    }
    class TypesConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return typeof(Dictionary<string,List<Types>>).IsAssignableFrom(objectType);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            return serializer.Deserialize<Dictionary<string,List<Types>>>(reader)
                .Values.First().ToList();
        }

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

    }
    class DateTimeConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return typeof(string).IsAssignableFrom(objectType);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            return DateTime.ParseExact(serializer.Deserialize<string>(reader), @"dd\/MM\/yyyy", null);
        }

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

    }

...

    var jsonobj = JsonConvert.DeserializeObject<MyClass>(json);
    Console.WriteLine(jsonobj);

打印:

Names:
Surya
ClassTypes:
    TypeId: 1
    TypeName: First Name

    TypeId: 2
    TypeName: Last Name
Status: InActive
DOB: 12/23/2014 12:00:00 AM

https://dotnetfiddle.net/EfQuET

两种方法-解析json,但随后您需要更改对Names,ClassTypes属性的访问权限或添加构造函数:

var jObject = JObject.Parse(json);
var names = new List<string> 
{ 
    jObject["Names"].Value<string>("string")
};
var types = jObject["ClassTypes"]["Types"]
    .Select(x => new Types
    {
        TypeId = x.Value<int>("TypeId"),
        TypeName = x.Value<string>("TypeName")
    })
        .ToList();
var data = new MyClass(names,types)
{
    Id = jObject.Value<int>("Id"),
    Status = (StatusType)Enum.Parse(typeof(StatusType),jObject.Value<string>("Status")),
    DOB = DateTime.ParseExact(jObject.Value<string>("DOB"), @"dd\/MM\/yyyy", null)
};

Console.WriteLine(data);

https://dotnetfiddle.net/HcPxT9

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM