admin管理员组

文章数量:1416051

I have a view where i dynamically render checkbox items with razor. User can make adjustments and then i need to send form back to controller. If i send only one item i.e. row, it works fine, but if i try to send all of them i always get null. How can i collect form data properly. This is what i have at the moment.

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

And view:

    <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>

EDIT:

This is how i render items with 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" [email protected] />
                <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>
    }

EDIT 2

Thank you for your answer @Avi Fatal it got me this far. Problem i am facing now is this. Checkbox elements rendered by razor have two inputs, one is hidden and other one is shown. When i collect form data i am always getting last input value (hidden one, that's always false) How can i get true value?

Current data sent to controller (everything is false):

{"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"}]}

Collecting data like this (found similar problem here on 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);

EDIT 3

With only .serialize() i get null as input parameter on controller, with JSON.stringify i get Count = 0, also empty. What am i missing?

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>

Controller

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

I have a view where i dynamically render checkbox items with razor. User can make adjustments and then i need to send form back to controller. If i send only one item i.e. row, it works fine, but if i try to send all of them i always get null. How can i collect form data properly. This is what i have at the moment.

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

And view:

    <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>

EDIT:

This is how i render items with 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" [email protected] />
                <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>
    }

EDIT 2

Thank you for your answer @Avi Fatal it got me this far. Problem i am facing now is this. Checkbox elements rendered by razor have two inputs, one is hidden and other one is shown. When i collect form data i am always getting last input value (hidden one, that's always false) How can i get true value?

Current data sent to controller (everything is false):

{"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"}]}

Collecting data like this (found similar problem here on 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);

EDIT 3

With only .serialize() i get null as input parameter on controller, with JSON.stringify i get Count = 0, also empty. What am i missing?

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>

Controller

public void SendData(IEnumerable<SomeClass> ajaxData)
    {
        var data = ajaxData;
    }
Share Improve this question edited Nov 25, 2015 at 8:25 azza idz asked Nov 24, 2015 at 7:30 azza idzazza idz 6633 gold badges13 silver badges28 bronze badges 8
  • You have not shown how you are dynamically generating the form controls, but the html you have shown has name attributes without indexers so will not bind to a collection. Refer the answers here and here for some options – user3559349 Commented Nov 24, 2015 at 7:33
  • Unfortunately adding indexes to names didn't work (following first and second link from your ment) – azza idz Commented Nov 24, 2015 at 8:19
  • Of course it works. If its not working for you, then consider posting the code you have used so we can correct your errors – user3559349 Commented Nov 24, 2015 at 10:22
  • 1 You cannot use a foreach loop to generate form controls in a view. You need to use for (int i = 0; i < Model.Count; i++) { @Html.HiddenFor(m => m.Id) @Html.CheckBoxFor(m -> m[i].R) .... } so that your controls are correctly named. – user3559349 Commented Nov 24, 2015 at 20:38
  • 1 Yes, and when you post back to the method which has a parameter for your model (i.e. List<SomeClass> model), the DefaultModelBinder will correctly set the value of all the boolean properties! – user3559349 Commented Nov 25, 2015 at 8:18
 |  Show 3 more ments

1 Answer 1

Reset to default 3

It took me some time to understand the problem (-:

Anyway, I have created a small test, and it is working.

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

public void TestPost(List<User> users)
{

}

you need to serialize your data to json array of objects, [{ 'UserName': "user 1" }, { 'UserName': "user 2" }] a little jquery manipulation... (see here: 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",
        });

本文标签: javascriptSend form data as array of objects to controller in aspnet mvcStack Overflow