Проверка asp.net MVC 3 для поля Id сначала с кодом EF

У меня есть следующая модель:

public class Product
{
  [Key]
  [HiddenInput(DisplayValue = false)]
  public int Id { get; set; }

  [Required]
  [StringLength(10)]
  public string ProductCode { get; set; }

  [Required]
  [StringLength(40)]
  public string ProductName { get; set; }
}

и следующую пару методов Add в контроллере:

[HttpGet]
public ActionResult Add()
{
  return View();
}

[HttpPost]
[ValidateInput(false)]
[ValidateAntiForgeryToken]
public ActionResult Add(Product product)
{
  productRepository.Add(product);

  return RedirectToAction("Index");
}

Это вид Добавить:

@using Models
@model Product

<h2>Add Product</h2>

@using (@Html.BeginForm("Add", "Home")) {
  @Html.AntiForgeryToken()
  @Html.EditorForModel()
  <input type="submit" id="btnSubmit" value="Submit"/>
}

Все отображается просто отлично, к сожалению, я не могу отправить форму. Мне потребовалось некоторое время, чтобы понять, что поле Id проверяется. Действительно, если я удалю HiddenInput атрибут, я могу видеть при отправке, что он говорит мне, что поле Id является обязательным.

Есть ли способ пометить его как не обязательный при использовании EditorForModel()?

2 ответа

Решение

Если вы должны сохранить первичный ключ как часть модели, вам нужно переопределить значение по умолчанию для DataAnnotationsModelValidatorProvider что типы значений являются обязательными. Добавьте следующее в метод Application_Start в Global.asax.cs:

ModelValidatorProviders.Providers.Clear(); 
ModelValidatorProviders.Providers.Add(new DataAnnotationsModelValidatorProvider());
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

Вам следует рассмотреть возможность использования моделей представлений вместо отправки ваших доменных сущностей в качестве моделей для представлений.

public class ProductAddModel
{
  [Required]
  [StringLength(10)]
  public string ProductCode { get; set; }

  [Required]
  [StringLength(40)]
  public string ProductName { get; set; }
}

Затем используйте такой инструмент, как AutoMapper, чтобы сопоставить модель представления с моделью вашего домена.

[HttpPost]
[ValidateInput(false)]
[ValidateAntiForgeryToken]
public ActionResult Add(ProductAddModel productAddModel)
{
  if (ModelState.IsValid)
  {
      Product product = Mapper.Map<ProductAddModel, Product>(productAddModel);

      productRepository.Add(product);
  }

  return RedirectToAction("Index");
}
Другие вопросы по тегам