你如何使用 System.Text.Json 从一些 json 中读取一个简单的值?
How do you read a simple value out of some json using System.Text.Json?
我有这个json
{"id":"48e86841-f62c-42c9-ae20-b54ba8c35d6d"}
如何从中取出 48e86841-f62c-42c9-ae20-b54ba8c35d6d
?我能找到的所有例子都表明可以做类似
的事情
var o = System.Text.Json.JsonSerializer.Deserialize<some-type>(json);
o.id // <- here's the ID!
但是我没有符合这个定义的类型,我不想创建一个。我试过反序列化为动态,但无法正常工作。
var result = System.Text.Json.JsonSerializer.Deserialize<dynamic>(json);
result.id // <-- An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Linq.Expressions.dll but was not handled in user code: ''System.Text.Json.JsonElement' does not contain a definition for 'id''
谁能给点建议?
编辑:
我刚刚发现我可以做到这一点:
Guid id = System.Text.Json.JsonDocument.Parse(json).RootElement.GetProperty("id").GetGuid();
这确实有效 - 但有更好的方法吗?
你可以反序列化为 Dictionary
:
var dict = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(json)
或者只是反序列化为 Object
,这将产生一个 JsonElement
,您可以在 GetProperty
上调用它。
我最近将一个项目从 ASP.NET Core 2.2 迁移到 3,但遇到了一些不便。在我们的团队中,我们重视精益依赖,因此我们试图避免包括 Newtonsoft.JSON 并尝试使用 System.Text.Json
。我们还决定不只为 JSON 序列化使用大量 POCO 对象,因为我们的后端模型比 Web API 所需的更复杂。此外,由于非平凡的行为封装,后端模型不能轻易用于 serialize/deserialize JSON 字符串。
我理解 System.Text.Json
应该比 Newtonsoft.JSON 快,但我相信这与 ser/deser from/to 特定的 POCO [=39] 有很大关系=]是的。无论如何,速度不在我们的 pros/cons 列表中,所以 YMMV。
长话短说,目前我写了一个小的动态对象包装器,它从 System.Text.Json 中解压缩 JsonElement
并尽可能地尝试 convert/cast。典型的用法是将请求主体作为动态对象读取。同样,我很确定这种方法会扼杀任何速度提升,但这对我们的用例来说不是问题。
这是class:
public class ReflectionDynamicObject : DynamicObject {
public JsonElement RealObject { get; set; }
public override bool TryGetMember (GetMemberBinder binder, out object result) {
// Get the property value
var srcData = RealObject.GetProperty (binder.Name);
result = null;
switch (srcData.ValueKind) {
case JsonValueKind.Null:
result = null;
break;
case JsonValueKind.Number:
result = srcData.GetDouble ();
break;
case JsonValueKind.False:
result = false;
break;
case JsonValueKind.True:
result = true;
break;
case JsonValueKind.Undefined:
result = null;
break;
case JsonValueKind.String:
result = srcData.GetString ();
break;
case JsonValueKind.Object:
result = new ReflectionDynamicObject {
RealObject = srcData
};
break;
case JsonValueKind.Array:
result = srcData.EnumerateArray ()
.Select (o => new ReflectionDynamicObject { RealObject = o })
.ToArray ();
break;
}
// Always return true; other exceptions may have already been thrown if needed
return true;
}
}
这是一个示例用法,用于解析请求正文 - 一部分位于我所有 WebAPI 控制器的基础 class 中,它将正文公开为动态对象:
[ApiController]
public class WebControllerBase : Controller {
// Other stuff - omitted
protected async Task<dynamic> JsonBody () {
var result = await JsonDocument.ParseAsync (Request.Body);
return new ReflectionDynamicObject {
RealObject = result.RootElement
};
}
}
在实际控制器中可以这样使用:
//[...]
[HttpPost ("")]
public async Task<ActionResult> Post () {
var body = await JsonBody ();
var name = (string) body.Name;
//[...]
}
//[...]
如果需要,您可以根据需要集成对 GUID 或其他特定数据类型的解析 - 而我们都在等待一些官方/框架认可的解决方案。
更新到 .NET Core 3.1 以支持
public static dynamic FromJson(this string json, JsonSerializerOptions options = null)
{
if (string.IsNullOrEmpty(json))
return null;
try
{
return JsonSerializer.Deserialize<ExpandoObject>(json, options);
}
catch
{
return null;
}
}
在 System.Text.Json (.NET Core 3+)
中解析字符串的实际方法
var jsonStr = "{\"id\":\"48e86841-f62c-42c9-ae20-b54ba8c35d6d\"}";
using var doc = JsonDocument.Parse(jsonStr);
var root = doc.RootElement;
var id = root.GetProperty("id").GetGuid();
您可以使用以下扩展方法来查询类似“xpath”的数据
public static string? JsonQueryXPath(this string value, string xpath, JsonSerializerOptions? options = null) => value.Deserialize<JsonElement>(options).GetJsonElement(xpath).GetJsonElementValue();
public static JsonElement GetJsonElement(this JsonElement jsonElement, string xpath)
{
if (jsonElement.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
return default;
string[] segments = xpath.Split(new[] {'.'}, StringSplitOptions.RemoveEmptyEntries);
foreach (var segment in segments)
{
if (int.TryParse(segment, out var index) && jsonElement.ValueKind == JsonValueKind.Array)
{
jsonElement = jsonElement.EnumerateArray().ElementAtOrDefault(index);
if (jsonElement.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
return default;
continue;
}
jsonElement = jsonElement.TryGetProperty(segment, out var value) ? value : default;
if (jsonElement.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
return default;
}
return jsonElement;
}
public static string? GetJsonElementValue(this JsonElement jsonElement) => jsonElement.ValueKind != JsonValueKind.Null &&
jsonElement.ValueKind != JsonValueKind.Undefined
? jsonElement.ToString()
: default;
简单使用如下
string raw = @"{
""data"": {
""products"": {
""edges"": [
{
""node"": {
""id"": ""gid://shopify/Product/4534543543316"",
""featuredImage"": {
""originalSrc"": ""https://cdn.shopify.com/s/files/1/0286/pic.jpg"",
""id"": ""gid://shopify/ProductImage/146345345339732""
}
}
},
{
""node"": {
""id"": ""gid://shopify/Product/123456789"",
""featuredImage"": {
""originalSrc"": ""https://cdn.shopify.com/s/files/1/0286/pic.jpg"",
""id"": [
""gid://shopify/ProductImage/123456789"",
""gid://shopify/ProductImage/666666666""
]
},
""1"": {
""name"": ""Tuanh""
}
}
}
]
}
}
}";
System.Console.WriteLine(raw2.QueryJsonXPath("data.products.edges.0.node.featuredImage.id"));
已使用 System.Text.Json.Nodes
在 .NET 6
中添加对 JsonObject
的支持。
示例:
const string Json = "{\"MyNumber\":42, \"MyArray\":[10,11]}";
// dynamic
{
dynamic obj = JsonNode.Parse(Json);
int number = (int)obj["MyNumber"];
Debug.Assert(number == 42);
obj["MyString"] = "Hello";
Debug.Assert((string)obj["MyString"] == "Hello");
}
// JsonObject
{
JsonObject obj = JsonNode.Parse(Json).AsObject();
int number = (int)obj["MyNumber"];
Debug.Assert(number == 42);
obj["MyString"] = "Hello";
Debug.Assert((string)obj["MyString"] == "Hello");
}
来源:
您还可以将 json 反序列化为目标 class 的对象,然后按正常方式读取其属性:
var obj = DeSerializeFromStrToObj<ClassToSerialize>(jsonStr);
Console.WriteLine($"Property: {obj.Property}");
其中 DeSerializeFromStrToObj
是自定义 class,它利用反射来实例化目标 class 的对象:
public static T DeSerializeFromStrToObj<T>(string json)
{
try
{
var o = (T)Activator.CreateInstance(typeof(T));
try
{
var jsonDict = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
var props = o.GetType().GetProperties();
if (props == null || props.Length == 0)
{
Debug.WriteLine($"Error: properties from target class '{typeof(T)}' could not be read using reflection");
return default;
}
if (jsonDict.Count != props.Length)
{
Debug.WriteLine($"Error: number of json lines ({jsonDict.Count}) should be the same as number of properties ({props.Length})of our class '{typeof(T)}'");
return default;
}
foreach (var prop in props)
{
if (prop == null)
{
Debug.WriteLine($"Error: there was a prop='null' in our target class '{typeof(T)}'");
return default;
}
if (!jsonDict.ContainsKey(prop.Name))
{
Debug.WriteLine($"Error: jsonStr does not refer to target class '{typeof(T)}'");
return default;
}
var value = jsonDict[prop.Name];
Type t = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
object safeValue = value ?? Convert.ChangeType(value, t);
prop.SetValue(o, safeValue, null); // initialize property
}
return o;
}
catch (Exception e2)
{
Debug.WriteLine(e2.Message);
return o;
}
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
return default;
}
}
您可以测试您的 json,例如 here
在这里您可以找到一个完整的工作示例,其中包含您可能感兴趣的不同序列化和反序列化方式and/or未来的读者:
using System;
using System.Collections.Generic;
using System.Text.Json;
using static Json_Tests.JsonHelpers;
namespace Json_Tests
{
public class Class1
{
public void Test()
{
var obj1 = new ClassToSerialize();
var jsonStr = obj1.ToString();
// if you have the class structure for the jsonStr (for example, if you have created the jsonStr yourself from your code):
var obj2 = DeSerializeFromStrToObj<ClassToSerialize>(jsonStr);
Console.WriteLine($"{nameof(obj2.Name)}: {obj2.Name}");
// if you do not have the class structure for the jsonStr (forexample, jsonStr comes from a 3rd party service like the web):
var obj3 = JsonSerializer.Deserialize<object>(jsonStr) as JsonElement?;
var propName = nameof(obj1.Name);
var propVal1 = obj3?.GetProperty("Name");// error prone
Console.WriteLine($"{propName}: {propVal1}");
JsonElement propVal2 = default;
obj3?.TryGetProperty("Name", out propVal2);// error prone
Console.WriteLine($"{propName}: {propVal2}");
var obj4 = DeSerializeFromStrToDict(jsonStr);
foreach (var pair in obj4)
Console.WriteLine($"{pair.Key}: {pair.Value}");
}
}
[Serializable]
public class ClassToSerialize
{
// important: properties must have at least getters
public string Name { get; } = "Paul";
public string Surname{ get; set; } = "Efford";
public override string ToString() => JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true });
}
public static class JsonHelpers
{
/// <summary>
/// to use if you do not have the class structure for the jsonStr (forexample, jsonStr comes from a 3rd party service like the web)
/// </summary>
public static Dictionary<string, string> DeSerializeFromStrToDict(string json)
{
try
{
return JsonSerializer.Deserialize<Dictionary<string, string>>(json);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return new Dictionary<string, string>(); // return empty
}
}
/// <summary>
/// to use if you have the class structure for the jsonStr (for example, if you have created the jsonStr yourself from your code)
/// </summary>
public static T DeSerializeFromStrToObj<T>(string json) // see this: https://json2csharp.com/#
{
try
{
var o = (T)Activator.CreateInstance(typeof(T));
try
{
var jsonDict = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
var props = o.GetType().GetProperties();
if (props == null || props.Length == 0)
{
Console.WriteLine($"Error: properties from target class '{typeof(T)}' could not be read using reflection");
return default;
}
if (jsonDict.Count != props.Length)
{
Console.WriteLine($"Error: number of json lines ({jsonDict.Count}) should be the same as number of properties ({props.Length})of our class '{typeof(T)}'");
return default;
}
foreach (var prop in props)
{
if (prop == null)
{
Console.WriteLine($"Error: there was a prop='null' in our target class '{typeof(T)}'");
return default;
}
if (!jsonDict.ContainsKey(prop.Name))
{
Console.WriteLine($"Error: jsonStr does not refer to target class '{typeof(T)}'");
return default;
}
var value = jsonDict[prop.Name];
Type t = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
object safeValue = value ?? Convert.ChangeType(value, t);
prop.SetValue(o, safeValue, null); // initialize property
}
return o;
}
catch (Exception e2)
{
Console.WriteLine(e2.Message);
return o;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return default;
}
}
}
}
我有这个json
{"id":"48e86841-f62c-42c9-ae20-b54ba8c35d6d"}
如何从中取出 48e86841-f62c-42c9-ae20-b54ba8c35d6d
?我能找到的所有例子都表明可以做类似
var o = System.Text.Json.JsonSerializer.Deserialize<some-type>(json);
o.id // <- here's the ID!
但是我没有符合这个定义的类型,我不想创建一个。我试过反序列化为动态,但无法正常工作。
var result = System.Text.Json.JsonSerializer.Deserialize<dynamic>(json);
result.id // <-- An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Linq.Expressions.dll but was not handled in user code: ''System.Text.Json.JsonElement' does not contain a definition for 'id''
谁能给点建议?
编辑:
我刚刚发现我可以做到这一点:
Guid id = System.Text.Json.JsonDocument.Parse(json).RootElement.GetProperty("id").GetGuid();
这确实有效 - 但有更好的方法吗?
你可以反序列化为 Dictionary
:
var dict = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(json)
或者只是反序列化为 Object
,这将产生一个 JsonElement
,您可以在 GetProperty
上调用它。
我最近将一个项目从 ASP.NET Core 2.2 迁移到 3,但遇到了一些不便。在我们的团队中,我们重视精益依赖,因此我们试图避免包括 Newtonsoft.JSON 并尝试使用 System.Text.Json
。我们还决定不只为 JSON 序列化使用大量 POCO 对象,因为我们的后端模型比 Web API 所需的更复杂。此外,由于非平凡的行为封装,后端模型不能轻易用于 serialize/deserialize JSON 字符串。
我理解 System.Text.Json
应该比 Newtonsoft.JSON 快,但我相信这与 ser/deser from/to 特定的 POCO [=39] 有很大关系=]是的。无论如何,速度不在我们的 pros/cons 列表中,所以 YMMV。
长话短说,目前我写了一个小的动态对象包装器,它从 System.Text.Json 中解压缩 JsonElement
并尽可能地尝试 convert/cast。典型的用法是将请求主体作为动态对象读取。同样,我很确定这种方法会扼杀任何速度提升,但这对我们的用例来说不是问题。
这是class:
public class ReflectionDynamicObject : DynamicObject {
public JsonElement RealObject { get; set; }
public override bool TryGetMember (GetMemberBinder binder, out object result) {
// Get the property value
var srcData = RealObject.GetProperty (binder.Name);
result = null;
switch (srcData.ValueKind) {
case JsonValueKind.Null:
result = null;
break;
case JsonValueKind.Number:
result = srcData.GetDouble ();
break;
case JsonValueKind.False:
result = false;
break;
case JsonValueKind.True:
result = true;
break;
case JsonValueKind.Undefined:
result = null;
break;
case JsonValueKind.String:
result = srcData.GetString ();
break;
case JsonValueKind.Object:
result = new ReflectionDynamicObject {
RealObject = srcData
};
break;
case JsonValueKind.Array:
result = srcData.EnumerateArray ()
.Select (o => new ReflectionDynamicObject { RealObject = o })
.ToArray ();
break;
}
// Always return true; other exceptions may have already been thrown if needed
return true;
}
}
这是一个示例用法,用于解析请求正文 - 一部分位于我所有 WebAPI 控制器的基础 class 中,它将正文公开为动态对象:
[ApiController]
public class WebControllerBase : Controller {
// Other stuff - omitted
protected async Task<dynamic> JsonBody () {
var result = await JsonDocument.ParseAsync (Request.Body);
return new ReflectionDynamicObject {
RealObject = result.RootElement
};
}
}
在实际控制器中可以这样使用:
//[...]
[HttpPost ("")]
public async Task<ActionResult> Post () {
var body = await JsonBody ();
var name = (string) body.Name;
//[...]
}
//[...]
如果需要,您可以根据需要集成对 GUID 或其他特定数据类型的解析 - 而我们都在等待一些官方/框架认可的解决方案。
更新到 .NET Core 3.1 以支持
public static dynamic FromJson(this string json, JsonSerializerOptions options = null)
{
if (string.IsNullOrEmpty(json))
return null;
try
{
return JsonSerializer.Deserialize<ExpandoObject>(json, options);
}
catch
{
return null;
}
}
在 System.Text.Json (.NET Core 3+)
中解析字符串的实际方法 var jsonStr = "{\"id\":\"48e86841-f62c-42c9-ae20-b54ba8c35d6d\"}";
using var doc = JsonDocument.Parse(jsonStr);
var root = doc.RootElement;
var id = root.GetProperty("id").GetGuid();
您可以使用以下扩展方法来查询类似“xpath”的数据
public static string? JsonQueryXPath(this string value, string xpath, JsonSerializerOptions? options = null) => value.Deserialize<JsonElement>(options).GetJsonElement(xpath).GetJsonElementValue();
public static JsonElement GetJsonElement(this JsonElement jsonElement, string xpath)
{
if (jsonElement.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
return default;
string[] segments = xpath.Split(new[] {'.'}, StringSplitOptions.RemoveEmptyEntries);
foreach (var segment in segments)
{
if (int.TryParse(segment, out var index) && jsonElement.ValueKind == JsonValueKind.Array)
{
jsonElement = jsonElement.EnumerateArray().ElementAtOrDefault(index);
if (jsonElement.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
return default;
continue;
}
jsonElement = jsonElement.TryGetProperty(segment, out var value) ? value : default;
if (jsonElement.ValueKind is JsonValueKind.Null or JsonValueKind.Undefined)
return default;
}
return jsonElement;
}
public static string? GetJsonElementValue(this JsonElement jsonElement) => jsonElement.ValueKind != JsonValueKind.Null &&
jsonElement.ValueKind != JsonValueKind.Undefined
? jsonElement.ToString()
: default;
简单使用如下
string raw = @"{
""data"": {
""products"": {
""edges"": [
{
""node"": {
""id"": ""gid://shopify/Product/4534543543316"",
""featuredImage"": {
""originalSrc"": ""https://cdn.shopify.com/s/files/1/0286/pic.jpg"",
""id"": ""gid://shopify/ProductImage/146345345339732""
}
}
},
{
""node"": {
""id"": ""gid://shopify/Product/123456789"",
""featuredImage"": {
""originalSrc"": ""https://cdn.shopify.com/s/files/1/0286/pic.jpg"",
""id"": [
""gid://shopify/ProductImage/123456789"",
""gid://shopify/ProductImage/666666666""
]
},
""1"": {
""name"": ""Tuanh""
}
}
}
]
}
}
}";
System.Console.WriteLine(raw2.QueryJsonXPath("data.products.edges.0.node.featuredImage.id"));
已使用 System.Text.Json.Nodes
在 .NET 6
中添加对 JsonObject
的支持。
示例:
const string Json = "{\"MyNumber\":42, \"MyArray\":[10,11]}";
// dynamic
{
dynamic obj = JsonNode.Parse(Json);
int number = (int)obj["MyNumber"];
Debug.Assert(number == 42);
obj["MyString"] = "Hello";
Debug.Assert((string)obj["MyString"] == "Hello");
}
// JsonObject
{
JsonObject obj = JsonNode.Parse(Json).AsObject();
int number = (int)obj["MyNumber"];
Debug.Assert(number == 42);
obj["MyString"] = "Hello";
Debug.Assert((string)obj["MyString"] == "Hello");
}
来源:
您还可以将 json 反序列化为目标 class 的对象,然后按正常方式读取其属性:
var obj = DeSerializeFromStrToObj<ClassToSerialize>(jsonStr);
Console.WriteLine($"Property: {obj.Property}");
其中 DeSerializeFromStrToObj
是自定义 class,它利用反射来实例化目标 class 的对象:
public static T DeSerializeFromStrToObj<T>(string json)
{
try
{
var o = (T)Activator.CreateInstance(typeof(T));
try
{
var jsonDict = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
var props = o.GetType().GetProperties();
if (props == null || props.Length == 0)
{
Debug.WriteLine($"Error: properties from target class '{typeof(T)}' could not be read using reflection");
return default;
}
if (jsonDict.Count != props.Length)
{
Debug.WriteLine($"Error: number of json lines ({jsonDict.Count}) should be the same as number of properties ({props.Length})of our class '{typeof(T)}'");
return default;
}
foreach (var prop in props)
{
if (prop == null)
{
Debug.WriteLine($"Error: there was a prop='null' in our target class '{typeof(T)}'");
return default;
}
if (!jsonDict.ContainsKey(prop.Name))
{
Debug.WriteLine($"Error: jsonStr does not refer to target class '{typeof(T)}'");
return default;
}
var value = jsonDict[prop.Name];
Type t = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
object safeValue = value ?? Convert.ChangeType(value, t);
prop.SetValue(o, safeValue, null); // initialize property
}
return o;
}
catch (Exception e2)
{
Debug.WriteLine(e2.Message);
return o;
}
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
return default;
}
}
您可以测试您的 json,例如 here
在这里您可以找到一个完整的工作示例,其中包含您可能感兴趣的不同序列化和反序列化方式and/or未来的读者:
using System;
using System.Collections.Generic;
using System.Text.Json;
using static Json_Tests.JsonHelpers;
namespace Json_Tests
{
public class Class1
{
public void Test()
{
var obj1 = new ClassToSerialize();
var jsonStr = obj1.ToString();
// if you have the class structure for the jsonStr (for example, if you have created the jsonStr yourself from your code):
var obj2 = DeSerializeFromStrToObj<ClassToSerialize>(jsonStr);
Console.WriteLine($"{nameof(obj2.Name)}: {obj2.Name}");
// if you do not have the class structure for the jsonStr (forexample, jsonStr comes from a 3rd party service like the web):
var obj3 = JsonSerializer.Deserialize<object>(jsonStr) as JsonElement?;
var propName = nameof(obj1.Name);
var propVal1 = obj3?.GetProperty("Name");// error prone
Console.WriteLine($"{propName}: {propVal1}");
JsonElement propVal2 = default;
obj3?.TryGetProperty("Name", out propVal2);// error prone
Console.WriteLine($"{propName}: {propVal2}");
var obj4 = DeSerializeFromStrToDict(jsonStr);
foreach (var pair in obj4)
Console.WriteLine($"{pair.Key}: {pair.Value}");
}
}
[Serializable]
public class ClassToSerialize
{
// important: properties must have at least getters
public string Name { get; } = "Paul";
public string Surname{ get; set; } = "Efford";
public override string ToString() => JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true });
}
public static class JsonHelpers
{
/// <summary>
/// to use if you do not have the class structure for the jsonStr (forexample, jsonStr comes from a 3rd party service like the web)
/// </summary>
public static Dictionary<string, string> DeSerializeFromStrToDict(string json)
{
try
{
return JsonSerializer.Deserialize<Dictionary<string, string>>(json);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return new Dictionary<string, string>(); // return empty
}
}
/// <summary>
/// to use if you have the class structure for the jsonStr (for example, if you have created the jsonStr yourself from your code)
/// </summary>
public static T DeSerializeFromStrToObj<T>(string json) // see this: https://json2csharp.com/#
{
try
{
var o = (T)Activator.CreateInstance(typeof(T));
try
{
var jsonDict = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
var props = o.GetType().GetProperties();
if (props == null || props.Length == 0)
{
Console.WriteLine($"Error: properties from target class '{typeof(T)}' could not be read using reflection");
return default;
}
if (jsonDict.Count != props.Length)
{
Console.WriteLine($"Error: number of json lines ({jsonDict.Count}) should be the same as number of properties ({props.Length})of our class '{typeof(T)}'");
return default;
}
foreach (var prop in props)
{
if (prop == null)
{
Console.WriteLine($"Error: there was a prop='null' in our target class '{typeof(T)}'");
return default;
}
if (!jsonDict.ContainsKey(prop.Name))
{
Console.WriteLine($"Error: jsonStr does not refer to target class '{typeof(T)}'");
return default;
}
var value = jsonDict[prop.Name];
Type t = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
object safeValue = value ?? Convert.ChangeType(value, t);
prop.SetValue(o, safeValue, null); // initialize property
}
return o;
}
catch (Exception e2)
{
Console.WriteLine(e2.Message);
return o;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return default;
}
}
}
}