我目前正在为外部 REST API(我无法控制)编写 ac# 包装器库,它返回 JSON。
反序列化以下 JSON
{
"countries": {
"2": {
"name": "Albania",
"isoCode": "AL",
"dialCode": "+355"
},
"3": {
"name": "Algeria",
"isoCode": "DZ",
"dialCode": "+213"
},
"4": {
"name": "American Samoa",
"isoCode": "AS",
"dialCode": "+1684"
}
}
}
我的库中有一个方法GetCountries
,它执行以下操作:
public List<Country> GetCountries()
{
string endpointUrl = GenerateEndPointUri(...)
var countries = IssueApiGETRequest<CountriesWrapper>(endpointUrl);
return countries.Countries.Select(x =>
{
x.Value.Id = x.Key;
return x.Value;
}).ToList();
}
IssueAPIGetRequest
看起来像这样:
private T IssueApiGETRequest<T>(string endPointUrl)
{
using (var handler = new HttpClientHandler())
{
handler.Credentials = ...;
using (HttpClient client = new HttpClient(handler))
{
var response = client.GetAsync(endPointUrl).Result;
if (response.IsSuccessStatusCode)
{
string json = response.Content.ReadAsStringAsync().Result;
var result = JsonConvert.DeserializeObject<T>(json);
return result;
}
else
{
switch (response.StatusCode)
{
case HttpStatusCode.BadRequest:
throw new InvalidParameterException("Invalid parameters");
}
throw new Exception("Unable to process request");
}
}
}
}
这允许我为外部 API 上的所有 GET 端点定义一个通用方法,并将它们序列化为我自己定义的类型。
最后,我定义了这些类实体:
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
internal class CountriesWrapper
{
[JsonProperty(PropertyName = "countries")]
public IDictionary<int, Country> Countries { get; set; }
}
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class Country
{
public int Id { get; set; }
[JsonProperty(PropertyName = "name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "isoCode")]
public string IsoCode { get; set; }
[JsonProperty(PropertyName = "dialCode")]
public string DialCode { get; set; }
}
我对 GetCountries 方法不太满意,该方法必须重申从反序列化返回的 Dictionary 并拥有CountriesWrapper
该类。
问题:我想知道我是否错过了一个技巧,或者是否有人可以建议一种更清洁的方式来解决这个问题。同时保持向外部 API 发出 GET 请求的通用方法。