我对新发布的 .NET Core 3.0 及其新版本有疑问System.Text.Json
,我想问一下新版本JsonDocument
是否可以ContractResolver
与 Newtonsoft JSON.NET 中的类类似地使用。
我需要的很简单,假设一个类有两个属性
公共字符串名称 {get; 放;} 公共字符串 Street {get; 放;}
我需要将两个不同的 JSON 反序列化到这个类中。
JSON 1:
{"person_A":{"full-name":"Micheal","address-street":"1st avenue","address-city":"New York"}, "person_B":{"full-name":"John","address-street":"Green street","address-city":"London"}}
JSON 2:
{"man_A":{"fullname":"Bush","street":"第一大道","city":"Washington","state":"US"}, "woman_B":{"fullname":"McCarter","street":"Green street","city":"London","state":"GB"}}
我需要反序列full-name
化属性fullname
asName
和as address-street
。不需要其他 JSON 字段。street
Street
为了反序列化具有不同属性名称的多个 JSON,我ContractResolver
在 JSON.NET 中使用了一个,它工作得很好。
我正在研究的原因JsonDocument
是我只反序列化了几个 JSON 属性,并且使用当前的方法我必须缓存整个 JSON。如果我理解正确,JsonDocument
应该允许我只访问我需要的属性。
谢谢!
编辑
为了澄清我在这里要问的问题 - 想法是获取有关 Json 对象的信息但不完全加载它,因为它不需要,这就是为什么我想使用新的 JsonDocument,只选择那些我需要并加载这些。由于 Json 属性名称与我的类属性不同,并且我有多个 Json 试图反序列化到同一个类中,因此我需要 IContractResolver 之类的东西来将类属性与 Json 中的名称匹配。
我能够做出这样的事情,但我承认它不是很漂亮。
private readonly Dictionary propertyMappings = new Dictionary();
private void AddMap<U>(Expression<Func<Instrument,U>> expression, string jsonPropertyName)
{
var memberExpression = (MemberExpression)expression.Body;
propertyMappings.Add(memberExpression.Member.Name, jsonPropertyName);
}
public override async Task<List<Person>> GetPeopleAsync(HttpRequestMessage request)
{
AddMap(x => x.Name, "full-name");
AddMap(x => x.Street, "address-street");
var result = new List<Person>();
var response = await SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
var stream = await response.Content.ReadAsStreamAsync();
var document = await JsonDocument.ParseAsync(stream);
document.RootElement.GetProperty("people").EnumerateObject()
.ToList()
.ForEach(x =>
{
var person= new Person();
foreach (var p in propertyMappings)
{
x.Value.TryGetProperty(p.Value, out var prop);
var v = person.GetType().GetProperty(p.Key);
v.SetValue(person,Convert.ChangeType(prop.ToString(),v.PropertyType));
}
result.Add(person);
});
return result;
}</code>