Nic*_*ick 39 c# .net-core system.text.json
我有这个 json
{"id":"48e86841-f62c-42c9-ae20-b54ba8c35d6d"}
Run Code Online (Sandbox Code Playgroud)
我如何48e86841-f62c-42c9-ae20-b54ba8c35d6d摆脱它?我能找到的所有例子都显示做类似的事情
var o = System.Text.Json.JsonSerializer.Deserialize<some-type>(json);
o.id // <- here's the ID!
Run Code Online (Sandbox Code Playgroud)
但是我没有符合这个定义的类型,我不想创建一个。我试过反序列化为动态,但我无法让它工作。
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''
Run Code Online (Sandbox Code Playgroud)
任何人都可以提供任何建议吗?
编辑:
我刚刚发现我可以这样做:
Guid id = System.Text.Json.JsonDocument.Parse(json).RootElement.GetProperty("id").GetGuid();
Run Code Online (Sandbox Code Playgroud)
这确实有效 - 但有更好的方法吗?
小智 32
您可以反序列化为Dictionary:
var dict = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(json)
Run Code Online (Sandbox Code Playgroud)
或者只是反序列化到Object哪个会产生一个JsonElement你可以调用GetProperty的。
Ogg*_*las 30
使用JsonObject中添加了对 的支持。.NET 6System.Text.Json.Nodes
例子:
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");
}
Run Code Online (Sandbox Code Playgroud)
资料来源:
https://github.com/dotnet/runtime/issues/53195
https://github.com/dotnet/runtime/issues/45188
Ale*_*iol 14
我最近将一个项目从 ASP.NET Core 2.2 迁移到 3,我遇到了这种不便。在我们的团队中,我们重视精益依赖,因此我们试图避免包含 Newtonsoft.JSON 并尝试使用System.Text.Json. 我们还决定不将大量 POCO 对象仅用于 JSON 序列化,因为我们的后端模型比 Web API 所需的更复杂。此外,由于非平凡的行为封装,后端模型不能轻松用于序列化/反序列化 JSON 字符串。
我知道这System.Text.Json应该比 Newtonsoft.JSON 更快,但我相信这与从/到特定 POCO 类的 ser/deser 有很大关系。无论如何,速度不在我们这个决定的利弊列表中,所以 YMMV。
长话短说,暂时我写了一个小的动态对象包装器,它JsonElement从 System.Text.Json解包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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个示例用法,用于解析请求正文 - 一部分位于我所有 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
};
}
}
Run Code Online (Sandbox Code Playgroud)
并且可以像这样在实际控制器中使用:
//[...]
[HttpPost ("")]
public async Task<ActionResult> Post () {
var body = await JsonBody ();
var name = (string) body.Name;
//[...]
}
//[...]
Run Code Online (Sandbox Code Playgroud)
如果需要,您可以根据需要集成对 GUID 或其他特定数据类型的解析 - 而我们都在等待一些官方/框架认可的解决方案。
解析 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();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
26172 次 |
| 最近记录: |