0

I need to pass my model, built in this form:

using (Ajax.BeginForm("Index", null, new AjaxOptions() { UpdateTargetId = "FormContainer", HttpMethod = "Post", InsertionMode = InsertionMode.Replace, OnSuccess = "successFunc" }, new { id = "UpdateForm" }))

To this method:

public ActionResult SavePreset(DocumentFilterModel model, string name)
{
    //Do some magic
    return PartialView("Partial/FilterListPartial", model);
}

The point is that by default, this form will collect report presets, however i need to add and option to save preset in my DB, that is why SavePreset method is needed.

I have tried to use this script:

$("#SavePresetButton").on("click", function () {
$.ajax({
    type: "POST",
    url: '@Url.Action("SavePreset", "Reports")',
    data: {
        name: $("#PresetNameEditor").val(),
        model: $("#UpdateForm").serialize()
    }
    }).success(function(result) {
        $("#FilterSettingsContainer").html(result);
    });
});

But i have encountered a problem, where i either get null in DocumentFilterModel model either (if change model parametr's type to string) can't deserialize it. Things i have tried:

var SettingsModel = new JavaScriptSerializer().Deserialize<DocumentFilterModel>(model);
var a =  JsonConvert.DeserializeObject<DocumentFilterModel>(model);

By the way, (these filters located in separate partial view) i would like to keep my form as it is, because i still need to update my second partial view with lists of record, and DocumentFilterModel is too big to parse it manually.

2
  • You do not need to deserialize explicitly. Let the model binder does it's job. How does your DocumentFilterModel looks like ? How are you rendering the input elements inside the form ? Commented Nov 6, 2017 at 15:44
  • The problem is that inside DocumentFilterModel is about 70+ properties (10 right inside an object and it contains 6 different object with 10 properties each), that is why parsing it manually is an option i want to avoid at any cost. Editors are created using ViewData.ModelMetadata.Properties list, that is why i didn't include the code inside my form. And i can't use submit, because preset saving method must return partial view with filters and submit must return partial with records (the conflict inside UpdateTargetId property). Commented Nov 6, 2017 at 15:52

1 Answer 1

1

The serialize method reads your form and generates a url encoded string with your input element names and values. So basically it will be a big querystring. When you pass that as the data property of the $.ajax call, jquery will use that for the request body (like FormData)

So when you try something like this

data:{
        name: $("#PresetNameEditor").val(),
        model: $("#UpdateForm").serialize()
     }

It it trying to send an object like this

{name: "Abc", model: "FirstName=Scott&Email=someEmail"}

You can see that you have a js object with 2 properties and the second property has all your input values in a query string format. The model binder cannot read this data and map to your DocumentFilterModel object!.

You cannot mix the result of serialize method to build a js object you want to send as data.

Simply use the result of serialize as the data property value of the ajax call and pass name in querystring.

$("#SavePresetButton").on("click", function () {
    $.ajax({
        type: "POST",
        url: '@Url.Action("SavePreset", "Reports")?name='+$("#PresetNameEditor").val(),
        data: $("#UpdateForm").serialize()
    }).done(function(result) {
        console.log(result);
    });
});
Sign up to request clarification or add additional context in comments.

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.