2

JSON データを受け取るいくつかの PUT メソッドを使用して Web API ApiController を作成しています。JSON は決定論的ではないため、カスタム C# オブジェクトにハードマップすることはできませんが、辞書/シーケンス (マップ/リスト) として受け取る必要があります。

コントローラーの PUT メソッドのデータ パラメーターに IDictionary を使用してみましたが、この種の作業は、データが JSON から辞書にマップされているように見えます。ただし、ディクショナリを として宣言する必要が<String,Object>あり、オブジェクトの値を適切な型として取得する明確な方法はありません。(検索でいくつかの提案されたクルーゲを見つけましたが、それらはそれだけです。)

System.Json.JsonObject タイプもあり、最終的に NuGet 経由でロードできましたが、それを使用すると、システムはデータのマッピング方法を認識していないようです。

これは通常どのように行われますか? 一般的な JSON を受け取る ApiController メソッドをどのように実装しますか?

3 つの基本的なアプローチを見ることができます。

  1. どういうわけか、ディクショナリ/シーケンスをオブジェクトなどで機能させます。
  2. おそらくルーティング情報を入れ替えて、System.Json.JsonObject のようなものを機能させます。
  3. JSON をバイト配列として受け取り、利用可能な C# JSON ツールキットのいずれかを使用して明示的に解析します。

(データがどの程度動的であるかに関しては、JSON オブジェクトにはエントリが欠落しているか無関係なエントリがある可能性があり、場合によっては、特定のエントリが単一の JSON 値または値の JSON 配列として表されることがあります。(「値」は JSON 配列です) 、オブジェクト、文字列、数値、ブール値、または null.) 一般に、配列/非配列のあいまいさを除いて、キーと値の型の間の関係は既知です。)

(ただし、これは大規模なプロジェクトであり、他の作成者によって他のいくつかのコンポーネントから JSON 文字列を受信することに注意してください。受信した型を調べて、それが期待どおりであることをアサートできることは非常に便利であり、必要になることさえあります。セキュリティの観点から。)

(私はC#の比較的初心者であることを付け加えておく必要があります-約6か月しか使用していません。)

4

1 に答える 1

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);
    }
}
于 2014-06-03T22:54:51.713 に答える