2

MVC4 コントローラー ルートに渡したい複雑な JSON オブジェクトがあります。

{
"name": "Test",
"description": "Description",
"questions": [
    {
        "id": "1",
        "type": "1",
        "text": "123",
        "answers": [
            {
                "answer": "123",
                "prerequisite": 0
            },
            {
                "answer": "123",
                "prerequisite": 0
            }
        ],
        "children": [
            {
                "id": "2",
                "type": "2",
                "text": "234",
                "answers": [
                    {
                        "answer": "234",
                        "prerequisite": 0
                    },
                    {
                        "answer": "234",
                        "prerequisite": 0
                    }
                ],
                "children": []
            }
        ]
    }
]

これらのViewModelを定義しました:

public class FormDataTransformContainer
{
    public string name { get; set; }
    public string description { get; set; }
    public QuestionDataTransformContainer[] questions;
}

public class QuestionDataTransformContainer {
    public int type { get; set; }
    public string text { get; set; }
    public AnswerDataTransformContainer[] answers { get; set; }
    public QuestionDataTransformContainer[] children { get; set; }
}

public class AnswerDataTransformContainer {
    public string answer { get; set; }
    public int prerequisite { get; set; }
}

そして、これは私が打っているルートです:

    [HttpPost]
    public ActionResult Create(FormDataTransformContainer formData)
    {

現在、FormDataTransformContainer の名前と説明のプロパティが設定されていますが、質問の配列は null です。データ バインディングが解決してくれることを願っていましたが、データ構造のツリーの性質が少し複雑であると思います。私が正しければ、これに対する最善の解決策は何ですか?

4

3 に答える 3

3

questionsフィールドではなく、プロパティにする必要があります。また、配列からIList<>(シリアライゼーション ライブラリが適切に処理すると仮定して) に変更します。これは、おそらく本来あるべき状態に近く、特定の実装ではなく、より一般的なインターフェイスを使用できるためです。

public class FormDataTransformContainer
{
  public string name { get; set; }
  public string description { get; set; }
  public IList<QuestionDataTransformContainer> questions { get; set; }
}

public class QuestionDataTransformContainer {
  public int type { get; set; }
  public string text { get; set; }
  public IList<AnswerDataTransformContainer> answers { get; set; }
  public IList<QuestionDataTransformContainer> children { get; set; }
}

public class AnswerDataTransformContainer {
  public string answer { get; set; }
  public int prerequisite { get; set; }
}

この構造を Json.net (MVC4 のデフォルトだと思います) でテストしたところ、うまくいきました。

于 2013-09-23T20:21:38.617 に答える
0

@robert-harvey が言ったように、すでに利用可能なJSON.NETなどのライブラリを利用して、面倒な作業を行う必要があります。

JSON.NET API ドキュメントから取得: json を保持
する を作成するstring jsonと、それから読み取ることができますnew JsonTextReader(new StringReader(json))

于 2013-09-23T20:10:01.700 に答える
0

私は同様の問題を次のコードで解決しました:

public class ExtendedController : Controller
{
    public T TryCreateModelFromJson<T>(string requestFormKey)
    {
        if (!this.Request.Form.AllKeys.Contains(requestFormKey))
        {
            throw new ArgumentException("Request form doesn't contain provided key.");
        }

        return
            JsonConvert.DeserializeObject<T>(
                this.Request.Form[requestFormKey]);
    }
}

そして使用法:

    [HttpPost]
    [ActionName("EditAjax")]
    public ActionResult EditAjaxPOST()
    {
        try
        {
            var viewModel =
                this.TryCreateModelFromJson<MyModel>(
                    "viewModel");

            this.EditFromModel(viewModel);

            return
                this.JsonResponse(
                    this.T("Model updated successfuly."),
                    true);
        }
        catch (Exception ex)
        {
            this.Logger.Error(ex, "Error while updating model.");

            return this.JsonResponse(this.T("Error"), false);
        }
    }

JS から呼び出されます:

function saveViewModel() {
    $.post(
        '@Url.Action("EditAjax")',
        {
            __RequestVerificationToken: '@Html.AntiForgeryTokenValueOrchard()',
            viewModel: ko.mapping.toJSON(viewModel)
        },
        function (data) {
             // response
        });
}

JSON の逆シリアル化/シリアル化に追加のライブラリを使用: http://www.nuget.org/packages/Newtonsoft.Json

于 2013-09-23T20:29:35.430 に答える