Asp.Net Core Razor页面中的远程验证

时间:2019-01-14 17:11:04

标签: asp.net-core razor-pages

我正在使用Razor Pages和Code First开发一个Web应用程序。

我知道,在ASP.NET MVC中,您可以在属性上方使用Remote,该属性引用控制器中用于验证数据的操作,而无需回发整个页面。但这似乎在Razor Pages中不起作用,因为ASP.NET Core Razor Pages中没有控制器和动作。

那么,如何在Razor Pages中完成远程验证?

5 个答案:

答案 0 :(得分:2)

对于像我这样后来发现这一点并失去尝试将属性从模型传递到验证方法上的人,让方法签名看起来像这样

public IActionResult IsCharacterNameAvailable([Bind(Prefix = "Character.Name")] string name)

字符是模型,名称是属性。在参数之前始终不添加[Bind(Prefix =“”)]的情况下,我始终会收到一个空值。希望这可以帮助!

答案 1 :(得分:1)

好像在ASP.NET Core Razor Pages中有一个功能要求进行远程验证,但这不是优先事项:

https://github.com/aspnet/Mvc/issues/8245

答案 2 :(得分:1)

我在模型类中添加了以下内容:

 [Remote(action: "IsNationalIdValid",controller:"Validations")]

我在Razor Pages项目中创建了“ Controllers”文件夹,并使用以下方法添加了一个控制器(ValidationsController):

        public IActionResult IsNationalIdValid(string nationalId){}

但是,当我尝试转到应该进行此验证的页面时,出现以下异常:

  

在asp.net核心中找不到用于远程验证的URL

感谢Asp.Net论坛中对同一主题的答复,我找到了答案: 我要做的就是在Razor Pages项目的Startup.cs文件中添加以下代码,以配置路由。

app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });

希望这个答案对其他人也有帮助。

答案 3 :(得分:1)

PageRemoteValidation 属性是在 ASP.NET Core 3.0 中引入的,专门设计用于与 Razor Pages 处理程序方法一起使用。

因此,如果您使用的是 ASP.NET Core 2.x,或者您的验证端点是 MVC 控制器,则必须使用 <select id="listado" size="5" multiple> <option value="Leer" id="aficion-leer">Leer</option> <option value="Programar" id="aficion-programar" selected>Programar</option> <!-- selected for demo --> <option value="Cine" id="aficion-cine">Cine</option> <option value="Deporte" id="aficion-deporte">Deporte</option> </select> 属性。如果您使用 ASP.NET Core 3.x 或更高版本,并且您的验证服务是 Razor Pages 处理程序方法,则必须使用 RemoteValidation 属性。

Here 是一个对此进行详细描述的示例:

答案 4 :(得分:0)

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;
    }
}

在我使用区域的应用程序中,创建一个网址/BusinessPartners/Clients/Create?handler=CheckUnique

要使用[MyRemote(Url="/Something/Somecheck")]装饰模型属性以使用指定的URL,或使用[MyRemote("CheckUnique")]装饰Razor页面处理程序。处理程序应命名为OnGet<handlername>,并需要返回JsonResulttrue以通过验证,如果验证失败则返回falsenull

“剃刀”页面中的处理程序为:

public IActionResult OnGetCheckUnique(string shortName)
{
    var found = db.Queryable<BusinessPartner>().Any(a => a.ShortName == shortName);
    return new JsonResult(!found);
}

RemoteAttribute相同,只是对命名约定进行了稍微修改。

我希望我的验证接近使用点,因此我将其放在同一页面中。我还为模型类使用了一个[BindProperty],只是为了使事情保持整洁和可管理。

相关问题