如何拦截请求以获取用于站点本地化的原始 URL?
How to intercept a request to get the raw URL for site localization?
我的网站是这样工作的:
- 所有内容都有 {culture/slug} URLs
的自动路由
- 用户可以select站点文化,以便一切都以他们选择的语言呈现
我正在尝试实现此功能:
- 用户 select 的英语站点。
- 用户转到 "site.com/es/content",这是西班牙语内容。
- 站点必须自动将文化更改为西班牙语和return请求的内容。
我认为我需要的是拦截请求,解析URL并获取文化,看看它是否与当前相同。
我尝试使用 IHttpContextAccessor 在 Orchard.Core.Contents 的 ItemsController 中获取它,但它没有原始 Url.
我也尝试在 Orchard.Autoroute 和 Orchard.Alias 服务中捕获请求,但它们不是处理请求的服务。
任何指点将不胜感激。
有一些方法可以做到这一点。
实施 ICultureSelector
namespace SomeModule
{
using System;
using System.Globalization;
using System.Linq;
using System.Web;
using Orchard.Localization.Services;
public class CultureSelectorByHeader : ICultureSelector
{
private readonly ICultureManager cultureManager;
public CultureSelectorByHeader(ICultureManager cultureManager)
{
this.cultureManager = cultureManager;
}
public CultureSelectorResult GetCulture(HttpContextBase context)
{
var acceptedLanguageHeader = context?.Request?.UserLanguages?.FirstOrDefault();
if ( acceptedLanguageHeader == null )
return null;
var enabledCultures = this.cultureManager.ListCultures();
var siteCulture = this.cultureManager.GetSiteCulture();
// Select the specified culture if it's enabled.
// Otherwise, or if it wasn't found, fall back to the default site culture.
var culture = enabledCultures.Contains(acceptedLanguageHeader, StringComparer.InvariantCultureIgnoreCase)
? CultureInfo.CreateSpecificCulture(acceptedLanguageHeader).Name
: CultureInfo.CreateSpecificCulture(siteCulture).Name;
return new CultureSelectorResult { CultureName = culture, Priority = 0 };
}
}
}
您可以在 GetCulture
、读取 headers、cookie、查询字符串或从数据库中获取当前用户的一些设置。满足您的需求。
直接设置文化
private void SetWorkContextCulture(string cultureTwoLetterIsoCode)
{
if ( !string.IsNullOrWhitespace(cultureTwoLetterIsoCode) )
{
try
{
var culture = CultureInfo.CreateSpecificCulture(cultureTwoLetterIsoCode);
this.Services.WorkContext.CurrentCulture = culture.TwoLetterISOLanguageName;
}
catch ( CultureNotFoundException )
{
Debug.WriteLine("Couldn't change thread culture.");
}
}
}
只需在返回结果之前更改 WorkContext
的当前文化即可。
有趣的事实:在控制器中更改 WorkContext.Culture
将覆盖您在 ICultureSelector
实现中所做的一切。
我的网站是这样工作的:
- 所有内容都有 {culture/slug} URLs 的自动路由
- 用户可以select站点文化,以便一切都以他们选择的语言呈现
我正在尝试实现此功能:
- 用户 select 的英语站点。
- 用户转到 "site.com/es/content",这是西班牙语内容。
- 站点必须自动将文化更改为西班牙语和return请求的内容。
我认为我需要的是拦截请求,解析URL并获取文化,看看它是否与当前相同。
我尝试使用 IHttpContextAccessor 在 Orchard.Core.Contents 的 ItemsController 中获取它,但它没有原始 Url.
我也尝试在 Orchard.Autoroute 和 Orchard.Alias 服务中捕获请求,但它们不是处理请求的服务。
任何指点将不胜感激。
有一些方法可以做到这一点。
实施 ICultureSelector
namespace SomeModule
{
using System;
using System.Globalization;
using System.Linq;
using System.Web;
using Orchard.Localization.Services;
public class CultureSelectorByHeader : ICultureSelector
{
private readonly ICultureManager cultureManager;
public CultureSelectorByHeader(ICultureManager cultureManager)
{
this.cultureManager = cultureManager;
}
public CultureSelectorResult GetCulture(HttpContextBase context)
{
var acceptedLanguageHeader = context?.Request?.UserLanguages?.FirstOrDefault();
if ( acceptedLanguageHeader == null )
return null;
var enabledCultures = this.cultureManager.ListCultures();
var siteCulture = this.cultureManager.GetSiteCulture();
// Select the specified culture if it's enabled.
// Otherwise, or if it wasn't found, fall back to the default site culture.
var culture = enabledCultures.Contains(acceptedLanguageHeader, StringComparer.InvariantCultureIgnoreCase)
? CultureInfo.CreateSpecificCulture(acceptedLanguageHeader).Name
: CultureInfo.CreateSpecificCulture(siteCulture).Name;
return new CultureSelectorResult { CultureName = culture, Priority = 0 };
}
}
}
您可以在 GetCulture
、读取 headers、cookie、查询字符串或从数据库中获取当前用户的一些设置。满足您的需求。
直接设置文化
private void SetWorkContextCulture(string cultureTwoLetterIsoCode)
{
if ( !string.IsNullOrWhitespace(cultureTwoLetterIsoCode) )
{
try
{
var culture = CultureInfo.CreateSpecificCulture(cultureTwoLetterIsoCode);
this.Services.WorkContext.CurrentCulture = culture.TwoLetterISOLanguageName;
}
catch ( CultureNotFoundException )
{
Debug.WriteLine("Couldn't change thread culture.");
}
}
}
只需在返回结果之前更改 WorkContext
的当前文化即可。
有趣的事实:在控制器中更改 WorkContext.Culture
将覆盖您在 ICultureSelector
实现中所做的一切。