为特定的Razor Pages Route调用特定的过滤器?

问题描述 投票:2回答:1

我有2个域(.com.ru)和2个网址,如site.com/about-ussite.ru/o-nas,应重定向到同一页面。该网站使用Razor Pages。

此外,特定的URL应该在适当的域中可用。例如:

  • site.COM/o-nas不应该工作并返回Not Found (404)
  • site.RU/about-us不应该工作并返回Not Found (404) 我发现过滤器工作正常,但对于site.com/about-ussite.ru/o-nas,两个过滤器都被调用。

如何只为特定的URL调用1,是否可能?谢谢,我目前的代码如下。

public static class DomainFilters
{
    public static IPageApplicationModelConvention DomainEng(
        this PageConventionCollection con, string pageName, string route = "")
    {
        return con.AddPageApplicationModelConvention(pageName, model =>
        {
            model.Filters.Add(new EnglishActionFilter(route));
        });
    }
    public static IPageApplicationModelConvention DomainRussian(
        this PageConventionCollection con, string pageName, string route = "")
    {
        return con.AddPageApplicationModelConvention(pageName, model =>
        {
            model.Filters.Add(new RussianActionFilter(route));
        });
    }
}

public class EnglishActionFilter : IResultFilter
{
    public void OnResultExecuting(ResultExecutingContext context)
    {
        if (context.HttpContext.Request.Host.ToString().Contains(".ru"))
        {
            context.Result = new NotFoundResult();
        }
    }

    public void OnResultExecuted(ResultExecutedContext context) { }
}

public class RussianActionFilter : IResultFilter
{
    public void OnResultExecuting(ResultExecutingContext context)
    {
        if (context.HttpContext.Request.Host.ToString().Contains(".com"))
        {
            context.Result = new NotFoundResult();
        }
    }

    public void OnResultExecuted(ResultExecutedContext context) { }
}

最后来自ConfigureServicesStartup.cs方法:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc()
        .AddRazorPagesOptions(options =>
        {
            options.Conventions.DomainEng("/AboutUs", "about-us");
            options.Conventions.DomainRussian("/AboutUs", "o-nas");
        })
}
c# asp.net-core-2.0 razor-pages asp.net-core-routing
1个回答
1
投票

考虑实现自定义FilterFactory

public class LanguageFilterFactory : Attribute, IFilterFactory
{
    public bool IsReusable => false;

    public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
    {
        var context = serviceProvider.GetService<IHttpContextAccessor>();

        if (context.HttpContext.Request.Host.ToString().Contains(".com"))
        {
            return new EnglishActionFilter();
        }

        return new RussianActionFilter();
    }
}

这个工厂将创建一个EnglishRussian过滤器(取决于域)。这完全是关于它的责任。剩下的就是过滤器本身(你需要更改过滤器中的代码以使它们验证页面定位器):

public class RussianActionFilter : IResultFilter
{
    public void OnResultExecuting(ResultExecutingContext context)
    {
        // you may want to play with RouteData in order to make this check more elegant   
        if (context.HttpContext.Request.Path.Value.Contains("About"))
        {
            context.Result = new NotFoundResult();
        }
    }
}

过滤器工厂的应用方式与其他过滤器相同:

[LanguageFilterFactory]
public class IndexModel : PageModel

Startup.cs文件更新:

.AddMvcOptions(options =>
{
   options.Filters.Add<LanguageFilterFactory>();
});
© www.soinside.com 2019 - 2024. All rights reserved.