1

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?

5
  • Use action and method attributes on form tag. This should not be hard to research. Fix outer quotes in data attribute to single quotes or browser html parsers will have a problem Commented Jul 30, 2015 at 19:20
  • Using jquery on click and handle the rest. Commented Jul 30, 2015 at 19:20
  • I tried both options but no success Commented Jul 30, 2015 at 19:40
  • Firstly your input does not even have a value attribute (just a data-value attribute) so nothing will be posted, Even if you change it, it wont bind (try using List<Work> Works = "[{"Id":44,"Body": .....}]"; to understand). What is the point of this? Why send a collection to the client and then post it back again completely unchanged? Just get the collection again from the repository in the POST method (use Session if your concerned about making a database call) Commented Jul 31, 2015 at 0:49
  • But if you really wanted to do this, then its for (int i = 0; i < Model.Works.Count; i++) { @Html.HiddenFor(m => m.Works[i].Body) .... } which correctly generated the html you need to bind to a collection Commented Jul 31, 2015 at 0:51

2 Answers 2

2

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

Sign up to request clarification or add additional context in comments.

Comments

0

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)
    // ...
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.