C# 如何使用System.Text.json从一些json中读取简单值?
我有这个jsonC# 如何使用System.Text.json从一些json中读取简单值?,c#,.net-core,system.text.json,C#,.net Core,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
{"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 dict = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(json)
var dict=System.Text.Json.JsonSerializer.Deserialize(Json)
或者只是反序列化到对象
,这将产生一个可以调用的JsonElement
。我最近将一个项目从ASP.NET Core 2.2迁移到了3,这给我带来了不便。在我们的团队中,我们重视精益依赖,因此我们试图避免将Newtonsoft.JSON包含在后面,并尝试使用System.Text.JSON
。我们还决定不只是在JSON序列化中使用大量POCO对象,因为我们的后端模型比Web API所需的更复杂。此外,由于非平凡的行为封装,后端模型无法轻松用于序列化/反序列化JSON字符串
我知道System.Text.Json
应该比Newtonsoft.Json快,但我相信这与特定POCO类的ser/deser有很大关系。无论如何,速度不在我们这个决定的赞成/反对名单上,所以YMMV
长话短说,目前我编写了一个小型动态对象包装器,它从System.Text.Json中解包jsonement
s,并尽可能地转换/转换。典型的用法是将请求主体作为动态对象读取。同样,我非常肯定这种方法会扼杀任何速度提升,但这并不是我们的用例所关心的
这是一节课:
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控制器的基类中,该基类将主体作为动态对象公开:
[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
};
}
}
[ApiController]
公共类网络控制器数据库:控制器{
//其他材料-省略
受保护的异步任务JsonBody(){
var result=await JsonDocument.ParseAsync(Request.Body);
返回新的ReflectionDynamicObject{
RealObject=result.RootElement
};
}
}
并可在实际控制器中使用,如下所示:
//[...]
[HttpPost ("")]
public async Task<ActionResult> Post () {
var body = await JsonBody ();
var name = (string) body.Name;
//[...]
}
//[...]
/[…]
[HttpPost(“”)
公共异步任务发布(){
var body=await JsonBody();
变量名称=(字符串)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;
}
}
public static dynamic FromJson(此字符串为json,JsonSerializerOptions options=null)
{
if(string.IsNullOrEmpty(json))
返回null;
尝试
{
返回JsonSerializer.Deserialize(json,选项);
}
抓住
{
返回null;
}
}
在System.Text.Json(.NET Core 3+)中解析字符串的实际方法
您可以使用以下扩展方法查询“xpath”之类的数据
你能使用像NethOpthon的JSON这样的第三方库吗?不,我们放弃了NethtSoStor,因为它有多慢。我不认为我添加的是一个答案。<代码>字典<代码>也不是一个坏的选择。“或者只是反序列化到一个对象,它将产生一个JSONE元素,你可以调用它。你能给我举个例子吗?使用System.Text.Json;var json=JsonSerializer。反序列化(json)为JsonElement?;var tmp=json?.GetProperty(“id”)我认为您也可以这样做:var je_root=JsonSerializer.Deserialize(jsonstr);然后像这样访问它:int myvalue=je_root.GetProperty(“MyProperty”).GetProperty(“MySubProperty”).GetInt32()@Muflix-如果需要测试属性是否存在,可以反序列化到JsonElement,然后使用:JsonSerializer.Deserialize().TryGetProperty(“SomeProp”,out var元素)
JsonSerializer.Deserialize
不能帮助您从JsonValueKind中提取价值,升级.Net Core 3.1不会改变System.Text的行为。Json@Kuroro你是不对的,你可以很容易地将ExpandoObject转换为JsonElement,并获得所有对一级属性有效但对子级无效的东西。根据,当它超出范围时,需要将其强制转换为{System.Text.Json.JsonElement}JsonDocument
,以防止内存泄漏。当您需要在文档的生存期之外使用RootElement
时,必须使用它。
//[...]
[HttpPost ("")]
public async Task<ActionResult> Post () {
var body = await JsonBody ();
var name = (string) body.Name;
//[...]
}
//[...]
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;
}
}
var jsonStr = "{\"id\":\"48e86841-f62c-42c9-ae20-b54ba8c35d6d\"}";
using var doc = JsonDocument.Parse(jsonStr);
var root = doc.RootElement;
var id = root.GetProperty("id").GetGuid();
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"));