Reputation: 3989
If my Model has a property List<MyType> MyProperty
(where MyType is a complex type), how can I pass this to a Controller Action?
e.g.
[HttpGet]
public ActionResult UpdateAll(List<MyType> thingy)
If I just use
Model.MyProperty
It turns up in the controller as null
I can't bend my mind round the examples I can find - but what I can pick up leads me to think I should state that my view is NOT based on an IEnumerable<MyType>
(nor can/should it be).
EDIT: what I want to do with it is
<a id="updateall" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" href="@Url.Action("UpdateAll", "MyController", new { area = "Operator", myproperty=Model.MyProperty})"><span class="ui-button-text">Update All</span></a>
EDIT2: Is it as simple as that I need to serialize it before passing it? But I'd have thought that would have very quickly come up as an answer/search result...
Upvotes: 0
Views: 119
Reputation: 4148
I have the data that is in my View in a javascript object. In case this is a direction you're going...
I have a toDictionary
method...
(function ($) {
$.extend({
toDictionary: function (data, prefix, includeNulls) {
/// <summary>Flattens an arbitrary JSON object to a dictionary that Asp.net MVC default model binder understands.</summary>
/// <param name="data" type="Object">Can either be a JSON object or a function that returns one.</data>
/// <param name="prefix" type="String" Optional="true">Provide this parameter when you want the output names to be prefixed by something (ie. when flattening simple values).</param>
/// <param name="includeNulls" type="Boolean" Optional="true">Set this to 'true' when you want null valued properties to be included in result (default is 'false').</param>
// get data first if provided parameter is a function
data = $.isFunction(data) ? data.call() : data;
// is second argument "prefix" or "includeNulls"
if (arguments.length === 2 && typeof (prefix) === "boolean") {
includeNulls = prefix;
prefix = "";
}
// set "includeNulls" default
includeNulls = typeof (includeNulls) === "boolean" ? includeNulls : false;
var result = [];
_flatten(data, result, prefix || "", includeNulls);
return result;
}
});
}
Here is my ajax call where roles
is a javascript Object()
:
var data = { roleGroups: roles };
$.ajax({
url: '/Controller/Action',
type: 'post',
dataType: 'json',
data: $.toDictionary(data)
})
And I'm then using a, IList
on the server...
[HttpPost]
public virtual ActionResult EditRoleGroups(IList<RoleGroupViewModel> roleGroups)
{
//do stuff
}
Upvotes: 0
Reputation: 82096
Lists are treated a little bit differently in MVC, in order to post data back from a list you need to first render the UI for each item in that list i.e.
@model MyComplexModel
@foreach (MyType item in Model.MyProperty)
{
@Html.EditorFor(x => item.SomeProperty)
@Html.EditorFor(x => item.AnotherProperty)
}
Using the *For
helpers will generate the appropriate HTML which allows the model binder to know which items in the list it is updating. If you inspect the DOM you should find the HTML for your list items looks something like
<input type="text" name="Model.MyProperty[0].SomeProperty" />
<input type="text" name="Model.MyProperty[0].AnotherProperty" />
<input type="text" name="Model.MyProperty[1].SomeProperty" />
<input type="text" name="Model.MyProperty[1].AnotherProperty" />
...
Upvotes: 2