【发布时间】:2014-09-23 16:58:19
【问题描述】:
我的 ASP.NET MVC 应用程序中有一个简单的模型,我希望对作为类的属性进行验证。我查看了 ScottGu 的博客 here 关于类级验证,但是当在上下文中调用 SaveChanges() 时会发生验证,这是我不想要的。我希望它的反应就像您在提交表单时使用 DataAnnotations 获得的验证一样。
这是我的模型:
public class SignupModel
{
[Display(Name = "Company Name")]
[Required(ErrorMessage = "Company Name Required")]
public string CompanyName { get; set; }
[Display(Name = "Company Type")]
[Required(ErrorMessage = "Company Type Required")]
public int SelectedCompanyTypeId { get; set; }
[Display(Name = "Requested Services")]
[Required(ErrorMessage = "At least 1 service is required")]
public PostedServicesOffered PostedServices { get; set; }
public IEnumerable<ServicesOffered> ServicesOffered { get; set; }
public IEnumerable<ServicesOffered> SelectedServicesOffered { get; set; }
public IEnumerable<SelectListItem> CompanyTypes { get; set; }
}
PostedServicesOffered 对象是一个具有一个属性的简单类:
public class PostedServicesOffered
{
public string[] ServiceOfferedIds { get; set; }
}
这是控制器:
public ActionResult Index()
{
SignupModel model = new SignupModel()
{
CompanyTypes = SelectCompanyType(),
ServicesOffered = GetServicesOffered(),
SelectedServicesOffered = new List<ServicesOffered>(),
PostedServices = new PostedServicesOffered()
};
ViewBag.BannerText = "Sign Up Form";
return View(model);
}
[HttpPost]
public ActionResult Index(SignupModel model)
{
if (ModelState.IsValid)
{
}
return View(GetSignupModel(model));
}
private SignupModel GetSignupModel(SignupModel model)
{
SignupModel signupModel = new SignupModel();
var selectedServices = new List<ServicesOffered>();
var postedServicesOfferedIds = new string[0];
if (model.PostedServices == null)
model.PostedServices = new PostedServicesOffered();
// if a view model array of posted services ids exists
// and is not empty,save selected ids
if (model.PostedServices.ServiceOfferedIds != null && model.PostedServices.ServiceOfferedIds.Any())
postedServicesOfferedIds = model.PostedServices.ServiceOfferedIds;
//If there are any selected ids saved, create a list of ServicesOffered.
if (postedServicesOfferedIds.Any())
selectedServices = GetServicesOffered()
.Where(x => postedServicesOfferedIds.Any(s => x.ServicesOfferedId.ToString().Equals(s)))
.OrderBy(x => x.ServiceName)
.ToList();
signupModel.CompanyTypes = SelectCompanyType();
signupModel.ServicesOffered = GetServicesOffered();
signupModel.SelectedServicesOffered = selectedServices;
signupModel.PostedServices = model.PostedServices;
signupModel.SelectedCompanyTypeId = model.SelectedCompanyTypeId;
return signupModel;
}
private IEnumerable<ServicesOffered> GetServicesOffered()
{
return Repository.GetServicesOffered(new UnitOfWork()).OrderBy(so => so.ServiceName);
}
private IEnumerable<SelectListItem> SelectCompanyType()
{
List<SelectListItem> items = new List<SelectListItem>();
var companyTypes = Repository.GetCompanyTypes(new UnitOfWork()).OrderBy(ct => ct.CompanyType1);
foreach (CompanyType companyType in companyTypes)
items.Add(new SelectListItem()
{
Text = companyType.CompanyType1,
Value = companyType.CompanyTypeId.ToString()
});
return items;
}
和视图:
<div id="contact-form" class="contatct-form">
<h4 class="classic-title"><span>Registration</span></h4>
@using (Html.BeginForm())
{
<div class="validation-text">
<h5>@Html.ValidationSummary()</h5>
</div>
<div class="row padBtm-20">
<div class="col-md-4">
@Html.LabelFor(x => x.CompanyName)
@Html.TextBoxFor(x => x.CompanyName, new { placeholder = "Company Name..." })
</div>
<div class="col-md-4">
@Html.LabelFor(x => x.SelectedCompanyTypeId)
@Html.DropDownListFor(x => x.SelectedCompanyTypeId, Model.CompanyTypes)
@Html.HiddenFor(x => x.SelectedCompanyTypeId, new { value = Model.SelectedCompanyTypeId })
</div>
<div class="col-md-4">
@Html.LabelFor(model => model.PostedServices)<br />
@*@Html.CheckBoxListFor(model => model.PostedServices.ServiceOfferedIds,
model => model.ServicesOffered,
service => service.ServicesOfferedId,
service => service.ServiceName,
model => model.SelectedServicesOffered,
Position.Vertical)*@
@Html.CheckBoxListFor(model => model.PostedServices,
model => model.ServicesOffered,
service => service.ServicesOfferedId,
service => service.ServiceName,
model => model.SelectedServicesOffered,
Position.Vertical)
</div>
</div>
<div class="row padBtm-20"></div>
<input type="submit" class="button" value="Send Message" />
}
</div>
简而言之,ServicesOffered 属性是显示为复选框的服务列表。我正在使用一个名为 MvcCheckBoxList 的 NeGut 包(找到 here),它基于列表创建一组复选框。
发生的情况是,当我点击Submit 并选中no 复选框时,表单首先验证其他属性并显示那些错误消息first。只有在这些字段通过验证并发布表单后,PostedServices 字段才会通过验证并显示错误。如何在不发布所有其他属性的情况下对其进行验证?
【问题讨论】:
-
您想对复选框执行什么类型的验证?您也应该能够将数据注释添加到列表中。如果您的验证更复杂,那么您始终可以让模型实现
IValidatableObject -
在生成的所有复选框中,至少需要选中1个。我试图让模型从
IValidatableObject继承,但是当按下提交按钮时,Validate事件永远不会触发。
标签: asp.net asp.net-mvc validation data-annotations