[英]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.Content
到ExpandoObject
为了使dynamic
-ness按预期方式工作:
dynamic content = response.Content.ReadAsAsync<ExpandoObject>().Result;
var myPropertyValue = content.MyProperty;
要获得ReadAsync<T>()
扩展方法,您需要使用NuGet从Microsoft.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
,它在dynamic
和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。
希望这可以帮助。
将HttpResponseMessage.Content
作为动态读取它是可能的但不能直接以动态方式访问它,而是使用适当的扩展方法将其内容读取为ExpandoObject 。
我写了一个行为测试,很明显是一个测试,但上下文类似于你的问题:
测试结构如下:
HttpResponseMessage
时 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.