我正在尝试从网上检索一些数据。数据以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)中的任何一种?我该怎么办?
答案 0 :(得分:18)
编辑#2:
我在下面添加了一条关于使用优秀的Json.NET库反序列化为dynamic
对象的说明。
编辑#1:
感谢Hoghweed's answer,我的答案现在更完整了。具体来说,我们需要投射我们从HttpContent
到ExpandoObject
的HttpResponseMessage.Content
,以便dynamic
- ness按预期工作:< / p>
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
似乎非常适合您的用例:
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's 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。
希望这有帮助。
答案 1 :(得分:2)
将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也可以做到这一点。