Visual studio 使用实体数据模型自定义验证MVC 3
我正在使用MVC3进行一个项目。我首先创建了一个数据库(带有必要的约束,如PK和FK),并使用ADO.NET实体数据模型将该数据库添加到我的WebApplicatione中。一切似乎都很好,但我无法灵活地进行验证。这里有一些代码来澄清我的问题Visual studio 使用实体数据模型自定义验证MVC 3,visual-studio,asp.net-mvc-3,entity-framework,validation,Visual Studio,Asp.net Mvc 3,Entity Framework,Validation,我正在使用MVC3进行一个项目。我首先创建了一个数据库(带有必要的约束,如PK和FK),并使用ADO.NET实体数据模型将该数据库添加到我的WebApplicatione中。一切似乎都很好,但我无法灵活地进行验证。这里有一些代码来澄清我的问题 编辑:添加视图+正确的模型。此版本未导入数据库,但结果相同 --模型---- namespace CustomValidation.Models { 公共类人物:IValidatableObject { 公共int Id{get;set;} [必
编辑:添加视图+正确的模型。此版本未导入数据库,但结果相同
--模型----
namespace CustomValidation.Models
{
公共类人物:IValidatableObject
{
公共int Id{get;set;}
[必需]
公共字符串名{get;set;}
[必需]
公共字符串LastName{get;set;}
公共IEnumerable验证(ValidationContext ValidationContext)
{
if(String.IsNullOrEmpty(FirstName))
{
var field=new[]{“FirstName”};
返回新的ValidationResult(“Firstname不能为null”,字段);
}
}
}
}
命名空间CustomValidation.Models
{
公共类地址:IValidatableObject
{
公共int Id{get;set;}
[必需]
公共字符串Streetname{get;set;}
[必需]
公共字符串Zipcode{get;set;}
[必需]
公共字符串City{get;set;}
[必需]
公共字符串国家{get;set;}
公众人物{get;set;}
公共IEnumerable验证(ValidationContext ValidationContext)
{
if(String.IsNullOrEmpty(Streetname))
{
var field=new[]{“Streetname”};
返回新的ValidationResult(“Streetname不能为空”,字段);
}
}
}
}
公共类主模型
{
公共列表地址{get;set;}
公众人物{get;set;}
}
}
命名空间CustomValidation.Models
{
公共类DBEntities:DbContext
{
公共数据库集人物{get;set;}
公共数据库集地址{get;set;}
}
}
----控制器----
namespace CustomValidation.Controllers
{
公共类HomeController:控制器
{
公共行动结果索引()
{
主模型=新的主模型();
Model.Person=newperson();
Model.address=新列表();
Model.Address.Add(新地址());
Model.Address.Add(新地址());
返回视图(模型);
}
[HttpPost]
公共行动结果指数(主模型)
{
DBEntities _db=新的DBEntities();
if(TryValidateModel(Model.Person))
{
_db.People.Add(Model.Person);
_db.SaveChanges();
}
其他的
{
返回视图(模型);
}
for(int i=0;i
以下是我的看法:
@model CustomValidation.Models.MasterModel
@{
ViewBag.Title = "Index";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Person</legend>
<div class="editor-label">
@Html.LabelFor(m => Model.Person.FirstName)
@Html.EditorFor(m => Model.Person.FirstName)
</div>
<div class="editor-label">
@Html.LabelFor(m => Model.Person.LastName)
@Html.EditorFor(m => Model.Person.LastName)
</div>
</fieldset>
for (int i = 0; i < Model.Addressess.Count; i++)
{
<fieldset>
<legend>Address</legend>
<div class="editor-label">
@Html.LabelFor(model => Model.Addressess[i].Streetname)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Addressess[i].Streetname)
@Html.ValidationMessageFor(model => Model.Addressess[i].Streetname)
</div>
<div class="editor-label">
@Html.LabelFor(model => Model.Addressess[i].Zipcode)
</div>
<div class="editor-field">
@Html.EditorFor(model => Model.Addressess[i].Zipcode)
@Html.ValidationMessageFor(model => Model.Addressess[i].Zipcode)
</div>
<div class="editor-label">
@Html.LabelFor(model => Model.Addressess[i].City)
</div>
<div class="editor-field">
@Html.EditorFor(model => Model.Addressess[i].City)
@Html.ValidationMessageFor(model => Model.Addressess[i].City)
</div>
<div class="editor-label">
@Html.LabelFor(model => Model.Addressess[i].Country)
</div>
<div class="editor-field">
@Html.EditorFor(model => Model.Addressess[i].Country)
@Html.ValidationMessageFor(model => Model.Addressess[i].Country)
</div>
</fieldset>
}
<p>
<input type="submit" value="Create" />
</p>
}
@model CustomValidation.Models.MasterModel
@{
ViewBag.Title=“Index”;
}
创造
@使用(Html.BeginForm()){
@Html.ValidationSummary(true)
人
@LabelFor(m=>Model.Person.FirstName)
@EditorFor(m=>Model.Person.FirstName)
@LabelFor(m=>Model.Person.LastName)
@EditorFor(m=>Model.Person.LastName)
for(int i=0;imodel.address[i].Streetname)
@Html.EditorFor(model=>model.address[i].Streetname)
@Html.ValidationMessageFor(model=>model.address[i].Streetname)
@Html.LabelFor(model=>model.address[i].Zipcode)
@Html.EditorFor(model=>model.address[i].Zipcode)
@Html.ValidationMessageFor(model=>model.address[i].Zipcode)
@Html.LabelFor(model=>model.address[i].City)
@EditorFor(model=>model.address[i].City)
@Html.ValidationMessageFor(model=>model.address[i].City)
@Html.LabelFor(model=>model.address[i].Country)
@Html.EditorFor(model=>model.address[i].Country)
@Html.ValidationMessageFor(model=>model.address[i].Country)
}
}
问题(我在调试类似的东西时注意到)是,在请求进入我的操作之前,MVC首先为您的集合运行验证器。因此,如果我在表单中只填写了Person,则在验证模型时。Person只返回false(我猜是因为地址的必填字段)所以它会回到我的观点
我需要一些变通方法,让我能够决定要在操作中验证集合的哪些实例
在网上搜索了很长时间后,我一直找不到任何解决方案
我希望有人能帮助我
另外,我是Visual Studio和MVC 3的新手,所以请不要对我太苛刻:)为了验证返回到您的操作的模型的子模型,您需要将
TryValidateModel
应用到特定的子模型,并使用包含模型前缀的重载。如果查看生成的HTML,您将请参阅Person字段的前缀为Person
,第一个地址字段的前缀为Addressess[0]
,第二个地址字段的前缀为Addressess[1]
此外,在调用TryValidateModel之前,必须清除所有模型错误(否则现有错误将导致TryValidateModel返回false)
请执行以下操作:
[HttpPost]
public ActionResult Index(MasterModel model)
{
var reloadView = true;
// clear any existing errors
foreach (var key in ModelState.Keys)
ModelState[key].Errors.Clear();
if (TryValidateModel(model.Person, "Person"))
{
_db.People.Add(model.Person);
_db.SaveChanges();
reloadView = false;
for (var i = 0; i < model.Addressess.Count(); i++)
{
foreach (var key in ModelState.Keys)
ModelState[key].Errors.Clear();
if (TryValidateModel(model.Addressess[i], "Addressess[" + i.ToString() + "]"))
{
**// UPDATED CODE**
// add Person to Address model
model.Addressess[i].Person = model.Person;
_db.Addressess.Add(model.Addressess[i]);
_db.SaveChanges();
}
}
}
if (reloadView)
{
// clear and re-add all errors
foreach (var key in ModelState.Keys)
ModelState[key].Errors.Clear();
TryValidateModel(model);
return View(model);
}
else
{
// go to some other view
}
}
[HttpPost]
公共行动结果
@model CustomValidation.Models.MasterModel
@{
ViewBag.Title = "Index";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Person</legend>
<div class="editor-label">
@Html.LabelFor(m => Model.Person.FirstName)
@Html.EditorFor(m => Model.Person.FirstName)
</div>
<div class="editor-label">
@Html.LabelFor(m => Model.Person.LastName)
@Html.EditorFor(m => Model.Person.LastName)
</div>
</fieldset>
for (int i = 0; i < Model.Addressess.Count; i++)
{
<fieldset>
<legend>Address</legend>
<div class="editor-label">
@Html.LabelFor(model => Model.Addressess[i].Streetname)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Addressess[i].Streetname)
@Html.ValidationMessageFor(model => Model.Addressess[i].Streetname)
</div>
<div class="editor-label">
@Html.LabelFor(model => Model.Addressess[i].Zipcode)
</div>
<div class="editor-field">
@Html.EditorFor(model => Model.Addressess[i].Zipcode)
@Html.ValidationMessageFor(model => Model.Addressess[i].Zipcode)
</div>
<div class="editor-label">
@Html.LabelFor(model => Model.Addressess[i].City)
</div>
<div class="editor-field">
@Html.EditorFor(model => Model.Addressess[i].City)
@Html.ValidationMessageFor(model => Model.Addressess[i].City)
</div>
<div class="editor-label">
@Html.LabelFor(model => Model.Addressess[i].Country)
</div>
<div class="editor-field">
@Html.EditorFor(model => Model.Addressess[i].Country)
@Html.ValidationMessageFor(model => Model.Addressess[i].Country)
</div>
</fieldset>
}
<p>
<input type="submit" value="Create" />
</p>
}
[HttpPost]
public ActionResult Index(MasterModel model)
{
var reloadView = true;
// clear any existing errors
foreach (var key in ModelState.Keys)
ModelState[key].Errors.Clear();
if (TryValidateModel(model.Person, "Person"))
{
_db.People.Add(model.Person);
_db.SaveChanges();
reloadView = false;
for (var i = 0; i < model.Addressess.Count(); i++)
{
foreach (var key in ModelState.Keys)
ModelState[key].Errors.Clear();
if (TryValidateModel(model.Addressess[i], "Addressess[" + i.ToString() + "]"))
{
**// UPDATED CODE**
// add Person to Address model
model.Addressess[i].Person = model.Person;
_db.Addressess.Add(model.Addressess[i]);
_db.SaveChanges();
}
}
}
if (reloadView)
{
// clear and re-add all errors
foreach (var key in ModelState.Keys)
ModelState[key].Errors.Clear();
TryValidateModel(model);
return View(model);
}
else
{
// go to some other view
}
}