В базовом классе, который RemoteAttribute
является производным, есть защищенный метод GetUrl()
, который можно переопределить. Поэтому я создал свой собственный MyRemoteAttribute
класс
public class MyRemoteAttribute : RemoteAttribute
{
/// <summary>
/// Initialise an instance of the <see cref="MyRemoteAttribute"/>
/// </summary>
/// <param name="handler">The name of the Razor Page Handler</param>
/// <param name="page">The Razor Page name</param>
public MyRemoteAttribute(string handler = null, string page = null)
{
Handler = handler;
Page = page;
}
/// <summary>
/// Gets/sets the url to use for remote validation
/// </summary>
public string Url { get; set; }
public string Page { get; private set; }
public string Handler { get; private set; }
protected override string GetUrl(ClientModelValidationContext context)
{
// Use an URL is specified
if (!string.IsNullOrEmpty(Url)) return Url;
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
if (string.IsNullOrEmpty(Handler))
{
throw new InvalidOperationException("No Handler specified");
}
var services = context.ActionContext.HttpContext.RequestServices;
var factory = services.GetRequiredService<Microsoft.AspNetCore.Mvc.Routing.IUrlHelperFactory>();
var urlHelper = factory.GetUrlHelper(context.ActionContext);
var page = Page?? context.ActionContext.RouteData.Values["page"] as string;
Url = urlHelper.Page(page, Handler);
if (Url == null)
{
throw new InvalidOperationException();
}
return Url;
}
}
В моем приложении, которое использует области, создает URL /BusinessPartners/Clients/Create?handler=CheckUnique
Для использования украсьте свойство вашей модели с помощью [MyRemote(Url="/Something/Somecheck")]
, чтобы использовать указанный URL, или [MyRemote("CheckUnique")]
, чтобы указать обработчик страницы Razor. Обработчик должен иметь имя OnGet<handlername>
и должен возвращать JsonResult
с true
для прохождения проверки, false
или null
, если проверка не пройдена.
Обработчик на странице Razor:
public IActionResult OnGetCheckUnique(string shortName)
{
var found = db.Queryable<BusinessPartner>().Any(a => a.ShortName == shortName);
return new JsonResult(!found);
}
Это то же самое, что вы сделали бы для RemoteAttribute
, за исключением слегка измененного соглашения об именах.
Мне нравится, что моя валидация близка к той точке, где она используется, поэтому я поместил ее на той же странице. Я также использовал один [BindProperty]
для модельного класса, чтобы все было аккуратно и легко.