Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Post JSON data through a form in MVC4

I'm trying to POST a JSON object (a JSON-ified knockout model, if that's of any relevance) to my MVC controller, and have the controller return a new view. To do this, I'm sending the data with a form. The problem is that I would like to have the JSON automatically converted to a model when the controller receives it.

If I were to use an AJAX call for this,

var actionModel = new Object();
actionModel.Controls = ko.toJS(self.controls());
var json = JSON.stringify(actionModel);
$.ajax({
    url: "MyController/Preview",
    type: "POST",
    contentType: 'application/json; charset=utf-8',
    cache: false,
    data: json,
    success: function (data) {
    }
});

...the JSON object is successfully deserialized and converted into an instance of my model class.

public ActionResult Preview(ActionModel actionModel) { ... }
public class ActionModel
{
    public List<ControlModel> Controls { get; set; }
}

If I want to do this with a form, I understand that I need to insert the JSON into a hidden input field, but the best I can manage when doing this is to receive the data as a serialized string:

@using (Html.BeginForm("Preview", "MyController", FormMethod.Post, new { id = "previewForm" }))
{
    <input type="hidden" id="hiddenFieldName" />
}

public ActionResult Preview(string hiddenFieldName) { ... }

I could just deserialize it afterwards, but I really would prefer it if MVC could convert it for me, as it would with an AJAX call. Is this possible?

Thanks.

like image 903
Alejo Avatar asked Nov 02 '12 13:11

Alejo


2 Answers

Assuming you want to post data encoded as json using a form and no XHR, I don't think it's out of the box possible.

Forms don't allow many content types. http://www.w3.org/TR/html401/interact/forms.html#form-content-type

If you post json as a string, its probably possible to create a model binder that looks for strings which appear to be json and deal with deserialization there. Not the prettiest thing, especially if this is just for some one off odd situation.

like image 66
Kenneth Ito Avatar answered Oct 07 '22 14:10

Kenneth Ito


Instead of the manual deserialization, you can catch the form post event and reconstruct your own post, adding the additional JSON object. Here is an example that uses the serializeObject method from this post):

$(document).ready(function () {
    $('form').live('submit', function (e) {
        e.preventDefault();

        var dataToPost = $(this).serializeObject();
        dataToPost.hiddenFieldName = actionModel; //additional object here
        $.ajax({
            type: $(this).attr('method'),
            url: $(this).attr('action'),
            data: JSON.stringify(dataToPost),
            contentType: 'application/json; charset=utf-8',
            success: function (res) {
                //do something...
            }
        });
    });
});
like image 21
Johann Avatar answered Oct 07 '22 14:10

Johann