DfrDkn
DfrDkn

Reputation: 1370

How can I post JSON data using mvc form submit?

I have hidden fields on my view which contains data in Json Format. I want to post this data using form submit. I can't use ajax.

<input type="hidden" id="workData" name="Works" data-value="[{"Id":44,"Body":"Completion Status","IsCompleted":true},{"Id":11,"Body":"Completion details","IsCompleted":false}]" value="{"Id":"33","Body":"Status","IsCompleted":true}">

<input type= "hidden" name ="Name" value="Micheal">

I have a Employee Model and a Work Model. Each employee is assigned list of works.

public class Employee
{
    public string Name {get; set;}
    public List<Work> Works {get; set;} 
}

public class Work 
{
    public string Body {get; set;}
    public boll IsCompleted{get; set;}
}

My action method signature is this

public ActionResult SetWorkStatus(Employee employee)

How can I post this data to the action?

Upvotes: 1

Views: 7933

Answers (2)

brroshan
brroshan

Reputation: 1650

I faced a similar problem when I couldn't use ajax. So this is how I managed to get it to work.

First replace the double quotes around your data-value attribute with single quotes ' '

Then you have to append hidden inputs to your form. They will then bind correctly to your model.

To bind complex objects, you need to provide an index for each item, rather than relying on the order of items. This ensures we can unambiguously match up the submitted properties with the correct object.

@using (Html.BeginForm("SetWorkStatus", "Controller", FormMethod.Post))
{
   @Html.HiddenFor(e => e.Name)
   <input type="hidden" id="workData" data-value='[{"id":44,"body":"completion status","iscompleted":true},{"id":11,"body":"completion details","iscompleted":false}]' value='{"id":"33","body":"status","iscompleted":true}'>
   <input type="submit" value="submit" />
}

@section scripts{
<script type="text/javascript">

    $(function () {



        $("input:submit")
        .on("click", function () {

            var str = JSON.stringify($("#workData").data("value"));
            var data = JSON.parse(str).map(function (e) {
                return { Body: e.body, IsCompleted: e.iscompleted };
            });

            data.forEach(function (e, i) {

                $("form").append("<input type='hidden' name='Employee.Works[" + i + "].Body' value='" + e.Body + "' />" +
                                 "<input type='hidden' name='Employee.Works[" + i + "].IsCompleted' value='" + e.IsCompleted + "' />");

            });

        });

    });

</script>

}

Note that the index must be an unbroken sequence of integers starting at 0 and increasing by 1 for each element.

See model binding to list

Upvotes: 2

jrummell
jrummell

Reputation: 43077

The MVC model binder doesn't know how to convert the JSON value of your Work input to a model. One thing you can try is changing your POST model to use a string for Works, and then parse the JSON in your action.

public class PostEmployeeModel
{
    public string Name {get; set;}
    public string Works {get; set;} 
}

[HttpPost]
public ActionResult SetWorkStatus(PostEmployeeModel employee)
{
    Work work = JsonConvert.DeserializeObject<Work>(employee.Works)
    // ...
}

Upvotes: 0

Related Questions