【发布时间】:2016-04-13 09:02:30
【问题描述】:
我查看了许多关于此主题的帖子 - 自定义服务器端验证 - here 和 here 和 here(我相信这是针对 MVC4),但似乎没有一个为我解决这个问题。
我创建了一个基本的 MVC6 项目(两个文本框)只是为了测试数据注释,但仍然无法使其工作。作为基础,我使用tutorial 并重新创建了他的数据验证类,没有任何更改。
我没有使用实际模型,而是使用 viewModel,如果验证成功,则通过分配给模型来更新数据库。
我对此处的成功验证不感兴趣,但是否在“(ModelState.IsValid)”等于“False”时,它会在文本框下显示错误消息。
我已经单步执行了它,发现它确实单步执行了实际的自定义验证器,并且它肯定在自定义验证中给出了 false 的模型状态 - 返回视图 - 但没有显示错误消息。
但是,如果我从文本框中删除所有内容 - 将其设为空 - 返回视图模型,但这次它会出现红色的“必需”错误。也就是说,错误消息适用于数据注释而不是自定义注释。
好的,所以为什么它显示正常的注释验证错误而不是自定义验证错误?
这是 ASP.NET 核心的结果,还是只是我返回视图模型的方式(例如,我更有可能出错)?
我决定包括所有活动部分,因为其中任何一个可能不正确或存在问题。这就是一个模型、一个基于模型的视图模型、一个控制器和按照教程的自定义验证器类。
public class CompanyDetail
{
public int CompanyDetailId { get; set; }
public string CompanyName { get; set; }
public string ABN { get; set; }
}
添加了数据注释的 CompanyDetailViewModel:
public class CompanyDetailsViewModel
{
public int CompanyDetailsId { get; set; }
[ExcludeChar("/")]
[Required(ErrorMessage = "A Company Name is required")]
[Display(Name = "Company Name:")]
[StringLength(100)]
public string CompanyName { get; set; }
[Required(ErrorMessage = "An ABN is required")]
[CheckValidABN(ErrorMessage = "This is not a valid ABN")]
[Display(Name = "ABN:")]
public string ABN { get; set; }
}
控制器: 公共类 CompanyDetailsController : 控制器 { 私有 ApplicationDbContext _context;
public CompanyDetailsController(ApplicationDbContext context)
{
_context = context;
}
// GET: CompanyDetailsViewModels/Edit/5
public IActionResult Edit()
{
var Company = _context.CompanyDetails.First();
if (Company == null)
{
return HttpNotFound();
}
var CompanyDetails = new CompanyDetailsViewModel();
CompanyDetails.CompanyDetailsId = Company.CompanyDetailId;
CompanyDetails.CompanyName = Company.CompanyName;
CompanyDetails.ABN = Company.ABN;
return View(CompanyDetails);
}
// POST: CompanyDetailsViewModels/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(CompanyDetailsViewModel companyDetailsViewModel)
{
if (ModelState.IsValid)
{
CompanyDetail Company = _context.CompanyDetails.First();
var CompanyDetails = new CompanyDetailsViewModel();
Company.CompanyName = CompanyDetails.CompanyName;
CompanyDetails.ABN = Company.ABN;
_context.CompanyDetails.Update(Company);
_context.SaveChanges();
return RedirectToAction("Index");
}
return View(companyDetailsViewModel);
}
}
具有(普通脚手架)形式的视图 - 它使用视图模型作为模型:
<form asp-action="Edit">
<div class="form-horizontal">
<h4>CompanyDetailsViewModel</h4>
<hr />
<div asp-validation-summary="ValidationSummary.ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="CompanyDetailsId" />
<div class="form-group">
<label asp-for="ABN" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="ABN" class="form-control" />
<span asp-validation-for="ABN" class="text-danger" />
</div>
</div>
<div class="form-group">
<label asp-for="CompanyName" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="CompanyName" class="form-control" />
<span asp-validation-for="CompanyName" class="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
以及实际的自定义验证类:
public class ExcludeChar : ValidationAttribute
{
private readonly string _chars;
public ExcludeChar(string chars)
: base("{0} contains invalid character.")
{
_chars = chars;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value != null)
{
for (int i = 0; i < _chars.Length; i++)
{
var valueAsString = value.ToString();
if (valueAsString.Contains(_chars[i]))
{
var errorMessage = FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult(errorMessage);
}
}
}
return ValidationResult.Success;
}
}
【问题讨论】:
-
如果我将视图 cshtml 中的“”更改为“ValidationSummary.All”错误消息显示但仅在页面顶部 - 不在文本框下方。如果我清除文本框,则“requred”错误会显示在两个地方......由于某种原因,自定义验证仅显示摘要,并且仅在其设置为“全部”时显示
-
MVC6 是否存在此功能?
-
您不使用内置的 html 帮助程序是否有特定原因?
标签: asp.net-mvc validation asp.net-core-mvc data-annotations