1

I have a form whose data I want to be passed to my controller. This is the JQuery call that I am making -

    var data = $form.serializeArray();

    var options = {

        contentType: "application/json",
        url: "/Form/Save",
        data: JSON.stringify(data),
        type: "post",
        datatype: "html",
        success: function (result, xhr, status) {
            console.log(result);
        },
        error: function (xhr, status, error) {
            // redirect to error page
        }
    };

    $.ajax(options);

And this is how I am recieving this in controller -

    public ActionResult Save(string paramJson)
    {
        // save paramJson

        return null;
    }

But all I am recieving in Save action is paramJson = null. I tried below as well -

data: JSON.stringify({paramJson: data})

but it didn't work. What should be done here?

Sam
  • 4,302
  • 12
  • 40
  • 74
  • Why would you post back to a `string`? You can just serialize your form and have it post back to a model. –  Dec 05 '14 at 23:56
  • The reason is that there are some fields whose 'Name' tag is different from the field name due to an issue with jQuery.validate() – Sam Dec 06 '14 at 12:55
  • There is no issue with jQuery. If your `name` attribute is not correct is because your not constructing the html correctly. That's what you should be fixing, not trying to some hack. –  Dec 06 '14 at 22:26

3 Answers3

3

I took some hint from above answer and was able to frame a solution which works perfectly for me. I am now recieving a json in the format of formname: formvalue instead of name: formname, value: formvalue format. Here it is -

    var json = {};

    // converting to formname:formvalue format
    $.each($form.serializeArray(), function (i, field) {
        json[field.name] = field.value || '';
    });

    // stringify the parameter
    var data = { paramJson: JSON.stringify(json) };

    var options = {

        contentType: "application/json",
        url: "/Form/Save",
        data: JSON.stringify(data),
        type: "post",
        datatype: "html",
        success: function (result, xhr, status) {
            console.log(result);
        },
        error: function (xhr, status, error) {
            // redirect to error page
        }
    };

    $.ajax(options);
Sam
  • 4,302
  • 12
  • 40
  • 74
  • 1
    Fix your view and you can just use `form.serialize()` and post back your model. None of this is necessary! –  Dec 07 '14 at 22:31
  • There are a couple of array of objects fields in my model. I tried serializing but the values were not serialized as array. There was another issue where when I was binding Id field to the view, it was not getting validated. Can you tell how to fix these? – Sam Dec 08 '14 at 03:48
  • Without seeing your model and view I cant tell. But if you always use strongly typed helpers (e.g. `@Html.TextBoxFor(m => m.SomeProperty)`) and generate collections using `for` (not `foreach`) loops or `EditorTemplates` then you should have no problems. The `name` attributes will always match your properties and be bound when you post back. –  Dec 08 '14 at 03:53
  • I do use helpers but please clear a couple of things - Firstly, do they work with a dropdownfield (an int field in model) too -say @Html.DropDownListFor(m => m.TypeId, ...)? Secondly, does the foreach generate array of names after serializing? – Sam Dec 08 '14 at 04:00
  • Yes, you can use `@Html.DropDownListFor(m => m.SomeInt, Model.SomeSelectList)` but never use `foreach` if your generating controls - all the controls will have duplicate `id` (invalid html) and `name` attributes so they cannot be bound to a collection. It should always be `for(int i = 0; i < Model.MyCollection.Count; i++) { @Html.TextBoxFor(m => m.MyCollection[i].SomeProperty) ...}` –  Dec 08 '14 at 04:04
2

the ajax call has wrong contentType, it should be something like

var data = { paramJson: JSON.stringify($form.serializeArray()) };

var options = {

    contentType: "text/plain",
    url: "/Form/Save",
    data: JSON.stringify(data),
    type: "post",
    datatype: "html",
    success: function (result, xhr, status) {
        console.log(result);
    },
    error: function (xhr, status, error) {
        // redirect to error page
    }
};

$.ajax(options);
0

well, I did try all of the above solutions but what worked for me is one option "traditional:true" in ajax call. follow the code below;

var Fixtures = [2,3,4]; var UnitViews = [4,3,6,8];

        $.ajax({
        url: '/RHomes/umbraco/surface/Propertysurface/GetPropertiesBL',
        async: false,
        type: "GET",
        data: {
            iServiceId: serviceid, iLocationID: locationid, 
            iCategoryId: categoryid, iTypeId: propertyTypeid,
            idevhold: developmentHold, iminbed: minBedRoom, 
            imaxbed: maxBedRom, iminPrice: minPrice, 
            fixtures: Fixtures, imaxPrice: maxPrice, 
            views: UnitViews
        },
        dataType: "html",
        traditional: true,
        contentType: "application/json",
        error: function (data) {
            alert(data.value);
        },
        success: function (data, textStatus, jqXHR) {
            //alert(criteria + 'success...' + data);
            console.log(data);
            $("#ResultContainer").empty().append(data);
        }
    }); 

Hope that helps somebody.