With this Contact model
public class Contact
{
public string Name { get; set; }
public ICollection<Phone> Phones { get; set; }
public Phone PrimaryPhone
{
get { return Phones.FirstOrDefault(x => x.Primary) ?? new Phone(); }
}
}
public class Phone
{
public bool Primary { get; set; }
public string PhoneNumber { get; set; }
public string Type { get; set; }
}
And this controller
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(Contact contact)
{
return View();
}
}
When I POST to the HomeController Index using jQuery
(function ($) {
var myData = {
Name: 'Wesley Crusher',
Phones: [
{ Primary: false, PhoneNumber: '111-111-1111', Type: 'Business' },
{ Primary: true, PhoneNumber: '222-222-2222', Type: 'Personal' },
{ Primary: false, PhoneNumber: '333-333-3333', Type: 'Business' }
],
PrimaryPhone: { Primary: true, PhoneNumber: '111-111-1111', Type: 'Business' }
};
$.ajax({
url: '@Url.Action("Index", "Home")',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(myData)
});
})(jQuery)
The model binder incorrect builds up the ICollection Phones. The data is:
The PhoneNumber "111-111-1111" is repeated and the Type is "Business" instead of "Personal". Is this expected behavior for some reason or is this a bug?
I can post a sample project if you'd like, let me know.
I reckon posting the PrimaryPhone
is causing the problem. Try removing
PrimaryPhone: { Primary: true, PhoneNumber: '111-111-1111', Type: 'Business' }
As this property has only a getter, and would correctly be determined by the Primary
property, it should still have valid data.
I think it's because it's not a primitive. It's a complex object so the model binder tries to set its properties.
Model binding is better suited to binding against "input models" which represent the input coming in from the form. Having calculated properties with business logic on the input model might not be the best approach as you saw.
You could probably have that be an extension method (sadly no support for extension properties) rather than a property of your input model. Or even a proper method. Having it be a property makes the model binder think it's fair game.
If it was a get only primitive type, it wouldn't try to set it.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.