私は現在、JSON を返す外部 REST API (これは制御できません) 用の ac# ラッパー ライブラリを作成しています。
次の 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; }
}
CountriesWrapper
逆シリアル化から返された Dictionary を反復処理しなければならない GetCountries メソッドと、クラスを持つことにあまり満足していません。
質問:トリックを見逃しているか、またはこれをレイアウトするためのよりクリーンな方法を誰かが提案できるかどうかを知りたい. 外部 API に GET リクエストを発行する一般的な方法を維持しながら。