I have an MVC form set up like this:
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "createForm"}))
{
@Html.Partial("_Action", Model)
<div class="form-group">
<button type="button" id="createButton" class="btn btn-primary">@Resources.Global.CreateActionButton</button>
</div>
}
Here's the code of the partial:
@model EWI_JOPWeb.Models.ActionsViewModel
@Html.AntiForgeryToken()
<div class="form-group">
@Html.HiddenFor(m => m.Action.Id)
</div>
<div class="form-group">
@Html.LabelFor(m => m.Action.Number)
@Html.TextBoxFor(m => m.Action.Number, new { @class = "form-control", type = "number", placeholder = "Vul hier een nummer in" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Action.Title)
@Html.TextBoxFor(m => m.Action.Title, new { @class = "form-control", placeholder = "Vul hier tekst in" })
</div>
<div class="form-group">
@Html.LabelFor(m => m.Action.DepartmentNumber)
@Html.DropDownListFor(m => m.Action.DepartmentNumber, Model.DepartmentSelectItems, new { @class = "form-control selectpicker noBoxShadow", title = "Selecteer opties...", data_selected_text_format = "count > 0", multiple = "multiple" })
</div>
<!-- Other similar controls -->
Following code is used to submit to a controller:
$("#createButton").click(function() {
$.ajax({
url: '@Url.Action("CreateAction", "Home")?spHostUrl=' + getSPHostUrlFromQueryString(window.location.search),
dataType: "json",
data: { viewModel: $("#createForm").serialize() },
cache: false,
type: "POST",
success: function (response) {
//show successMessage
},
error: function (jqXhr, textStatus, errorThrown ) {
//show errorMessage
}
});
});
And of course the controller/viewmodel code:
[HttpPost]
[SharePointContextFilter]
public ActionResult CreateAction(ActionsViewModel viewModel)
{
//process 'viewModel'
}
public class ActionsViewModel
{
public IEnumerable<DepartmentViewModel> Departments { get; set; }
public Action Action { get; set; }
public IEnumerable<SelectListItem> TypeSelectItems => new[]
{
new SelectListItem { Value = "Beheersactie", Text = @"Beheersactie", Selected = true },
new SelectListItem { Value = "Beleidsactie", Text = @"Beleidsactie", Selected = false }
};
public IEnumerable<SelectListItem> DepartmentSelectItems { get; set; }
public IEnumerable<SelectListItem> PolicyDocumentSelectItems { get; set; }
public IEnumerable<SelectListItem> BudgetArticleSelectItems { get; set; }
public IEnumerable<SelectListItem> MonitoringSelectItems { get; set; }
}
The result of $("#createForm").serialize()
is similar to:
__RequestVerificationToken=D71hJi2rti_r2nyqi5KLg1iYnUHIMoVizjoR5ru2fsVa4CAhRTr-3dqi9bzdWZGlE2fNZReSIzySm_B2gtmbubPWaIchekaTmOdyerwahD01&Action.Id=&Action.Number=23&Action.Title=test&Action.DepartmentNumber=f4663eb2-e9b1-4aea-a7e9-b1b49eb100a7
But when the debugger hits the controller method, viewModel
remains null.
I have searched and tried solutions from following other questions:
- How to post the viewmodel to action method using JQUERY AJAX in MVC
- MVC3 Passing ViewModel to controller method using JQuery Ajax
- "Invalid JSON primitive" in Ajax processing
- How to serialize model, pass it to MVC controller in ajax request
But none of these solutions have worked for me.
Now I changed my code and added variables for the selected items and such:
public string SelectedType { get; set; }
public List<string> SelectedDepartment { get; set; }
public List<string> SelectedPolicyDocuments { get; set; }
public List<string> SelectedBudgetArticles { get; set; }
public List<string> SelectedMonitorings { get; set; }
And in my markup I adjusted this to:
@Html.DropDownListFor(m => m.SelectedMonitorings,
new MultiSelectList(Model.MonitoringSelectItems, "Id", "Title", Model.SelectedMonitorings),
new { @class = "form-control selectpicker noBoxShadow",
title = "Selecteer opties...",
data_selected_text_format = "count > 0",
multiple = "multiple" })
The viewmodel is not null anymore but on the other hand, the selected values are not coming through. If I select one or more items from the MultiSelect, the SelectedXXX list has always 1 item with no value.
Does anyone have any idea what is the correct way to reconstruct the ViewModel from a jQuery AJAX call to the Controller method? I am kind of list because there are several ways and combinations to achieve this.