繁体   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