Reputation: 2997
I have a view that I'm binding with knockoutjs. I need to add data dynamically to a list in the viewmodel using ajax post.
var data = {
model: ko.toJS(self.Model),
name: name
}
$.ajax({
url: options.url + "AddAdvantage",
type: 'POST',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(data),
traditional: true,
success: function (data) {
self.UpdateOnChange = false;
ko.mapping.fromJS(data, self.Model);
self.UpdateOnChange = true;
}
});
when the data parameter is passed to the controller action:
[HttpPost]
public JsonResult AddAdvantage([ModelBinder(typeof(AdvantageModelBinder))] AdvantageViewModel model, string name) {
}
name value is passed, but model is always null
I have tried this:
var data = {
model: ko.toJSON(self.Model),
name: name
}
also tried:
var data = JSON.stringify({
model: ko.toJSON(self.Model),
name: name
});
same result.
this works fine:
$.ajax({
url: options.url + "AddAdvantage",
type: 'POST',
dataType: 'json',
contentType: 'application/json',
data: ko.toJSON(self.Model),
traditional: true,
success: function (data) {
self.UpdateOnChange = false;
ko.mapping.fromJS(data, self.Model);
self.UpdateOnChange = true;
}
});
My ModelBinder
public class AdvantageModelBinder: DefaultModelBinder
{
public AdvantageModelBinder()
{
}
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
ValueProviderResult value = bindingContext.ValueProvider.GetValue("WizardType");
Type typeByTypeName = AdvantageModelBinder.GetTypeByTypeName((string)value.ConvertTo(typeof(string)));
object obj = Activator.CreateInstance(typeByTypeName);
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => obj, typeByTypeName);
return obj;
}
public static Type GetTypeByTypeName(string typeName)
{
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
for (int i = 0; i < (int)assemblies.Length; i++)
{
Type type = assemblies[i].GetType(typeName, false, true);
if (type != null)
{
return type;
}
}
throw new ArgumentException("Can't find the specified type in the loaded assemblies.", typeName);
}
}
can anyone tell how to fix this?
Upvotes: 0
Views: 6634
Reputation: 5085
Try this:
var data = {
model: self.Model,
name: name
}
$.ajax({
url: options.url + "AddAdvantage",
type: 'POST',
dataType: 'json',
contentType: 'application/json',
data: ko.toJSON(data),
traditional: true,
success: function (data) { ... }
});
Upvotes: 0
Reputation: 770
Seems that you're not passing exactly the same object in the payload.
Let's say that your model object is like this:
{
foo: 1,
bar: 2
}
On the first two samples you are creating this object:
{
model: {
foo: 1,
bar: 2
},
name: "whatever"
}
So, when you pass it as an argument to the ajax call you're passing an object that is not expected on the MVC side.
If you want to store it in a variable, you need to do the following:
var data = ko.toJSON(self.model)
And make the ajax call doing this:
$.ajax({
url: options.url + "AddAdvantage",
type: 'POST',
dataType: 'json',
contentType: 'application/json',
data: data,
traditional: true,
success: function (data) {
self.UpdateOnChange = false;
ko.mapping.fromJS(data, self.Model);
self.UpdateOnChange = true;
}
});
Upvotes: 1