11

Webからデータを取得しようとしています。データは JSON オブジェクトまたは XML として提供されます。どちらの場合も、この XML/JSON の構造に基づいてモデルを構築するのではなく、必要なデータを取得するだけにしたいと考えています。

HttpResponseMessage response = await client.PostAsync(
"http://www.someAPI.com/api.xml",
requestContent);

response.EnsureSuccessStatusCode();

HttpContent content = response.Content;

返されたデータ構造に基づいてモデルを構築する必要がある場合は、それを行います。代替手段があるかどうかを知りたいだけです。匿名型として解析contentして、たとえばデータを任意のフィールド、プロパティ、または配列インデックスとして取得できますか?

言いましょう: response.Countries[5].CountryId. これらの 2 つのタイプ (JSON と XML) のいずれかで可能ですか? どうすればいいですか?

4

2 に答える 2

23

編集#2:

優れたJson.NETライブラリを使用してdynamicオブジェクトを逆シリアル化する方法について、以下にメモを追加しました。


編集#1:

Hoghweed's answer のおかげで、以下の私の答えはより完全になりました。具体的には、 -ness が期待どおりに機能するために、取得した をtoにキャストする必要があります。HttpContentHttpResponseMessage.ContentExpandoObjectdynamic

dynamic content = response.Content.ReadAsAsync<ExpandoObject>().Result;
var myPropertyValue = content.MyProperty;

ReadAsync<T>()ただし、拡張メソッドを取得するには、NuGetを使用してパッケージSystem.Net.Http.Formatting.dllからダウンロードしてインストールする必要があります (これは「古い」Nuget ページで、現在は上記のパッケージに含まれていることが記載されています)。Microsoft.AspNet.WebApi.Client


元の回答:

そのため、 POCOを作成したり、取得した XML/JSON 構造が変更されたときにそのプロパティを管理したりする必要はありません。dynamicあなたのユースケースに最適なようです:

HttpResponseMessage response = await client.PostAsync(
"http://www.someAPI.com/api.xml", requestContent);

response.EnsureSuccessStatusCode();

dynamic content = response.Content.ReadAsAsync<ExpandoObject>().Result; // Notice the use of the dynamic keyword
var myPropertyValue = content.MyProperty; // Compiles just fine, retrieves the value of this at runtime (as long as it exists, of course)

特に XML に関して: Anoop MadhusudananElasticObjectdynamicを試すことができますXML

特に JSON に関して: Json.NETを使用 して、次のようなことを行うことができます。

dynamic content = JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result);
var myPropertyValue = content.MyProperty;

Microsoft.AspNet.WebApi.Client利点は、パッケージに依存しないことです(v4.0.30506.0現時点では、Json.NET に依存しています)。欠点は、これを XML に使用できないことです。

お役に立てれば。

于 2013-08-01T09:16:51.927 に答える
3

HttpResponseMessage.Contentを動的として読み取ることは可能ですが、動的として直接アクセスすることはできませんが、適切な拡張メソッドを使用してコンテンツをExpandoObjectとして読み取ります。

そのための動作テストを書きました。テストであることは明らかですが、コンテキストはあなたの質問と似ています:

  1. json コンテンツを含む応答オブジェクト(テストでは json を使用しました)
  2. モデル オブジェクトのない動的解決

テストは次のように構成されています。

  1. 匿名オブジェクトが与えられた場合
  2. HttpResponseMessageJsonMedia Formatter を使用して、このオブジェクトのコンテンツで を作成する場合
  3. 次に、を使用して動的にアクセスすることができますExpandoObject

テストの前提条件は、Microsoft.AspNet.WebApi.Client をインストールすることなので、これがテストのコードです

public class RetrieveAnonymousTypeFromTheWebInCSharp 
    : BehaviorTest
{
    private object _testModel;
    private HttpResponseMessage _message;

    protected override void Given()
    {
        _testModel = new
            {
                Id = 14,
                MyProperty = "Test property value"
            };
    }

    protected override void When()
    {
        _message = new HttpResponseMessage(HttpStatusCode.Accepted)
                       {
                           Content =
                               new ObjectContent(_testModel.GetType(),
                                                 _testModel,
                                                 new JsonMediaTypeFormatter
                                                     ())
                       };
    }

    [Test]
    public void Then()
    {
        //then properties could be retrieved back by dynamics
        dynamic content = _message.Content.ReadAsAsync<ExpandoObject>().Result;
        var propertyvalue = content.MyProperty;
        Assert.That(propertyvalue, Is.Not.Null.And.EqualTo("Test property value"));
    }
}

これはxmlでも確実に実行できます。

于 2013-08-01T13:33:23.303 に答える