Для дальнейшего использования, как объяснил Александр, я должен был использовать оба значения ValidationAttribute, IClientModelValidator
:
ShareModel
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;
}
}
_ShareView.cshtml
@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>
index.cshtnl
@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>
}