【发布时间】:2020-03-21 19:24:16
【问题描述】:
我不相信我正在思考如何正确使用 JsonConverter 来解析 json 结果的多态性。
在我的场景中,我的目标是 TFS 中的 Git 策略配置。策略配置:
"value": [
{
"createdBy": {
"displayName": "username",
"url": "url",
"id": "id",
"uniqueName": "user",
"imageUrl": "url"
},
"createdDate": "2020-03-21T18:17:24.3240783Z",
"isEnabled": true,
"isBlocking": true,
"isDeleted": false,
"settings": {
"minimumApproverCount": 1,
"creatorVoteCounts": false,
"allowDownvotes": false,
"resetOnSourcePush": true,
"scope": [{
"refName": "refs/heads/master",
"matchKind": "Exact",
"repositoryId": "id"
}
]
},
"_links": {
"self": {
"href": "url"
},
"policyType": {
"href": "url"
}
},
"revision": 1,
"id": 974,
"url": "url",
"type": {
"id": "id",
"url": "url",
"displayName": "Minimum number of reviewers"
},
{...}]
更多settings例子:
需要合并策略
"settings": {
"useSquashMerge": true,
"scope": [
{
"refName": "refs/heads/master",
"matchKind": "Exact",
"repositoryId": "id"
}
]
}
需要的审稿人
"settings": {
"requiredReviewerIds": [
"id"
],
"scope": [
{
"refName": "refs/heads/master",
"matchKind": "Exact",
"repositoryId": "id"
}
]
}
在上面的json sn-p中,settings对象根据配置的类型不同。
除了动态序列化/反序列化设置对象之外,编写转换器的最佳方法是什么?我已经阅读了几篇关于此的文章,但无法完全理解它。
这就是我目前反序列化所有 API 结果的方式,到目前为止,它们都是简单的结果集。
async Task<List<T>> ParseResults<T>( HttpResponseMessage result, string parameter )
{
List<T> results = new List<T>();
if ( result.IsSuccessStatusCode )
{
using var stream = await result.Content.ReadAsStreamAsync();
JsonDocument doc = JsonDocument.Parse( stream );
JsonElement collection = doc.RootElement.GetProperty( parameter ).Clone();
foreach ( var item in collection.EnumerateArray() )
{
results.Add( JsonSerializer.Deserialize<T>( item.ToString() ) );
}
}
return results;
}
我的集成测试。
PolicyConfiguration 是我要反序列化的类型。
[Test]
public async Task Get_TestMasterBranchPolicyConfigurations()
{
HttpResponseMessage result = await GetResult( $"{_collection}/ProductionBuildTesting/_apis/policy/configurations?api-version=4.1" );
List<PolicyConfiguration> configurations = await ParseResults<PolicyConfiguration>( result, "value" );
Assert.AreEqual( 16, configurations.Count );
JsonPrint( configurations );
}
我目前针对这种解析情况的课程
public class CreatedBy
{
[JsonPropertyName( "displayName" )]
public string DisplayName { get; set; }
[JsonPropertyName( "url" )]
public string Url { get; set; }
[JsonPropertyName( "id" )]
public Guid Id { get; set; }
[JsonPropertyName( "uniqueName" )]
public string UniqueName { get; set; }
[JsonPropertyName( "imageUrl" )]
public string ImageUrl { get; set; }
}
public class PolicyConfigurationScope
{
[JsonPropertyName( "refName" )]
public string RefName { get; set; }
[JsonPropertyName( "matchKind" )]
public string MatchKind { get; set; }
[JsonPropertyName( "repositoryId" )]
public Guid RepositoryId { get; set; }
}
public class PolicyConfigurationSettings_MinimumNumberOfReviewers
{
[JsonPropertyName( "minimumApproverCount" )]
public int MinimumApproverCount { get; set; }
[JsonPropertyName( "creatorVoteCounts" )]
public bool CreatorVoteCounts { get; set; }
[JsonPropertyName( "allowDownvotes" )]
public bool AllowDownvotes { get; set; }
[JsonPropertyName( "resetOnSourcePush" )]
public bool ResetOnSourcePush { get; set; }
[JsonPropertyName( "scope" )]
public List<PolicyConfigurationScope> Scope { get; set; }
}
public class PolicyConfigurationType
{
[JsonPropertyName( "id" )]
public Guid Id { get; set; }
[JsonPropertyName( "url" )]
public string Url { get; set; }
[JsonPropertyName( "displayName" )]
public string DisplayName { get; set; }
}
public class PolicyConfiguration
{
[JsonPropertyName( "createdBy" )]
public CreatedBy CreatedBy { get; set; }
[JsonPropertyName( "createdDate" )]
public DateTime CreatedDate { get; set; }
[JsonPropertyName( "isEnabled" )]
public bool IsEnabled { get; set; }
[JsonPropertyName( "isBlocking" )]
public bool IsBlocking { get; set; }
[JsonPropertyName( "isDeleted" )]
public bool IsDeleted { get; set; }
//[JsonPropertyName( "settings" )]
//public PolicyConfigurationSettings_MinimumNumberOfReviewersSettings Settings { get; set; }
[JsonPropertyName( "revision" )]
public int Revision { get; set; }
[JsonPropertyName( "id" )]
public int Id { get; set; }
[JsonPropertyName( "url" )]
public string Url { get; set; }
[JsonPropertyName( "type" )]
public PolicyConfigurationType Type { get; set; }
}
【问题讨论】:
-
settings是您的示例中的单个令牌,为什么要序列化为List<T>?您是否在解析scope值?你通过了哪个parameter,哪些typeparams被用作T? -
@PavelAnikhouski 这是我序列化整个 json 结果的方法。在这种情况下,结果是计数 4,父对象是
value类型的数组。settings是值的子对象,并且是动态的。如果有帮助,我可以发布我的对象类型吗?本质上这是一个PolicyConfiguration,属性是PolicyConfigurationSettings。 -
@PavelAnikhouski 我已经用用于反序列化的类更新了我的问题。设置被注释掉并且一切正常,当我为列出的设置插入类时,它会尝试将设置解析为每个配置的设置,从这里我不确定将转换器放在哪里。
-
--编辑:我相信我现在拥有原始问题中的所有内容来解决我当前的设置。
-
谢谢,现在问题更清楚了。您是否需要一个确切的类型进行反序列化,您是否考虑过使用键和值字典?
标签: c# .net-core-3.1 system.text.json