C# - Json 使用子属性反序列化对象



我有以下json:

{
"issue" : 
{
"id": 1,
"project":
{
"id":1,
"name":"name of project"
}
}
}

我正在尝试将此 json 反序列化为以下类:

public class Issue
{
public int? id { get; set; }
public int project_id { get; set; }
public string project_name { get; set; }
}

有没有办法获取子属性并设置为父亲?

最简单的解决方案之一是转换为JObject,然后使用它从中创建所需的对象。

var jObject = JsonConvert.DeserializeObject<JObject>(text);
var issue = new Issue() {id = (int?)jObject["issue"]["id"], project_id = (int)jObject["issue"]["project"]["id"], project_name = (string)jObject["issue"]["project"]["name"]};

下面的代码执行上述操作:

using System;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class Issue
{
public int? id { get; set; }
public int project_id { get; set; }
public string project_name { get; set; }
public override string ToString()
{
return "Id: " + id + " project Id: " + project_id + " project name : " + project_name;
}
}

public class Program
{
public static void Main()
{
var text = "{ "issue" :  { "id": 1, "project": { "id": 2, "name":"name of project" }}}";
var jObject = JsonConvert.DeserializeObject<JObject>(text);
var issue = new Issue() {id = (int?)jObject["issue"]["id"], project_id = (int)jObject["issue"]["project"]["id"], project_name = (string)jObject["issue"]["project"]["name"]};
Console.WriteLine(issue);
}
}

您可以在此处查看现场演示。

你需要为project创建新的类:

问题类别 :

public class Issue
{
public int id { get; set; }
public Project project { get; set; }
}

项目类别 :

public class Project
{
public int id { get; set; }
public String name { get; set; }
}

如果您确实需要在问题类中包含project_idproject_name,则可以这样做:

public class Issue
{
public int id { get; set; }
public Project project { get; set; }
public int getProjectId() {
return this.getProject.getId;
}
//Do the same for projectName
}

希望这有帮助。

这里有一种方法可以做到这一点

这是代码

public class ConventionBasedConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(YOUR-OBJECT).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var daat = JObject.Load(reader);
var yourObject = new YOUR-OBJECT();
foreach (var prop in yourObject GetType().GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance))
{
var attr = prop.GetCustomAttributes(false).FirstOrDefault();
if (attr != null)
{
var propName = ((JsonPropertyAttribute)attr).PropertyName;
if (!string.IsNullOrWhiteSpace(propName))
{
//split by the delimiter, and traverse recursevly according to the path
var conventions = propName.Split('/');
object propValue = null;
JToken token = null;
for (var i = 0; i < conventions.Length; i++)
{
if (token == null)
{
token = daat[conventions[i]];
}
else {
token = token[conventions[i]];
}
if (token == null)
{
//silent fail: exit the loop if the specified path was not found
break;
}
else
{
//store the current value
if (token is JValue)
{
propValue = ((JValue)token).Value;
}
}
}
if (propValue != null)
{
//workaround for numeric values being automatically created as Int64 (long) objects.
if (propValue is long && prop.PropertyType == typeof(Int32))
{
prop.SetValue(yourObject, Convert.ToInt32(propValue));
}
else
{
prop.SetValue(yourObject, propValue);
}
}
}
}
}
return yourObject;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
}
}

然后像这样使用它:

var settings = new JsonSerializerSettings();
settings.Converters.Add(new ConventionBasedConverter());
JsonConvert.DeserializeObject<YOUR-OBJECT>(jsonString, settings);

这是另一种方法。使用 Cinchoo ETL - 一个开源库以及 JSON 路径,您可以使用几行代码进行反序列化

public class Issue
{
[ChoJSONRecordField(JSONPath = "$..id")]
public int? id { get; set; }
[ChoJSONRecordField(JSONPath = "$..project.id")]
public int project_id { get; set; }
[ChoJSONRecordField(JSONPath = "$..project.name")]
public string project_name { get; set; }
}
static void Sample33()
{
string json = @"{
""issue"" : 
{
""id"": 1,
""project"":
{
""id"":1,
""name"":""name of project""
}
}
}";
var issue = ChoJSONReader<Issue>.LoadText(json).First();
}

免责声明:我是这个库的作者。

最新更新