簡體   English   中英

在C#中從Web檢索匿名類型

[英]Retrieve anonymous type from the web in C#

我正在嘗試從網上檢索一些數據。 數據以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 是否有可能在這兩種類型(JSON和XML)中的任何一種? 我該怎么做?

編輯#2:

我在下面添加了一個關於使用優秀的Json.NET庫反序列化為dynamic對象的注釋。


編輯#1:

感謝Hoghweed的回答 ,我的答案現在更完整了。 具體而言,我們需要轉換 HttpContent我們從得到HttpResponseMessage.ContentExpandoObject為了使dynamic -ness按預期方式工作:

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

要獲得ReadAsync<T>()擴展方法,您需要使用NuGetMicrosoft.AspNet.WebApi.Client包下載並安裝System.Net.Http.Formatting.dll這里是“舊”Nuget頁面 ,其中提到它現在包含在上面的包中)。


原答案:

因此,您不希望創建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 Madhusudanan的ElasticObject ,它在dynamicXML之間轉換時可能非常有用。

特別是關於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作為動態讀取它是可能的但不能直接以動態方式訪問它,而是使用適當的擴展方法將其內容讀取為ExpandoObject

我寫了一個行為測試,很明顯是一個測試,但上下文類似於你的問題:

  1. 一個帶有json內容的響應對象 (我在測試中使用了json)
  2. 沒有模型對象的動態分辨率

測試結構如下:

  1. 給定一個匿名對象
  2. 使用JsonMedia Formatter創建包含此對象內容的HttpResponseMessage
  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也可以做到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM