Validation 未使用IValidatableObject显示自定义验证消息
我有一个简单的表单,有两个按钮(取消和提交)和一个文本区。用户键入电子邮件地址列表并按submit。我试图弄清楚为什么我提交表单时没有显示自定义消息。我知道验证逻辑在触发我的[Required]规则时起作用,我可以看到错误消息: 但是,当我输入“test@”等数据然后提交时,验证中的逻辑会被触发,但我看不到错误消息“请确保所有电子邮件都有效”。我做错了什么 这就是我的模型:Validation 未使用IValidatableObject显示自定义验证消息,validation,asp.net-core,asp.net-core-2.0,Validation,Asp.net Core,Asp.net Core 2.0,我有一个简单的表单,有两个按钮(取消和提交)和一个文本区。用户键入电子邮件地址列表并按submit。我试图弄清楚为什么我提交表单时没有显示自定义消息。我知道验证逻辑在触发我的[Required]规则时起作用,我可以看到错误消息: 但是,当我输入“test@”等数据然后提交时,验证中的逻辑会被触发,但我看不到错误消息“请确保所有电子邮件都有效”。我做错了什么 这就是我的模型: public class ShareModel : IValidatableObject { [HiddenIn
public class ShareModel : IValidatableObject
{
[HiddenInput] public string Title { get; set; }
[Required]
public string Emails { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
// custom validation logic here
yield return new ValidationResult($"Please make sure that all of the emails are valid", new[] { "Emails" });
}
}
公共类共享模型:IValidatableObject
{
[HiddenInput]公共字符串标题{get;set;}
[必需]
公共字符串电子邮件{get;set;}
公共IEnumerable验证(ValidationContext ValidationContext)
{
//这里的自定义验证逻辑
返回新的ValidationResult($“请确保所有电子邮件都有效”,新[]{“电子邮件”});
}
}
这是我的看法:
<div class="modal fade" id="shareFormModal" role="dialog">
<div class="modal-dialog modal-md">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Share Workbook - @Model.Title</h4>
</div>
@using (Html.BeginForm("ShareWorkbook", "Home", FormMethod.Post, new {@id = "partialform"}))
{
<div class="modal-body">
<label>@BaseLanguage.Share_workbook_Instruction_text</label>
<div class="form-group">
<textarea class="form-control" asp-for="Emails" rows="4" cols="50" placeholder="@BaseLanguage.ShareDialogPlaceholder"></textarea>
<span asp-validation-for="Emails" class="text-danger"></span>
</div>
<input asp-for="Title"/>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Share</button>
<button id="btnCancelDialog" type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
}
</div>
</div>
共享工作簿-@Model.Title
@使用(Html.BeginForm(“共享工作簿”、“主页”、FormMethod.Post、new{@id=“partialform”}))
{
@BaseLanguage.Share\u工作簿\u说明\u文本
分享
取消
}
根据此IValidatableObject
不在客户端考虑。为了显示来自自定义验证的自定义错误消息,您需要实现自定义ValidationAttribute
,该属性还实现了所述的IClientModelValidator
接口。供将来参考,正如Alexander在上面解释的,我必须同时使用ValidationAttribute,IClientModelValidator
类似于:
共享模型:
public class ShareModel
{
[HiddenInput] public string Title { get; set; }
[Required]
[IsEmailAttribute(ErrorMessage = "Check all of the emails you have typed")]
public string Emails { get; set; }
}
public class IsEmailAttribute : ValidationAttribute, IClientModelValidator
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return new ValidationResult("Check emails!");
}
public void AddValidation(ClientModelValidationContext context)
{
MergeAttribute(context.Attributes, "data-val", "true");
var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
MergeAttribute(context.Attributes, "data-val-isEmail", errorMessage);
}
private bool MergeAttribute(
IDictionary<string, string> attributes,
string key,
string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
@using DNAAnalysisCore.Resources
@model DNAAnalysisCore.Models.ShareModel
<!-- Modal -->
<div class="modal fade" id="shareFormModal" role="dialog">
<div class="modal-dialog modal-md">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Share Workbook - @Model.Title</h4>
</div>
@using (Html.BeginForm("ShareWorkbook", "Home", FormMethod.Post, new {@id = "partialform"}))
{
<div class="modal-body">
<label>@BaseLanguage.Share_workbook_Instruction_text</label>
<div class="form-group">
<textarea class="form-control" asp-for="Emails" rows="4" cols="50" placeholder="@BaseLanguage.ShareDialogPlaceholder"></textarea>
<span asp-validation-for="Emails" class="text-danger"></span>
</div>
<input asp-for="Title"/>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Share</button>
<button id="btnCancelDialog" type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
}
</div>
</div>
</div>
@using DNAAnalysisCore.Resources
@model DNAAnalysisCore.Models.WorkBookModel
@{
}
@section BodyFill
{
<div id="shareFormContainer">
<!--PLACEHOLDER FOR SHARE DIALOG -->
@{
@Html.Partial("_ShareView", new ShareModel())
}
</div>
<div class="workbook-container">
<table class="table">
<tbody>
@foreach (var workbook in Model.Workbooks)
{
<tr>
<td>@Html.ActionLink(workbook.Name, "Open", "OpenAnalytics", new { id = Model.Id, workbook = workbook.Name })</td>
<td>
<button title="Share" class="share-button" onclick='showSharingView("@workbook.Name")'> </button>
</td>
</tr>
}
</tbody>
</table>
</div>
}
@section Scripts
{
<!--Load JQuery 'unobtrusive' validation -->
@await Html.PartialAsync("_ValidationScriptsPartial")
<script type="text/javascript">
function showSharingView(title) {
var url = "@Url.Action("ShowShareDialog", "Home")" + "?workbookTitle=" + encodeURI(title);
$('#shareFormContainer').load(url,
function() {
$('#shareFormModal').modal("show");
// // We need to manually register the form for validation as the dialog is
// // not included in the page when it initially loads
$.validator.unobtrusive.parse("#partialform");
// email validation
$.validator.addMethod("isEmail",
function (value, element, parameters) {
// TODO CLIENT SIDE VALIDATETION LOGIC HERE
return false;
});
$.validator.unobtrusive.adapters.add("isEmail",
[],
function(options) {
options.rules.isEmail = {};
options.messages["isEmail"] = options.message;
});
});
}
</script>
}
公共类共享模型
{
[HiddenInput]公共字符串标题{get;set;}
[必需]
[IsEmailAttribute(ErrorMessage=“检查您键入的所有电子邮件”)]
公共字符串电子邮件{get;set;}
}
公共类IsEmailAttribute:ValidationAttribute,IClientModelValidator
{
受保护的重写ValidationResult有效(对象值,ValidationContext ValidationContext)
{
返回新的ValidationResult(“检查电子邮件!”);
}
public void AddValidation(ClientModelValidationContext上下文)
{
MergeAttribute(context.Attributes,“数据值”、“真”);
var errorMessage=FormatErrorMessage(context.ModelMetadata.GetDisplayName());
MergeAttribute(context.Attributes,“data val isEmail”,errorMessage);
}
私有布尔合并属性(
IDictionary属性,
字符串键,
字符串值)
{
if(attributes.ContainsKey(键))
{
返回false;
}
属性。添加(键、值);
返回true;
}
}
\u ShareView.cshtml:
public class ShareModel
{
[HiddenInput] public string Title { get; set; }
[Required]
[IsEmailAttribute(ErrorMessage = "Check all of the emails you have typed")]
public string Emails { get; set; }
}
public class IsEmailAttribute : ValidationAttribute, IClientModelValidator
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return new ValidationResult("Check emails!");
}
public void AddValidation(ClientModelValidationContext context)
{
MergeAttribute(context.Attributes, "data-val", "true");
var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
MergeAttribute(context.Attributes, "data-val-isEmail", errorMessage);
}
private bool MergeAttribute(
IDictionary<string, string> attributes,
string key,
string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
@using DNAAnalysisCore.Resources
@model DNAAnalysisCore.Models.ShareModel
<!-- Modal -->
<div class="modal fade" id="shareFormModal" role="dialog">
<div class="modal-dialog modal-md">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Share Workbook - @Model.Title</h4>
</div>
@using (Html.BeginForm("ShareWorkbook", "Home", FormMethod.Post, new {@id = "partialform"}))
{
<div class="modal-body">
<label>@BaseLanguage.Share_workbook_Instruction_text</label>
<div class="form-group">
<textarea class="form-control" asp-for="Emails" rows="4" cols="50" placeholder="@BaseLanguage.ShareDialogPlaceholder"></textarea>
<span asp-validation-for="Emails" class="text-danger"></span>
</div>
<input asp-for="Title"/>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Share</button>
<button id="btnCancelDialog" type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
}
</div>
</div>
</div>
@using DNAAnalysisCore.Resources
@model DNAAnalysisCore.Models.WorkBookModel
@{
}
@section BodyFill
{
<div id="shareFormContainer">
<!--PLACEHOLDER FOR SHARE DIALOG -->
@{
@Html.Partial("_ShareView", new ShareModel())
}
</div>
<div class="workbook-container">
<table class="table">
<tbody>
@foreach (var workbook in Model.Workbooks)
{
<tr>
<td>@Html.ActionLink(workbook.Name, "Open", "OpenAnalytics", new { id = Model.Id, workbook = workbook.Name })</td>
<td>
<button title="Share" class="share-button" onclick='showSharingView("@workbook.Name")'> </button>
</td>
</tr>
}
</tbody>
</table>
</div>
}
@section Scripts
{
<!--Load JQuery 'unobtrusive' validation -->
@await Html.PartialAsync("_ValidationScriptsPartial")
<script type="text/javascript">
function showSharingView(title) {
var url = "@Url.Action("ShowShareDialog", "Home")" + "?workbookTitle=" + encodeURI(title);
$('#shareFormContainer').load(url,
function() {
$('#shareFormModal').modal("show");
// // We need to manually register the form for validation as the dialog is
// // not included in the page when it initially loads
$.validator.unobtrusive.parse("#partialform");
// email validation
$.validator.addMethod("isEmail",
function (value, element, parameters) {
// TODO CLIENT SIDE VALIDATETION LOGIC HERE
return false;
});
$.validator.unobtrusive.adapters.add("isEmail",
[],
function(options) {
options.rules.isEmail = {};
options.messages["isEmail"] = options.message;
});
});
}
</script>
}
@使用dnaanalysicscore.Resources
@模型DNAAnalysicScore.Models.ShareModel
共享工作簿-@Model.Title
@使用(Html.BeginForm(“共享工作簿”、“主页”、FormMethod.Post、new{@id=“partialform”}))
{
@BaseLanguage.Share\u工作簿\u说明\u文本
分享
取消
}
索引.cshtnl:
public class ShareModel
{
[HiddenInput] public string Title { get; set; }
[Required]
[IsEmailAttribute(ErrorMessage = "Check all of the emails you have typed")]
public string Emails { get; set; }
}
public class IsEmailAttribute : ValidationAttribute, IClientModelValidator
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
return new ValidationResult("Check emails!");
}
public void AddValidation(ClientModelValidationContext context)
{
MergeAttribute(context.Attributes, "data-val", "true");
var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
MergeAttribute(context.Attributes, "data-val-isEmail", errorMessage);
}
private bool MergeAttribute(
IDictionary<string, string> attributes,
string key,
string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
@using DNAAnalysisCore.Resources
@model DNAAnalysisCore.Models.ShareModel
<!-- Modal -->
<div class="modal fade" id="shareFormModal" role="dialog">
<div class="modal-dialog modal-md">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Share Workbook - @Model.Title</h4>
</div>
@using (Html.BeginForm("ShareWorkbook", "Home", FormMethod.Post, new {@id = "partialform"}))
{
<div class="modal-body">
<label>@BaseLanguage.Share_workbook_Instruction_text</label>
<div class="form-group">
<textarea class="form-control" asp-for="Emails" rows="4" cols="50" placeholder="@BaseLanguage.ShareDialogPlaceholder"></textarea>
<span asp-validation-for="Emails" class="text-danger"></span>
</div>
<input asp-for="Title"/>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Share</button>
<button id="btnCancelDialog" type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
</div>
}
</div>
</div>
</div>
@using DNAAnalysisCore.Resources
@model DNAAnalysisCore.Models.WorkBookModel
@{
}
@section BodyFill
{
<div id="shareFormContainer">
<!--PLACEHOLDER FOR SHARE DIALOG -->
@{
@Html.Partial("_ShareView", new ShareModel())
}
</div>
<div class="workbook-container">
<table class="table">
<tbody>
@foreach (var workbook in Model.Workbooks)
{
<tr>
<td>@Html.ActionLink(workbook.Name, "Open", "OpenAnalytics", new { id = Model.Id, workbook = workbook.Name })</td>
<td>
<button title="Share" class="share-button" onclick='showSharingView("@workbook.Name")'> </button>
</td>
</tr>
}
</tbody>
</table>
</div>
}
@section Scripts
{
<!--Load JQuery 'unobtrusive' validation -->
@await Html.PartialAsync("_ValidationScriptsPartial")
<script type="text/javascript">
function showSharingView(title) {
var url = "@Url.Action("ShowShareDialog", "Home")" + "?workbookTitle=" + encodeURI(title);
$('#shareFormContainer').load(url,
function() {
$('#shareFormModal').modal("show");
// // We need to manually register the form for validation as the dialog is
// // not included in the page when it initially loads
$.validator.unobtrusive.parse("#partialform");
// email validation
$.validator.addMethod("isEmail",
function (value, element, parameters) {
// TODO CLIENT SIDE VALIDATETION LOGIC HERE
return false;
});
$.validator.unobtrusive.adapters.add("isEmail",
[],
function(options) {
options.rules.isEmail = {};
options.messages["isEmail"] = options.message;
});
});
}
</script>
}
@使用dnaanalysicscore.Resources
@模型DNAAnalysicScore.Models.WorkBookModel
@{
}
@分段填体
{
@{
@Html.Partial(“\u ShareView”,新的ShareModel())
}
@foreach(Model.Workbooks中的var工作簿)
{
@ActionLink(workbook.Name,“Open”,“OpenAnalytics”,new{id=Model.id,workbook=workbook.Name})
}
}
@节脚本
{
@等待Html.PartialAsync(“验证脚本”)
功能显示共享视图(标题){
var url=“@url.Action”(“ShowShareDialog”,“Home”)“+”?workbookTitle=“+encodeURI(标题);
$('#shareFormContainer')。加载(url,
函数(){
$('shareFormModal').modal(“show”);
////我们需要手动注册表单以进行验证,因为对话框是
////初始加载时不包括在页面中
$.validator.unobtrusive.parse(“#partialform”);
//电子邮件验证
$.validator.addMethod(“isEmail”,
函数(值、元素、参数){
//此处的TODO客户端验证逻辑
返回false;
});
$.validator.unobtrusive.adapters.add(“isEmail”,
[],
功能(选项){
options.rules.isEmail={};
options.messages[“isEmail”]=options.message;
});
});
}
}
谢谢您的建议。但是,它仍然不起作用-我看不到自定义错误消息。我用我这里的东西创建了一个要点,如果你能看一下,也许我遗漏了什么:@GeorgiKoemdzhiev you missingoptions.rules.isEmail={}代码>行。将其插入options.messages[“isEmail”]=options.message之前