【问题标题】:How to receive JSON data into Web API ApiController method?如何将 JSON 数据接收到 Web API ApiController 方法中?
【发布时间】:2014-07-24 10:38:54
【问题描述】:

我正在编写一个带有多个接收 JSON 数据的 PUT 方法的 Web API ApiController。 JSON 不是确定性的因此不能硬映射到自定义 C# 对象,但需要作为字典/序列(映射/列表)接收。

我已经尝试在控制器中为 PUT 方法的数据参数使用 IDictionary,并且这种方法很有效——数据似乎从 JSON 映射到字典。但是,有必要将字典声明为<String,Object>,并且没有明确的方法可以将 Object 值检索为其适当的类型。 (我在搜索中发现了一些建议的 kluges,但它们就是这样。)

还有一个 System.Json.JsonObject 类型,我终于设法通过 NuGet 加载它,但是当我使用它时,系统似乎不知道如何映射数据。

这通常是如何完成的?如何实现一个接收通用 JSON 的 ApiController 方法?

我可以看到三种基本方法:

  1. 以某种方式使 Dictionary/Sequence 与 Object 或类似对象一起工作。
  2. 让 System.Json.JsonObject 之类的东西工作起来,或许可以通过调整路由信息来实现。
  3. 以字节数组的形式接收 JSON,然后使用可用的 C# JSON 工具包之一显式解析。

(关于数据的动态性,JSON 对象可能缺少条目或无关条目,在某些情况下,特定条目可能表示为单个 JSON 值或 JSON 值数组。(其中“值”是 JSON 数组、对象、字符串、数字、布尔值或 null。)一般情况下,除了数组/非数组的歧义外,键和值类型之间的关系是已知的。)

(但我应该注意,这是一个大型项目,我将从其他作者的其他几个组件接收 JSON 字符串。能够检查接收到的类型并断言它与预期的一样非常有用,并且可能从安全的角度来看,甚至是必要的。)

(我应该补充一点,我是 C# 的相对新手——只使用了大约 6 个月。)

【问题讨论】:

  • 问题需要更具体,“这通常是如何完成的?”风格问题通常会因为过于宽泛或基于观点而被关闭。
  • dynamic 您收到的 JSON 格式如何?您是否提前知道它可能包含哪些字段?
  • 好吧,我打算为此提供大量赏金,但我想我不会那样做。
  • 我已经很清楚了。可惜没人想知道我发现了什么。
  • @HotLicks,问题已重新打开,请随时添加您发现的内容。

标签: c# json asp.net-web-api asp.net-apicontroller


【解决方案1】:

你必须知道你期待什么样的数据,但我过去使用动态类型成功地做到了这一点。

类似这样的:

    [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);
    }
}

【讨论】:

  • 那么你如何做动态打字呢?我发现的例子只是 Object kluges 的变体?
  • 不清楚在框架执行反序列化的 ApiController 上下文中如何工作。
  • 目前还不清楚这将如何在 ApiController 中工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
  • 2013-08-10
  • 2017-05-07
  • 2016-02-28
  • 1970-01-01
相关资源
最近更新 更多