Asp.Net Core Razor 页面中的远程验证
Posted
技术标签:
【中文标题】Asp.Net Core Razor 页面中的远程验证【英文标题】:Remote Validation in Asp.Net Core Razor Pages 【发布时间】:2019-06-08 17:09:48 【问题描述】:我正在使用 Razor Pages 和 Code First 开发一个 Web 应用程序。
我知道在 ASP.NET MVC 中,您可以在属性上方使用 Remote
来引用控制器中的操作,该操作验证数据而无需回发整个页面。但它似乎在 Razor 页面中不起作用,因为 ASP.NET Core Razor 页面中没有控制器和操作。
那么,如何在 Razor Pages 中完成远程验证?
【问题讨论】:
ASP.NET MVC 和 ASP.NET Core(总是“MVC”,但有所不同)的技能不容易转移。花一些时间(也许很多!)阅读docs.microsoft.com/en-us/aspnet/core/razor-pages/… @BrianOgden 您发表的文章涉及在 Asp.Net Core MVC 而不是 Asp.Net Razor Pages 中的远程验证!他们很接近但不同!我正在寻找一种在 Razor Pages 中实现远程验证的方法。在最后求助于社区帮助之前,我已经做了很多搜索。 然后调整你的互联网搜索:binaryintellect.net/articles/… @meisamdehghan 对您的问题进行编辑,然后我可以删除我的反对票,在“所以,我如何...”中的 comm 之后添加空格 @BrianOgden 感谢您的回答。目前看来,Asp.Net Core 中没有 Razor Pages 特定版本的 [Remote] 属性。 【参考方案1】:我在模型类中添加了以下内容:
[Remote(action: "IsNationalIdValid",controller:"Validations")]
我在 Razor Pages 项目中创建了“Controllers”文件夹,并使用以下方法添加了一个控制器(ValidationsController):
public IActionResult IsNationalIdValid(string nationalId)
但是,当我尝试转到应该进行此验证的页面时,出现以下异常:
在 asp.net core 中找不到远程验证的 URL
感谢在 Asp.Net 论坛中对同一主题的回复,我想出了答案: 我需要做的就是在我的 Razor Pages 项目的 Startup.cs 文件中添加以下代码以配置路由。
app.UseMvc(routes =>
routes.MapRoute(
name: "default",
template: "controller=Home/action=Index/id?");
);
希望这个答案也能对其他人有所帮助。
【讨论】:
【参考方案2】:对于像我这样后来发现这一点并在试图将模型中的属性传递到验证方法时失去理智的人,让方法签名看起来像这样
public IActionResult IsCharacterNameAvailable([Bind(Prefix = "Character.Name")] string name)
Character 是模型,Name 是属性。没有在参数之前添加 [Bind(Prefix = "")] 我总是收到一个空值。希望这可以帮助!
【讨论】:
【参考方案3】:在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]
,只是为了保持整洁和易于管理。
【讨论】:
【参考方案4】:在 ASP.NET Core Razor Pages 中似乎有远程验证的功能请求,但不是优先级:
https://github.com/aspnet/Mvc/issues/8245
【讨论】:
【参考方案5】:PageRemoteValidation 属性是在 ASP.NET Core 3.0 中引入的,专为使用 Razor Pages 处理程序方法而设计。
因此,如果您使用的是 ASP.NET Core 2.x,或者您的验证端点是 MVC 控制器,则必须使用 RemoteValidation
属性。如果您使用 ASP.NET Core 3.x 或更高版本,并且您的验证服务是 Razor Pages 处理程序方法,则必须使用 PageRemoteValidation
属性。
Here 是一个详细描述这一点的示例:
【讨论】:
以上是关于Asp.Net Core Razor 页面中的远程验证的主要内容,如果未能解决你的问题,请参考以下文章
更改 ASP.NET Core Razor 页面中的默认登录页面?
将 ASP.NET Core Razor 页面中的默认页面更改为登录页面