Я использую валидатор аннотаций данных, описанный здесь:
http://www.asp.net/learn/mvc/tutorial-39-cs.aspx
Связыватель модели аннотаций данных находится в кодовом комплексе:
http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471
Я скачал код, собрал его и сослался на новый файл System.ComponentModel.DataAnnotations.dll. Я также установил привязку модели по умолчанию для использования Microsoft.Web.Mvc.DataAnnotations.dll. Он отлично работает при привязке к простому объекту (например, Order), но если я связываюсь с Order, имеющим объект CreditCard, я получаю сообщение об ошибке в новом связывателе:
Ссылка на объект не установлена для экземпляра объекта, DataAnnotationsModelBinder.cs Строка: 60.
В моем примере fullPropertyKey имеет значение "Card", а modelState имеет значение null, поэтому очевидно, что имеется проблема со свойством Card для Order.
ModelState modelState = bindingContext.ModelState[fullPropertyKey];
// Only validate and bind if the property itself has no errors
if (modelState.Errors.Count == 0) {
if (OnPropertyValidating(controllerContext, bindingContext, propertyDescriptor, newPropertyValue)) {
SetProperty(controllerContext, bindingContext, propertyDescriptor, newPropertyValue);
OnPropertyValidated(controllerContext, bindingContext, propertyDescriptor, newPropertyValue);
}
}
Поддерживает ли это связка аннотаций данных? Привязка акций не имеет проблем со структурой Order -> CreditCard (за исключением проверки, конечно). Тестовый код:
Контроллер и модель:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.ComponentModel.DataAnnotations;
namespace PAW.Controllers
{
//MODEL
public class Order
{
[Required]
[DataType(DataType.Text)]
[StringLength(5)]
public string CustomerName { get; set; }
public CreditCard Card { get; set; }
public Order()
{
this.Card = new CreditCard();
}
}
public class CreditCard
{
[StringLength(16), Required]
public string Number { get; set; }
}
//CONTROLLER
public class TestController : Controller
{
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index()
{
return View(new Order());
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(Order o)
{
if (ModelState.IsValid)
{
//update
}
return View(o);
}
}
}
Вид:
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<PAW.Controllers.Order>" %>
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<% using(Html.BeginForm()) { %>
<%=Html.ValidationSummary("Errors: ") %>
<div>
Name (max 5 chars): <%=Html.TextBox("CustomerName", Model.CustomerName)%>
</div>
<div>
CC#: <%=Html.TextBox("Card.Number", Model.Card.Number)%>
</div>
<input type="submit" value="submit" />
<% } %>
</body>
</html>