【问题标题】:Passing json into MVC controller将 json 传递给 MVC 控制器
【发布时间】:2016-09-01 07:17:53
【问题描述】:

我看到很多关于 SO 的帖子都在考虑这个主题,尽管应用解决方案对我不起作用,我现在很困惑。 Mb 我错过了什么?

请认为我是 .js 方面的菜鸟。

所以我用这个 JS 从动态创建的表单元素中获取我的值并尝试发布它:

编辑 12:21:我得到了这个脚本,它应该将表单中的每个元素解析为类似于 json 的自定义数组。我仍然得到空引用。知道如何获得它吗?

 var getValues = function (myForm) {
        var array = [];
    var parser;

    $("formElement").each( function (i, elem) {

            parser.empty()
            parser = {
                Id: $(elem,"#Id ").val(),
                someOption: $(elem, "#someOption ").val(),
                someText: $(elem, "#someText ").val(),
                someNumber: $(elem, "#someNumber  ").val()
            }
            array.push(parser);

        });

    console.log(array);


    $.ajax({
        type: "POST",
        url: 'angus',
        traditional: true,
        data:  {json: array },
        success: function (data) {
            $("#getData").empty();
            $("#getData").append(array);
        }
    });            
    };

我在日志中得到了这个: (像 i,i+1,i+2,i+3 这样的索引对象与视图模型匹配 - 对吗?我对这些原型和函数有复杂的感觉 - 它是什么?)

在我的控制器操作中,我得到空异常:

 [HttpPost]
        public ActionResult angus(IEnumerable<TrashViewModel> json)
        {

            return View(json.ToList());
        }

我创建了我的视图模型:

  [Serializable]
public class TrashViewModel
{
    public int Id { get; set; }
    public string someOption { get; set; }
    public string someText { get; set; }
    public string someNumber { get; set; }

}

我的表单 HTML 属性名称与 viemodel 类的名称匹配。

编辑: html:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="formExample" ng-controller="ExampleController">

    <button class="btn btn-primary" ng-controller="addRow" ng-click="addLine()">Dodaj przycisk</button>

    <form novalidate class="simple-form">
        <div class="here">
            <div class="formElement row">

                  <input type="hidden" name="Id" value="1"/>
                <div class="col-md-2">
                    <select name="someOption" class="optns form-group col-md-12" ng-model="user.class">
                        <option selected value="1"> Rodzaj... </option>
                        <option value="test">2</option>
                        <option value="2">test</option>
                        <option value="2">2</option>
                        <option value="3">3</option>
                        @*tutaj beda dodane opcje*@
                    </select>
                </div>
                <div class="col-md-1">
                    <input name="someNumber" class="form-group col-md-12" type="number" ng-model="user.number" value="" text="Ilość..." /><br />
                </div>
                <div class="col-md-9">
                    <input name="someText" class="form-group col-md-12" type="text" ng-model="user.text" value="" text="Uwagi..." /><br />
                </div>
            </div>
        </div>
        <input type="button" value="Reset" />
        <input type="submit" value="Save" />
    </form>
</div>

附加的html:

 var strVar = "";
            strVar += "<div class=\"formElement row\">";
            strVar += "                  <input type=\"hidden\" name=\"Id\" value=\" "+ $scope.counter +"\"\/>";
            strVar += "                <div class=\"col-md-2\">";
            strVar += "                    <select name=\"someOption\" class=\"optns form-group col-md-12\" ng-model=\"user.class\">";
            strVar += "                        <option selected value=\"1\"> Rodzaj... <\/option>";
            strVar += "                        <option value=\"test\">2<\/option>";
            strVar += "                        <option value=\"2\">test<\/option>";
            strVar += "                        <option value=\"2\">2<\/option>";
            strVar += "                        <option value=\"3\">3<\/option>";
            strVar += "                        @*tutaj beda dodane opcje*@";
            strVar += "                    <\/select>";
            strVar += "                <\/div>";
            strVar += "                <div class=\"col-md-1\">";
            strVar += "                    <input name=\"someNumber\" class=\"form-group col-md-12\" type=\"number\" ng-model=\"user.number\" value=\"\" text=\"Ilość...\" \/><br \/>";
            strVar += "                <\/div>";
            strVar += "                <div class=\"col-md-9\">";
            strVar += "                    <input name=\"someText\" class=\"form-group col-md-12\" type=\"text\" ng-model=\"user.text\" value=\"\" text=\"Uwagi...\" \/><br \/>";
            strVar += "                <\/div>";
            strVar += "            <\/div>";

我最终得到空异常,其他帖子建议是因为 viemodel 类与序列化对象不匹配。目前不知道该怎么办。

谢谢!

【问题讨论】:

  • 您需要显示您生成的html。显示一些典型的name 属性 - 它们是否被正确索引?
  • @StephenMuecke 已将其添加到帖子中,谢谢考虑
  • 如果您动态添加具有重复name 属性的多个项目,那么使用serializeArray()(或serialize())根本行不通。您可以根据 this example 使用索引器生成正确的名称属性,在这种情况下,它只是 data: form.serialize(), 并删除 traditional: true,
  • 另一种方法是通过循环遍历每个&lt;div class="row"&gt; 手动生成对象数组 - 它需要看起来像[{ Id: 1, someOption: 'xxx', ... }, { Id: 2, someOption: 'yyy', ... }, ... ] 然后JSON.stringify() 它并设置contentType: 'json',
  • thx @StephenMuecke 会尝试一下 :)

