我对新发布的.NET Core 3.0及其新的System.Text.Json
有疑问,我想问一下新的JsonDocument
是否可以类似于Newtonsoft中的ContractResolver
类使用。 JSON.NET。
我需要的很简单,假设一个类具有两个属性
public string Name {get; set;} public string Street {get; set;}
,我需要将两个不同的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":"1st avenue","city":"Washington","state":"US"}, "woman_B":{"fullname":"McCarter","street":"Green street","city":"London","state":"GB"}}
我需要将属性full-name
,fullname
反序列化为Name
和address-street
,street
反序列化为Street
。不需要其他JSON字段。
要反序列化具有不同属性名称的多个JSON,我在JSON.NET中使用了ContractResolver
,效果很好。
我研究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>