[英]asp mvc core 3 Client side validation for a custom attribute validation
我創建了一個自定義驗證屬性,如下所示:
public class UniqueTitleAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(
object value, ValidationContext validationContext)
{
var context = (MyDBContext)validationContext.GetService(typeof(MyDBContext));
var entity = context.Pages.SingleOrDefault(e => e.Title == value.ToString());
if (entity != null)
{
return new ValidationResult(GetErrorMessage(value.ToString()));
}
return ValidationResult.Success;
}
public string GetErrorMessage(string title)
{
return $"Title {title} is already in use.";
}
}
而在 model 中:
[UniqueTitle]
public string Title { get; set; }
而且效果很好,但是我還希望能夠添加客戶端驗證?
在自定義驗證屬性中,實現IClientModelValidator
接口並創建AddValidation
方法。 在AddValidation
方法中,添加data-
屬性進行驗證,如下所示:
public class UniqueTitleAttribute : ValidationAttribute, IClientModelValidator
{
protected override ValidationResult IsValid(
object value, ValidationContext validationContext)
{
var context = (ApplicationDbContext)validationContext.GetService(typeof(ApplicationDbContext));
var entity = context.Articles.SingleOrDefault(e => e.Title == value.ToString());
if (entity != null)
{
return new ValidationResult(GetErrorMessage(value.ToString()));
}
return ValidationResult.Success;
}
public void AddValidation(ClientModelValidationContext context)
{
Type obj = typeof(Article);
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
MergeAttribute(context.Attributes, "data-val", "true");
MergeAttribute(context.Attributes, "data-val-uniquetitle", GetErrorMessage());
}
private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
public string GetErrorMessage()
{
return $"The title is already in use.";
}
public string GetErrorMessage(string title)
{
return $"Title {title} is already in use.";
}
}
向 jQuery 驗證庫添加方法。 它使用addMethod()
方法來指定我們自己的驗證 function。 驗證 function 接收在標題文本框中輸入的值。 然后它執行驗證並返回 boolean 值。
<div class="row">
<div class="col-md-4">
<form method="post" asp-action="CreateArticle">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Author" class="control-label"></label>
<input asp-for="Author" class="form-control" />
<span asp-validation-for="Author" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
@section Scripts
{
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript">
var titlelist = @Html.Raw(Json.Serialize(ViewBag.TitleList));
$.validator.addMethod("uniquetitle",
function (value, element, param) {
if (titlelist.includes(value)) {
return false;
}
else {
return true;
}
});
$.validator.unobtrusive.adapters.addBool("uniquetitle");
</script>
}
在視圖的Get方法中保存ViewBag中的TitleList,以便js判斷標題是否在使用中:
public IActionResult CreateArticle()
{
ViewBag.TitleList = _context.Articles.Select(a => a.Title).ToList();
return View();
}
You have to use jquery and unobtrusive client side validation so fetch those urls in
your page.
Use like
<label asp-for="Name"></label>
<input asp-for="Name"/>
<span asp-validation-for="Name"></span>
Here i have taken example of Name as validation will fire on Name property but you can
change property on which you want.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.