如何使用 System.Text.Json 将 JsonDocument 反序列化为 POCO
How to Deserialise JsonDocument To POCO Using System.Text.Json
使用 HttpClient 我 post 一个 json 文档到我的控制器。
public async Task<string> PostAsync<T>(string url, T doc)
{
var json = JsonConvert.SerializeObject(doc);
var response = await mHttp.PostAsync(url, new StringContent(json));
}
当我在这里检查控制器时:
public async Task<ActionResult> Post([FromBody] object doc,string fid)
对象文档具有以下格式:
ValueKind = Object : "{"id": "101zsdfgfgh","fid": "test1",......
}
如果类型未知,如何反序列化?
我可能是错的,但如果你使用一个参数,你就会坚持
System.Text.Json
所以我认为答案是不使用参数
public async Task<ActionResult> Post([FromBody] object doc,string fid)
改为
public async Task<ActionResult> Post(string fid)
然后像这样反序列化请求的内容。
string obj = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();
var doc = JsonConvert.DeserializeObject<dynamic>(obj);
然后你可以使用 JsonConvert 到 deserialize.Seems 很好地工作。
我想像这样从 JsonDocument 转换
dynamic obj=jsonDoc.ToObject();
所以我做了一个扩展方法。
这些属性最终是 JsonElements - 这对我来说很好,通常我需要做一个 ToString()。
所以这是我的代码(没有经过彻底测试,请注意...)
using System.Dynamic;
using System.Text.Json;
using System.Collections.Generic;
namespace MyJsonExtensions
{
public static class Extensions
{
public static object ToObject(this JsonDocument jsonDoc)
{
return Convert(jsonDoc.RootElement);
}
private static object Convert(JsonElement json)
{
if (json.ValueKind!=JsonValueKind.Array && json.ValueKind!=JsonValueKind.Object)
{
return json;
}
var serialized=JsonSerializer.Deserialize<ExpandoObject>(json.GetRawText());
var output=new ExpandoObject();
var outputDict=(IDictionary<string,object>)output;
foreach (var prop in (IDictionary<string,object>)serialized)
{
var propValue=(JsonElement)prop.Value;
switch (propValue.ValueKind)
{
case JsonValueKind.Array:
var list=new List<object>();
foreach (var item in propValue.EnumerateArray())
{
list.Add(Convert(item));
}
outputDict[prop.Key]=list.ToArray();
break;
case JsonValueKind.Object:
ExpandoObject val=new ExpandoObject();
var node=(IDictionary<string,object>)val;
foreach (var objElement in propValue.EnumerateObject())
{
var v=Convert(objElement.Value);
node.Add(objElement.Name,v);
}
outputDict[prop.Key]=val;
break;
default:
outputDict[prop.Key]=prop.Value;
break;
}
}
return output;
}
}
}
使用 HttpClient 我 post 一个 json 文档到我的控制器。
public async Task<string> PostAsync<T>(string url, T doc)
{
var json = JsonConvert.SerializeObject(doc);
var response = await mHttp.PostAsync(url, new StringContent(json));
}
当我在这里检查控制器时:
public async Task<ActionResult> Post([FromBody] object doc,string fid)
对象文档具有以下格式:
ValueKind = Object : "{"id": "101zsdfgfgh","fid": "test1",......
}
如果类型未知,如何反序列化?
我可能是错的,但如果你使用一个参数,你就会坚持
System.Text.Json
所以我认为答案是不使用参数
public async Task<ActionResult> Post([FromBody] object doc,string fid)
改为
public async Task<ActionResult> Post(string fid)
然后像这样反序列化请求的内容。
string obj = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();
var doc = JsonConvert.DeserializeObject<dynamic>(obj);
然后你可以使用 JsonConvert 到 deserialize.Seems 很好地工作。
我想像这样从 JsonDocument 转换
dynamic obj=jsonDoc.ToObject();
所以我做了一个扩展方法。 这些属性最终是 JsonElements - 这对我来说很好,通常我需要做一个 ToString()。
所以这是我的代码(没有经过彻底测试,请注意...)
using System.Dynamic;
using System.Text.Json;
using System.Collections.Generic;
namespace MyJsonExtensions
{
public static class Extensions
{
public static object ToObject(this JsonDocument jsonDoc)
{
return Convert(jsonDoc.RootElement);
}
private static object Convert(JsonElement json)
{
if (json.ValueKind!=JsonValueKind.Array && json.ValueKind!=JsonValueKind.Object)
{
return json;
}
var serialized=JsonSerializer.Deserialize<ExpandoObject>(json.GetRawText());
var output=new ExpandoObject();
var outputDict=(IDictionary<string,object>)output;
foreach (var prop in (IDictionary<string,object>)serialized)
{
var propValue=(JsonElement)prop.Value;
switch (propValue.ValueKind)
{
case JsonValueKind.Array:
var list=new List<object>();
foreach (var item in propValue.EnumerateArray())
{
list.Add(Convert(item));
}
outputDict[prop.Key]=list.ToArray();
break;
case JsonValueKind.Object:
ExpandoObject val=new ExpandoObject();
var node=(IDictionary<string,object>)val;
foreach (var objElement in propValue.EnumerateObject())
{
var v=Convert(objElement.Value);
node.Add(objElement.Name,v);
}
outputDict[prop.Key]=val;
break;
default:
outputDict[prop.Key]=prop.Value;
break;
}
}
return output;
}
}
}