在JSON数组中使用特定数据的服务堆栈响应DTO
本文关键字:数据 服务 堆栈 DTO 响应 数组 JSON | 更新日期: 2023-09-27 18:09:46
我正在为返回JSON数据的服务建模我的响应dto:
{
"response":
{
"metadataA" : "useless info a",
"metadataB" : "useless info b",
"metadataC" : "useless info c",
...
"metadataZ" : "useless info z",
"results" :
[
{
"resultmetadataA" : "useless info a",
"resultmetadataB" : "useless info b",
"resultId": "a",
"resultName": "A"
},
{
"resultmetadataA" : "useless info a",
"resultmetadataB" : "useless info b",
"resultId": "b",
"resultName": "B"
}
]
}
}
显然,我只想让我的DTO有一个带有id和名称的结果列表,就像这样:
class Response
{
public List<Result> Results { get; set; }
}
class Result
{
public string Id { get; set; }
public string Name { get; set; }
}
是否有一些属性属性来告诉服务堆栈id和name值的"路径"?
编辑1
我试图使用一些属性从ServiceStack。没有运气的数据注释。尝试使用CompositeIndex(false, "response", "results")在Results
和Alias在Results
属性,但结果一直为null。
请帮助!
编辑2
也尝试了[DataContract]
在响应和[DataMember(Name = Id/Name)]
上的属性来解析这些数据直接,但它似乎不起作用。
你可以使用字典:
public class ResponseDTO
{
public List<Dictionary<string, string>> Results { get; set; }
}
首先您的JSON是无效的"response": [
不能是数组文字,但包含对象属性。
如何调试序列化问题
我们的目标是让模式匹配JSON的形状。不要试图猜测形状应该是什么,要养成推断形状的习惯,尝试看看哪些属性被序列化。如果没有属性被序列化,做相反的填充和序列化你的poco,看看他们是什么形状的期望,然后比较形状与原始JSON,看看他们的不同之处。有关调试序列化问题的其他提示,请参阅此回答。
var json = @"{
""response"":
{
""metadataA"" : ""useless info a"",
""metadataB"" : ""useless info b"",
""metadataC"" : ""useless info c"",
""metadataZ"" : ""useless info z"",
""results"" :
[
{
""resultmetadataA"" : ""useless info a"",
""resultmetadataB"" : ""useless info b"",
""resultId"": ""a"",
""resultName"": ""A""
},
{
""resultmetadataA"" : ""useless info a"",
""resultmetadataB"" : ""useless info b"",
""resultId"": ""b"",
""resultName"": ""B""
}
]
}
}";
从上述JSON中推断出的类型:
public class MetadataResponse
{
public Response Response { get; set; }
}
public class Response
{
public string MetadataA { get; set; }
public string MetadataB { get; set; }
public string MetadataC { get; set; }
public string MetadataZ { get; set; }
public List<Result> Results { get; set; }
}
public class Result
{
public string ResultmetadataA { get; set; }
public string ResultmetadataB { get; set; }
public string ResultId { get; set; }
public string ResultName { get; set; }
}
使用上述类型测试JSON序列化:
var dto = json.FromJson<MetadataResponse>();
dto.PrintDump();
输出:{
Response:
{
MetadataA: useless info a,
MetadataB: useless info b,
MetadataC: useless info c,
MetadataZ: useless info z,
Results:
[
{
ResultmetadataA: useless info a,
ResultmetadataB: useless info b,
ResultId: a,
ResultName: A
},
{
ResultmetadataA: useless info a,
ResultmetadataB: useless info b,
ResultId: b,
ResultName: B
}
]
}
}
毕竟我没有办法为复杂的响应建立简单的dto模型,无论如何,感谢所有的答案。
很遗憾,我的POCO结构依赖于JSON响应结构。但是,我可以抽象响应结构,并让所有的dto同时处理它。
考虑一个类似的JSON结构从我的问题:
{
"response":
{
...,
"results":
[
{
"resourceType": "letter" ,
"resources": ["a", "b", "c", ...]
},
{
"resourceType": "number" ,
"resources": ["1", "2", "3", ...]
},
...
]
}
}
我抽象了公共响应结构:
enum ResourceKind
{
Letter,
Number
}
public class BaseResponse
{
public ResponseContent Response
{
get;
set;
}
}
public class ResponseContent
{
public List<ResultContent> Results
{
get;
set;
}
}
public class ResultContent
{
public ResourceKind Kind
{
get;
set;
}
public List<string> Resources
{
get;
set;
}
}
最后得到了一个特定服务器响应的简化实现:
public class SpecificResponse : BaseResponse
{
public IEnumerable<SpecificResult> Results
{
get
{
foreach(ResultContent result in Response.Results)
{
SpecificResult newSpecificResult = new SpecificResult();
newSpecificResult.Kind = result.Kind;
newSpecificResult.Resources = result.Resources;
yield return newCategory;
}
yield break;
}
}
}
我还在寻找更好的东西,但现在这就是我的解决方案。