英文:
How to deserialize json array of objects into object with properties?
问题
以下是翻译后的代码部分:
public class Point
{
public string title { get; set; }
public string category { get; set; }
public DateTime? created { get; set; }
public int? version { get; set; }
}
在这里,您定义了一个名为Point
的类,该类具有与JSON中的属性名称相匹配的属性。
要实现您的目标,您可以考虑使用自定义的JSON转换器来处理反序列化。在.NET 4.8 Framework中,可以使用Newtonsoft.Json
库进行此操作,而不是System.Text.Json
。以下是如何使用Newtonsoft.Json
进行反序列化和转换的示例代码:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Linq;
public class PointConverter : JsonConverter<Point>
{
public override Point ReadJson(JsonReader reader, Type objectType, Point existingValue, bool hasExistingValue, JsonSerializer serializer)
{
JObject jsonObject = JObject.Load(reader);
Point point = new Point();
foreach (var property in jsonObject.Properties())
{
string propertyName = property.Name;
JToken propertyValue = property.Value;
switch (propertyName)
{
case "title":
point.title = propertyValue.Value<string>();
break;
case "category":
point.category = propertyValue.Value<string>();
break;
case "created":
point.created = propertyValue.Value<long?>() != null ? new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(propertyValue.Value<long>().ToString()) : (DateTime?)null;
break;
case "version":
point.version = propertyValue.Value<int?>();
break;
default:
// Handle unknown properties if needed
break;
}
}
return point;
}
public override void WriteJson(JsonWriter writer, Point value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
public class Program
{
public static async Task Main()
{
RestClient client = new RestClient("your-api-url");
RestRequest request = new RestRequest("my-views");
// Add the custom converter to the JsonSerializer settings
JsonSerializerSettings jsonSettings = new JsonSerializerSettings();
jsonSettings.Converters.Add(new PointConverter());
// Get response from API with deserialized json-data to a Point object
var response = await client.ExecuteGetAsync<Point>(request);
// Access the properties as needed
string title = response.Data.title;
string category = response.Data.category;
DateTime? created = response.Data.created;
int? version = response.Data.version;
// Your desired properties are now available in the 'response' object
}
}
这段代码演示了如何使用自定义JSON转换器PointConverter
来反序列化JSON响应并将其转换为Point
对象。然后,您可以按需访问Point
对象的属性。请确保将Newtonsoft.Json
库添加到您的项目中。
英文:
I am working with the following JSON string from api response:
{
"points": [{
"name": "title",
"value": "Test"
}, {
"name": "category",
"value": null
}, {
"name": "created",
"value": 1550743894373
}, {
"name": "version",
"value": 1
}]
}
the json-structure of the response is always the same, root-node "points" has 1 or more name-value pairs.
I have a class structure as follows for parsing and filling the json data
// can't use record, have to use class, i only have .NET Framework 4.8 available
public class Point
{
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("value")]
public object Value { get; set; }
}
public class MyViews
{
[JsonPropertyName("points")]
public List<Point> Points { get; set; }
}
and this is my code:
using RestSharp;
// create request for API
var request = new RestRequest("my-views");
// get response from API with deserialized json-data to my Points-object
var response = await client.ExecuteGetAsync<MyViews>(request);
// just example of getting simple data from object
Point response_point = response.Data.Points.first(); // get first object
string title;
// check if object is a title
if (response_point.Name == "title") {
title = response_point.Value; // get value of title
}}
// my goal is:
// Point response_point = response.Data;
// title = response_point.title;
My deserialization goal is to fill data in the following class structure:
public class Point
{
public string title { get; set; }
public string category { get; set; }
public DateTime? created { get; set; }
public int? version { get; set; }
}
I want to have only one "Point" object with all name-value pairs as properties (without List in MyViews class).
Is there a way to transform the data on deserialization process, or trigger a method on Points-object after deserialization complete?
I'm using RestSharp-lib
with default serializer System.Text.Json
.
Thanks.
UPDATE: I'm not attached to any library, I have free choice, the only restriction I have to stick to is .NET 4.8 Framework.
答案1
得分: 1
Text.Json 和 Net 4.8 是有史以来最糟糕的组合。安装 Newtonsoft.Json,代码将更简单。
using Newtonsoft.Json;
var response = await client.ExecuteGetAsync(request);
var points = JObject.Parse(response.Content)["points"];
Point point = new Point();
foreach (var item in points)
{
var val = item["value"];
switch ((string)item["name"])
{
case "title": point.title = (string)val; break;
case "category": point.category = (string)val; break;
// case "created": point.created = (DateTime)val; break; //只有您知道日期的格式是什么
case "version": point.version = (int?)val; break;
}
}
英文:
Text.Json and Net 4.8 is the worst combination ever. Install Newtonsoft.Json and the code will be simpler.
using Newonsoft.Json;
var response = await client.ExecuteGetAsync(request);
var points = JObject.Parse(response.Content)["points"];
Point point = new Point();
foreach (var item in points)
{
var val = item["value"];
switch ((string)item["name"])
{
case "title": point.title = (string)val; break;
case "category": point.category = (string)val; break;
// case "created":point.created = (DateTime) val; break; //only you know what format is your date
case "version": point.version = (int?)val; break;
}
}
答案2
得分: -1
请使用数组而不是列表:
public class Point
{
public string title { get; set; }
public string category { get; set; }
public DateTime? created { get; set; }
public int? version { get; set; }
}
public class MyViews
{
[JsonPropertyName("points")]
public Point[] Points { get; set; } // <- an array of the Points
}
public class Program
{
public static void Main()
{
string json = @"
{
""points"": [
{
""name"": ""title"",
""value"": ""Test""
},
{
""name"": ""category"",
""value"": null
},
{
""name"": ""created"",
""value"": 1550743894373
},
{
""name"": ""version"",
""value"": 1
}
]
}";
MyViews myViews = new MyViews();
// --> 在此处我们将 JSON 反序列化为 Points 数组
myViews.Points = JsonSerializer.Deserialize<Point[]>(json);
Console.WriteLine("Deserialized Points:");
foreach (Point point in myViews.Points)
{
Console.WriteLine($"Title: {point.title}");
Console.WriteLine($"Category: {point.category}");
Console.WriteLine($"Created: {point.created}");
Console.WriteLine($"Version: {point.version}");
Console.WriteLine();
}
string serializedJson = JsonSerializer.Serialize(myViews);
Console.WriteLine("Serialized JSON:");
Console.WriteLine(serializedJson);
}
}
英文:
Use array instead of list:
public class Point
{
public string title { get; set; }
public string category { get; set; }
public DateTime? created { get; set; }
public int? version { get; set; }
}
public class MyViews
{
[JsonPropertyName("points")]
public Point[] Points { get; set; } // <- an array of the Points
}
public class Program
{
public static void Main()
{
string json = @"{
""points"": [
{
""name"": ""title"",
""value"": ""Test""
},
{
""name"": ""category"",
""value"": null
},
{
""name"": ""created"",
""value"": 1550743894373
},
{
""name"": ""version"",
""value"": 1
}
]
}";
MyViews myViews = new MyViews();
// --> Here we deserialize the json to an array of Points
myViews.Points = JsonSerializer.Deserialize<Point[]>(json);
Console.WriteLine("Deserialized Points:");
foreach (Point point in myViews.Points)
{
Console.WriteLine($"Title: {point.title}");
Console.WriteLine($"Category: {point.category}");
Console.WriteLine($"Created: {point.created}");
Console.WriteLine($"Version: {point.version}");
Console.WriteLine();
}
string serializedJson = JsonSerializer.Serialize(myViews);
Console.WriteLine("Serialized JSON:");
Console.WriteLine(serializedJson);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论