[英]Razor page routing based on different domains
I'm trying to setup a single ASP.NET Core Razor Web app localized for use on multi domains. 我正在尝试设置一个本地化用于多域的ASP.NET Core Razor Web应用程序。 I have the localization working, with one different language for each domain. 我有本地化工作,每个域使用一种不同的语言。 But right now I want to have the .com domain accepting a routing parameter, to make the URL path decide with language to show. 但是现在我希望.com域接受路由参数,以使URL路径决定使用要显示的语言。
Something like: 就像是:
For MVC this could be achieved by using the MapRoute with a custom IRouteConstraint to filter by domain. 对于MVC,可以通过使用MapRoute和自定义IRouteConstraint按域过滤来实现。 However with Razor pages, I only see the option to go with the conventions and add a class derived from IPageRouteModelConvention. 但是对于Razor页面,我只看到了与约定一起使用的选项,并添加了一个派生自IPageRouteModelConvention的类。
But I don't see a way on the IPageRouteModelConvention methodology to use a IRouteConstraint. 但我没有看到使用IRouteConstraint的IPageRouteModelConvention方法。 Is there a way to do this? 有没有办法做到这一点?
Not exactly the best solution... but worked this out: 不完全是最好的解决方案......但是解决了这个问题:
On ConfigureServices added a custom convention that takes a country parameter only with two country codes US and CA: 在ConfigureServices上添加了一个自定义约定,该约定仅使用两个国家/地区代码US和CA获取国家/地区参数:
options.Conventions.Add(new CountryTemplateRouteModelConvention());
wethe this class being: 这个班级是这样的:
public class CountryTemplateRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
var selectorCount = model.Selectors.Count;
for (var i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
// selector.AttributeRouteModel.SuppressLinkGeneration = false;
//we are not adding the selector, but replacing the existing one
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = -1,
Template = AttributeRouteModel.CombineTemplates(@"{country:length(2):regex(^(us|ca)$)}", selector.AttributeRouteModel.Template),
}
});
}
}
}
Then, before the UseMvc on Configure, I used two types of Rewrite rules: 然后,在ConfigureM的UseMvc之前,我使用了两种类型的Rewrite规则:
var options = new RewriteOptions();
options.Add(new CountryBasedOnDomainRewriteRule(domains: GetDomainsWhereCountryComesFromDomain(Configuration)));
options.Add(new CountryBasedOnPathRewriteRule(domains: GetDomainsWhereCountryComesFromPath(Configuration)));
app.UseRewriter(options);
The methods GetDomainsWhereCountryComesFromDomain and GetDomainsWhereCountryComesFromPath just read from the appsettings the domains where I want to have a single language, and the domains where I want the language to be obtained from the URL path. 方法GetDomainsWhereCountryComesFromDomain和GetDomainsWhereCountryComesFromPath只是从appsettings中读取我想要使用单一语言的域,以及我希望从URL路径获取语言的域。
Now, the two IRule classes: 现在,两个IRule类:
public class CountryBasedOnPathRewriteRule : IRule
{
private readonly string[] domains;
public CountryBasedOnPathRewriteRule(string[] domains)
{
this.domains = domains;
}
public void ApplyRule(RewriteContext context)
{
string hostname = context.HttpContext.Request.Host.Host.ToLower();
if (!domains.Contains(hostname)) return;
//only traffic that has the country on the path is valid. examples:
// www.mysite.com/ -> www.mysite.com/US/
// www.mysite.com/Cart -> www.mysite.com/US/Cart
var path = context.HttpContext.Request.Path.ToString().ToLower();
/* let's exclude the error page, as method UseExceptionHandler doesn't accept the country parameter */
if (path == "/" || path == "/error")
{
//redirect to language default
var response = context.HttpContext.Response;
response.StatusCode = (int)HttpStatusCode.Moved;
response.Headers[HeaderNames.Location] = "/us/"; //default language/country
context.Result = RuleResult.EndResponse;
}
string pathFirst = path.Split('/')?[1];
if (pathFirst.Length != 2) /* US and CA country parameter is already enforced by the routing */
{
var response = context.HttpContext.Response;
response.StatusCode = (int)HttpStatusCode.NotFound;
context.Result = RuleResult.EndResponse;
}
}
}
public class CountryBasedOnDomainRewriteRule : IRule
{
private readonly string[] domains;
public CountryBasedOnDomainRewriteRule(string[] domains)
{
this.domains = domains;
}
public void ApplyRule(RewriteContext context)
{
string hostname = context.HttpContext.Request.Host.Host.ToLower();
if (!domains.Contains(hostname)) return;
var path = context.HttpContext.Request.Path.ToString().ToLower();
string pathFirst = path.Split('/')?[1];
if (pathFirst.Length == 2) //we are trying to use www.mysite.co.uk/us which is not allowed
{
var response = context.HttpContext.Response;
response.StatusCode = (int)HttpStatusCode.NotFound;
context.Result = RuleResult.EndResponse;
}
}
}
And that's it. 就是这样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.