asp.net mvc 3 validation for Id field with EF code first
I have the following model:
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; }
}
and the following pair of Add methods in the controller:
[HttpGet]
public ActionResult Add()
{
return View();
}
[HttpPost]
[ValidateInput(false)]
[ValidateAntiForgeryToken]
public ActionResult Add(Product product)
{
productRepository.Add(product);
return RedirectTo开发者_StackOverflowAction("Index");
}
This is the Add view:
@using Models
@model Product
<h2>Add Product</h2>
@using (@Html.BeginForm("Add", "Home")) {
@Html.AntiForgeryToken()
@Html.EditorForModel()
<input type="submit" id="btnSubmit" value="Submit"/>
}
Everything is displayed just fine, unfortunately I am unable to submit the form. It took me a while to figure out that the Id field gets validated. Indeed, if I remove the HiddenInput
attribute, I can see on submitting that it tells me the Id field is required.
Is there a way to mark it as not required while still using EditorForModel()
?
If you must keep the primary key as part of the model, then you need to override the default for DataAnnotationsModelValidatorProvider
that value types are required. Add the following to the Application_Start method in Global.asax.cs
:
ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(new DataAnnotationsModelValidatorProvider());
DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
You should consider using view models instead of sending your domain entities as models to views.
public class ProductAddModel
{
[Required]
[StringLength(10)]
public string ProductCode { get; set; }
[Required]
[StringLength(40)]
public string ProductName { get; set; }
}
Then use a tool like AutoMapper to map the viewmodel back to your domain model
[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");
}
精彩评论