我正在编写一个Web API ApiController,它有几个接收JSON数据的PUT方法。 JSON不是确定性的,因此无法硬映射到自定义C#对象,但需要作为词典/序列(地图/列表)接收。
我尝试在控制器中使用IDictionary作为PUT方法的数据parm,这种工作 - 数据似乎从JSON映射到字典。但是,有必要将字典声明为<String,Object>
,并且没有明确的方法可以将Object值检索为适当的类型。 (我在搜索中找到了一些建议的kluges,但它们就是这样。)
还有一个System.Json.JsonObject类型,我最终设法通过NuGet加载,但是当我使用它时,系统似乎不知道如何映射数据。
这通常如何做?如何实现接收通用JSON的ApiController方法?
我可以看到三种基本方法:
(关于数据的动态性,JSON对象可能缺少条目或无关条目,在某些情况下,特定条目可能表示为单个JSON值或JSON数组值。(其中“value”是JSON数组,对象,字符串,数字,布尔值或null。)通常,除了数组/非数组歧义外,键和值类型之间的关系是已知的。)
(但我应该注意,这是一个大型项目,我将从其他作者那里接收来自其他几个组件的JSON字符串。能够检查收到的类型并断言它符合预期会非常有用,并且可能从安全的角度来看,甚至是必要的。)
(我应该补充一点,我是C#的相对新手 - 只使用它约6个月。)
答案 0 :(得分:0)
你必须知道你期望的数据类型,但过去使用动态类型我已经取得了成功。
这样的事情:
[Test]
public void JsonTester()
{
string json = "{ 'fruit':'banana', 'color':'yellow' }";
dynamic data = JsonConvert.DeserializeObject(json);
string fruit = data["fruit"];
string color = data["color"];
Assert.That(fruit == "banana");
Assert.That(color == "yellow");
}
修改强>
您需要事先知道要反序列化的类型 - 在这种情况下,您可以立即将其反序列化为该类型。
或者您可以将其反序列化为dynamic
类型,然后在知道要对其执行操作后将其转换为静态类型。
using Newtonsoft.Json;
using NUnit.Framework;
public class DTO
{
public string Field1;
public int Field2;
}
public class JsonDeserializationTests
{
[Test]
public void JsonCanBeDeserializedToDTO()
{
string json = "{ 'Field1':'some text', 'Field2':45 }";
var data = JsonConvert.DeserializeObject<DTO>(json);
Assert.That(data.Field1 == "some text");
Assert.That(data.Field2 == 45);
}
[Test]
public void JsonCanBeDeserializedToDynamic_AndConvertedToDTO()
{
string json = "{ 'Field1':'some text', 'Field2':45 }";
var dynamicData = JsonConvert.DeserializeObject<dynamic>(json);
var data = new DTO { Field1 = dynamicData["Field1"], Field2 = dynamicData["Field2"] };
Assert.That(data.Field1 == "some text");
Assert.That(data.Field2 == 45);
}
}