【问题标题】:Send form data as array of objects to controller in asp.net mvc将表单数据作为对象数组发送到asp.net mvc中的控制器
【发布时间】:2015-11-24 07:30:04
【问题描述】:

我有一个视图,我用剃刀动态呈现复选框项目。用户可以进行调整,然后我需要将表单发送回控制器。如果我只发送一个项目,即行,它工作正常,但如果我尝试发送所有项目,我总是得到空值。如何正确收集表单数据。这是我目前拥有的。

public void SendData(List<SomeClass> myData)
    {
        var data = myData; //always null
    }

    public class SomeClass
    {
        public int Id { get; set; }
        public int RoleId { get; set; }
        public bool R { get; set; }
        public bool W { get; set; }
        public bool E { get; set; }
        public bool D { get; set; }
    }

并查看:

    <script type="text/javascript">

    $(document).ready(function () {

        var test = $("#myForm").serialize();

        console.log(test);

        test = JSON.stringify({ 'myData': test });

        console.log(test);

        $.ajax({
            contentType: 'application/json; charset=utf-8',
            type: 'POST',
            url: '/Home/SendData',
            data: test,
            success: function () {

            },
            failure: function (response) {

            }
        });
    });

    </script>


        <form id="myForm">

        <div class="row control_group">
            @Html.Hidden("Id", 1)
            @Html.Hidden("RoleId", 1)
            @Html.CheckBox("R", false)
            @Html.CheckBox("W", false)
            @Html.CheckBox("E", false)
            @Html.CheckBox("D", false)
        </div>

        <div class="row control_group">
            @Html.Hidden("Id", 2)
            @Html.Hidden("RoleId", 2)
            @Html.CheckBox("R", true)
            @Html.CheckBox("W", true)
            @Html.CheckBox("E", true)
            @Html.CheckBox("D", true)
        </div>

    </form>

编辑:

这就是我使用 razor 渲染项目的方式

    foreach (SomeObject x in items)
    {
        var menuName = someStringFromDb;
        var permissions = x.MainItem.FirstOrDefault();

            <div class="row control_group">
                <div class="col-sm-4">@menuName</div>
                <input name="Id" type="hidden" value="@permissions.Id"/>
                <input name="RoleId" type="hidden" value=@permissions.RoleId />
                <div class="col-sm-2">
                    @Html.CheckBox("R", @permissions.Read)
                </div>
                <div class="col-sm-2">
                    @Html.CheckBox("W", @permissions.Write)
                </div>
                <div class="col-sm-2">
                    @Html.CheckBox("E", @permissions.Edit)
                </div>
                <div class="col-sm-2">
                    @Html.CheckBox("D", @permissions.Delete)
                </div>
            </div>
    }

编辑 2

感谢您的回答@Avi Fatal,它让我走到了这一步。我现在面临的问题是这个。 razor 渲染的复选框元素有两个输入,一个是隐藏的,另一个是显示的。当我收集表单数据时,我总是得到最后一个输入值(隐藏的一个,那总是假的)我怎样才能得到真值?

当前发送给控制器的数据(一切都是假的):

{"ajaxData":[{"Id":"1","RoleId":"1","R":"false","W":"false","E":"false","D":"false"},{"Id":"2","RoleId":"2","R":"false","W":"false","E":"false","D":"false"}]}

像这样收集数据(在 SO 上发现了类似的问题):

var ajaxData = $('.control_group').map(function (i, group) {
                var data = {};
                $(group).find(':input').each(function () {
                    data[this.name] = this.value;
                });
                return data;
            }).get();

            ajaxData = JSON.stringify({ 'ajaxData': ajaxData });

            console.log(ajaxData);

编辑 3

仅使用 .serialize() 我得到 null 作为控制器上的输入参数,使用 JSON.stringify 我得到 Count = 0,也是空的。我错过了什么?

HTML:

        @model List<WebApplication3.Controllers.HomeController.SomeClass>

    <form id="myForm">
        @for (int i = 0; i < Model.Count; i++)
        {
            <div>Element</div>
            @Html.HiddenFor(m => m[i].Id)
            @Html.HiddenFor(m => m[i].RoleId)
            @Html.CheckBoxFor(m => m[i].R)
            @Html.CheckBoxFor(m => m[i].W)
            @Html.CheckBoxFor(m => m[i].E)
            @Html.CheckBoxFor(m => m[i].D)
        }
    </form>

    <button id="send">SEND</button>


    <script type="text/javascript">

        $('#send').on('click', function () {

            var data = $("#myForm").serialize();
            console.log(data);

            //data = JSON.stringify({ 'ajaxData': data });

            $.ajax({
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                type: 'POST',
                url: '/Home/SendData',
                data: data,
                success: function () {

                },
                failure: function (response) {

                }
            });

        });

    </script>

控制器

public void SendData(IEnumerable<SomeClass> ajaxData)
    {
        var data = ajaxData;
    }

【问题讨论】:

  • 您尚未展示如何动态生成表单控件,但您展示的 html 具有没有索引器的 name 属性,因此不会绑定到集合。请参阅答案herehere 了解一些选项
  • 不幸的是,为名称添加索引不起作用(按照您评论中的第一个和第二个链接)
  • 当然可以。如果它不适合您,请考虑发布您使用的代码,以便我们纠正您的错误
  • 您不能使用foreach 循环在视图中生成表单控件。您需要使用for (int i = 0; i &lt; Model.Count; i++) { @Html.HiddenFor(m =&gt; m.Id) @Html.CheckBoxFor(m -&gt; m[i].R) .... } 以便正确命名您的控件。
  • 是的,当您回发到具有模型参数的方法(即List&lt;SomeClass&gt; model)时,DefaultModelBinder 将正确设置所有boolean 属性的值!

标签: javascript jquery json ajax asp.net-mvc


【解决方案1】:

我花了一些时间来理解这个问题(-:

无论如何,我已经创建了一个小测试,并且它正在运行。

public class User
{
        public string UserName { get; set; }
}

public void TestPost(List<User> users)
{

}

您需要将数据序列化为 json 对象数组, [{ 'UserName': "user 1" }, { 'UserName': "user 2" }] 一个小小的 jquery 操作...(见这里:Convert form data to JavaScript object with jQuery

$.ajax({
            contentType: 'application/json; charset=utf-8',
            type: 'POST',
            url: '/Home/TestPost',
            data: JSON.stringify([{ 'UserName': "user 1" }, { 'UserName': "user 2" }]),
            dataType: "json",
        });

【讨论】:

  • 感谢您的回答@Avi Fatal,它让我走到了这一步(见编辑 2)。我现在面临的问题是这个。 razor 渲染的复选框元素有两个输入,一个是隐藏的,另一个是显示的。当我收集表单数据时,我总是得到最后一个输入值(隐藏的一个,总是假的)我怎样才能得到真正的价值?
  • 您好,请接受答案并打开另一个线程,这是一个不同的问题。它不属于这里...当您打开一个新线程时会查看它。
猜你喜欢
  • 2013-09-26
  • 2012-02-22
  • 1970-01-01
  • 2022-01-16
  • 2013-07-24
  • 2020-10-05
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
相关资源
最近更新 更多