标签: javascript json ajax asp.net-mvc


【解决方案1】:

为了发布您的数组,您需要对数据进行字符串化并设置contentType 选项。你的ajax代码需要是

$.ajax({
    type: 'POST',
    url: '@Url.Action("angus")', // do not hard code url's
    contentType: "application/json; charset=utf-8",
    data: JSON.stringify({ model: array }), 
    success: function (data) {

和控制器

[HttpPost]
public ActionResult angus(IEnumerable<TrashViewModel> model)

【讨论】:

    【解决方案2】:

    尝试替换

     var parsed = $(myForm).serializeArray();
    

     var parameters = {
                Id : $("#Id ").val(),
                someOption : $("#someOption ").val(),
                someText : $("#someText ").val(),
                 someNumber  : $("#someNumber  ").val()
           };
    

    然后将其传递给提交

    JSON.stringify(parameters)
    

    【讨论】:

    • 它为单个元素完成了工作,现在我将其更改为数组,因为这就是重点 - 如果它有效,肯定会标记为答案:) thx
    【解决方案3】:

    在你的 JavaScript 代码中,我突然想到了 3 件事:

    1. 您正在使用 .serializeArray(),它创建一个对象数组,每个对象都有一个名称和值属性。这与您的 TrashViewModel 对象的结构不匹配
    2. 您将序列化对象包装在一个新对象中,该对象具有一个名为“json”的属性,这会为您的数据添加更多结构
    3. 您正在对所述对象进行字符串化

    所有这些都是不必要的,因为 .ajax() 方法将为您以正确的格式打包数据。您只需将序列化表单作为数据参数传递。

    data: $(myform).serialize()
    

    在控制器上,您只需将操作上的参数设置为您的 TrashViewModel 对象。请注意,它是单个对象,而不是可枚举的。

    public ActionResult Angus(TrashViewModel form)
    {
        // do something
    }
    

    如果您要使用 .serializeArray(),那么您需要创建一个具有 Name 和 Value 属性的模型对象,以便模型绑定器可以正确解析参数。

    // JavaScript 
    data: $(myform).serializeArray()
    
    // Controller
    public class NameValueModel
    {
        public string Name { get; set; }
        public string Value { get; set; }
    }
    
    public ActionResult Angus(NameValueModel[] form)
    {
        // do something
    }
    

    【讨论】:

    • 我的想法虽然我还没有完全理解 json 的所有内容,但谢谢你,会尝试一下
    【解决方案4】:

    我对结果不是 100% 满意,因为我仍然需要在服务器端解析 json 字符串。我想我很快就会做Q&A,这样别人就不用打一周的时间来做这样的事情了。感谢:

    • @StephenMuecke
    • @Emil
    • @Jeff M

    所以实际上我做了什么:

    js 获取输入并推送自定义样式,然后发布 ajax 请求:

            var array = [];
            var parser;
    
            $(".formElement").each( function (i, elem) {
    
                    //parser.empty()
                    parser = {
                        Id: $("#Id", $(this)).val(),
                        someOption: $("#someOption", $(this)).val(),
                        someText: $("#someText", $(this)).val(),
                        someNumber: $("#someNumber", $(this)).val()
                    };
                    console.log(parser);
                    array.push(parser);
    
                });
    
            console.log(array);
    
    
            $.ajax({
                type: "POST",
                url: 'angus',
                traditional: true,
                data: { json: JSON.stringify(array) },
                success: function (data) {
                    $("#getData").empty();
                    $("#getData").append(array);
                }
            });
    

    控制器: (不要介意逻辑,因为它在这里没有用,除了它在调试期间提供信息)

    最重要的是将字符串类型作为参数;我 100% 确定我的 json 从复杂类型的视图模型中反弹了

           [HttpPost]
            public ActionResult angus(string json)
            {
    
                var check = json.ToString() == null;
    
                return RedirectToAction("ErrorAction");
            }
    

    【讨论】:

    • 您不必解析参数。将string json更改为IEnumerable&lt;TrashViewModel&gt; model,然后按照我之前的cmets修改ajax-删除traditional: true,添加contentType: 'json'并将其更改为data: JSON.stringify({ model: array })
    • @StephenMuecke 尝试了你提到的字符串化和序列化 - 仍然得到空结果 $.ajax({ type: "POST", url: 'angus', contentType: 'json', //data: JSON .stringify({ json: array }), data: $(myForm).serialize(), success: function (data) { $("#getData").empty(); $("#getData").append( "Sukces!"); $("#getData").addClass(); } });
    • 抱歉,必须是contentType: "application/json; charset=utf-8",(并且已经过测试并且工作正常)。但是您的 html 无效(重复的 id 属性),因此您将在第一个 formElement 中发回控件的重复值 - 您需要使用类名
    • @StephenMuecke 上帝之母......它有效!将编辑顶部并给出答案:o 顺便说一句,如果你想获得荣誉,只需发布​​答案,我不能强调你如何帮助我:) 你应该得到它的 100%
    • @StephenMuecke 我的意思是你的答案(虽然它可能在第一次不清楚):)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    • 2014-03-17
    • 1970-01-01
    相关资源
    最近更新 更多