2013-08-01 15 views
8

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

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)で可能ですか?どうしたらいいですか?

+0

あなたの質問を再調整する必要があります:今のところ、答えは**はい**と**はい**です。しかし、私はあなたにそれほど助けにならないと思います。 – Andreas

+1

[動的](http://msdn.microsoft.com/en-us/library/dd264741.aspx)変数に戻ってそのプロパティ/値にアクセスするコンテンツを割り当ててみることもできますが、 dはもちろん、プロパティの名前は –

+0

ですが、私はすでにデータ構造を知っている必要があります。私はちょうどその上にモデルを構築したくありません。 – Saturnix

答えて

17

EDIT#2:

私はdynamicオブジェクトにデシリアライズするために優れたJson.NETライブラリを使用することについて、以下の注記を追加しました。


EDIT#1:Hoghweed's answerから

おかげで、以下の私の答えは、今より完全です。具体的には、我々はに必要な、我々が期待どおりに動作するdynamic -nessためにExpandoObjectHttpResponseMessage.Contentから取得HttpContentをキャスト:

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

しかしReadAsync<T>()拡張メソッドを取得するには、あなたがNuGetを使用する必要があるだろうMicrosoft.AspNet.WebApi.Clientパッケージ(here's the "old" Nuget page、上記のパッケージに含まれていることを記載しています)からSystem.Net.Http.Formatting.dllをダウンロードしてインストールしてください。


オリジナル回答:

だから、あなたがPOCOを作成するために持っていて、変更を取り戻すXML/JSON構造としてそのプロパティを管理する必要がありますする必要はありません。 dynamicは、ユースケースのための完璧なようだ:具体的にXMLに関する

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) 

あなたがdynamicXML、とバックの間で変換するときに非常に役立つかもしれないAnoop Madhusudanan's ElasticObjectを試みることができます。具体的に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に使用できないことです。

これが役に立ちます。ダイナミックとしてHttpResponseMessage.Contentを読む

+0

[' ExpandoObject'](http://blogs.msdn.com/b/csharpfaq/ archive/2009/10/01/dynamic-in-c-4-0-introduction-the-expandoobject.aspx?Redirected = true)は、ElasticObjectのようなものに対する.NET 4.0の正式な回答と思われます。 – anaximander

+0

しかし、 'ElasticObject'は積極的に開発されていますが、' ExpandoObject'のアップデートは.NET Frameworkの新しいリリースと結びついています(ただし、[変更されるように見える](http://msdn.microsoft.com/en- us/library/dn151288.aspx))。また、OPが第三者のソフトウェアを使用するかどうかによって異なります。 –

+0

多くのご協力いただきありがとうございます。私はコードをコンパイルしていないという大きな問題を抱えていますが、できるだけ早くあなたが投稿したソリューションをテストし、答えをマークします。 – Saturnix

2

それはそれ直接のような動的、それはExpandoObjectなどのコンテンツです読み取るために適切な拡張メソッドを使用してアクセスすることが可能ですが、ない

私はそのための動作テストを書いて、それは明らかなのはテストですが、コンテキストは、あなたの質問が何であるかのようになります。

  1. JSONコンテンツと応答オブジェクト(私は自分でJSONを使用

      :テスト)
    1. モデルオブジェクト

    ことなくダイナミック解像度のテストは次のように構成されています

  2. は匿名オブジェクトに
  3. JsonMediaフォーマッタ
  4. を使用して、このオブジェクトの内容にHttpResponseMessageを作成する場合、それはテストの前提条件をインストールすることですExpandoObject

を使用して動的としてアクセスすることができますを考えますMicrosoft.AspNet.WebApi.Client だから、これはこれはあまりにもXMLの確認行うことができる

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")); 
    } 
} 

テストのコードです。

+0

おもしろいことに、 '.ReadAsAsync ()。Result'は、' HttpContent'を 'dynamic'として取得しますか? –

+0

はい、私はそれを使用し、結果が完了するまでスレッドをブロックする結果を読み取って結果を待っていましたが、余りにも継続を使用することができます。しかし、重要なことは、そうすることです、それをExpandoObjectとして読んで、あなたはそれをあなたの意図であったものを動的なものとして読むことができます – Hoghweed

関連する問題