Reputation: 6202
I have 2 domains (.com
and .ru
) and 2 URLs like site.com/about-us
and site.ru/o-nas
which should be redirected to the same page. The site uses Razor Pages.
Also, the particular URL should be available in the appropriate domain. For example:
site.COM/o-nas
should not work and return Not Found (404)
site.RU/about-us
should not work and return Not Found (404)
I found that filters work OK, but for both for site.com/about-us
and site.ru/o-nas
both filters are called.
How to call only 1 for particular URL, is it possible? Thank you, my current code is below.
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) { }
}
And finally ConfigureServices
method from Startup.cs
:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.DomainEng("/AboutUs", "about-us");
options.Conventions.DomainRussian("/AboutUs", "o-nas");
})
}
Upvotes: 2
Views: 587
Reputation: 2314
Consider implementation of a custom 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();
}
}
This factory will create either an English
or Russian
filter (depending on the domain). That's all about its responsibilities. The rest goes to Filters themselves (you'll need to change a code inside the filters to make them validate the page locator):
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();
}
}
}
The filter factory is applied in the same way as other filters:
[LanguageFilterFactory]
public class IndexModel : PageModel
The Startup.cs
file update:
.AddMvcOptions(options =>
{
options.Filters.Add<LanguageFilterFactory>();
});
Upvotes: 1