Как я могу (в ASP.NET MVC) получить CultureInfo текущего посетителя (на основе его/ее языков браузера)?
Я не знаю, с чего начать. Я попытался изучить заголовок "Accept-Languages", отправленный браузером. Но лучший способ это сделать?
Как я могу (в ASP.NET MVC) получить CultureInfo текущего посетителя (на основе его/ее языков браузера)?
Я не знаю, с чего начать. Я попытался изучить заголовок "Accept-Languages", отправленный браузером. Но лучший способ это сделать?
Request.UserLanguages - это свойство, которое вы ищете. Просто имейте в виду, что этот массив может содержать произвольные (даже не-экзистенциальные) языки, заданные заголовками запросов.
UPDATE
Пример:
// Get Browser languages.
var userLanguages = Request.UserLanguages;
CultureInfo ci;
if (userLanguages.Count() > 0)
{
try
{
ci = new CultureInfo(userLanguages[0]);
}
catch(CultureNotFoundException)
{
ci = CultureInfo.InvariantCulture;
}
}
else
{
ci = CultureInfo.InvariantCulture;
}
// Here CultureInfo should already be set to either user prefereable language
// or to InvariantCulture if user transmitted invalid culture ID
Вы можете использовать код, похожий на следующий, чтобы получить различные сведения от пользователя (включая языки):
MembershipUser user = Membership.GetUser(model.UserName);
string browser = HttpContext.Request.Browser.Browser;
string version = HttpContext.Request.Browser.Version;
string type = HttpContext.Request.Browser.Type;
string platform = HttpContext.Request.Browser.Platform;
string userAgent = HttpContext.Request.UserAgent;
string[] userLang = HttpContext.Request.UserLanguages
Я отмечаю этот вопрос для себя со звездой и разделяю здесь некоторый код, который по существу превращает Request.UserLanguages
в массив экземпляров CultureInfo для дальнейшего использования в вашем приложении. Кроме того, более гибко работать с CultureInfo, чем только коды ISO, потому что с CultureInfo вы получаете доступ ко всем свойствам культуры (например, имя, имя двух символов, собственное имя и т.д.):
// Create array of CultureInfo objects
string locale = string.Empty;
CultureInfo[] cultures = new CultureInfo[Request.UserLanguages.Length + 1];
for (int ctr = Request.UserLanguages.GetLowerBound(0); ctr <= Request.UserLanguages.GetUpperBound(0);
ctr++)
{
locale = Request.UserLanguages[ctr];
if (!string.IsNullOrEmpty(locale))
{
// Remove quality specifier, if present.
if (locale.Contains(";"))
locale = locale.Substring(0, locale.IndexOf(';'));
try
{
cultures[ctr] = new CultureInfo(locale, false);
}
catch (Exception) { continue; }
}
else
{
cultures[ctr] = CultureInfo.CurrentCulture;
}
}
cultures[Request.UserLanguages.Length] = CultureInfo.InvariantCulture;
НТН
Похоже, что Request.UserLanguages
недоступен в более поздних версиях mvc (в ядре Asp.net mvc 2.0.2 его не было).
Приведенный ниже код предоставит вам культуры из заголовка Accept-Language
в порядке предпочтения.
Это похоже на ответ @mare, но более актуально и качество не игнорируется. Я сделал это методом расширения для HttpRequest, поэтому он должен работать где угодно с request.GetAcceptLanguageCultures()
.
Протестировано с ASP.NET Core MVC 2.0.2
public static class HttpRequestExtensions
{
public static IList<CultureInfo> GetAcceptLanguageCultures(this HttpRequest request)
{
var requestedLanguages = request.Headers["Accept-Language"];
if (StringValues.IsNullOrEmpty(requestedLanguages) || requestedLanguages.Count == 0)
{
return null;
}
var preferredCultures = requestedLanguages.ToString().Split(',')
// Parse the header values
.Select(s => new StringSegment(s))
.Select(StringWithQualityHeaderValue.Parse)
// Ignore the "any language" rule
.Where(sv => sv.Value != "*")
// Remove duplicate rules with a lower value
.GroupBy(sv => sv.Value).Select(svg => svg.OrderByDescending(sv => sv.Quality.GetValueOrDefault(1)).First())
// Sort by preference level
.OrderByDescending(sv => sv.Quality.GetValueOrDefault(1))
.Select(sv => new CultureInfo(sv.Value.ToString()))
.ToList();
return preferredCultures;
}
}
var userLanguage = CultureInfo.CurrentUICulture;