【问题标题】:Get browser language in ASP.NET Core?在 ASP.NET Core 中获取浏览器语言?
【发布时间】:2018-08-29 03:03:27
【问题描述】:

我正在尝试从浏览器获取默认语言,我使用以下代码获取它:

var languages = HttpContext.Request.UserLanguages;

由于 .NET Core 2 不支持上述内容,因此我测试过:

var requestContext = Request.HttpContext.Features.Get<IRequestCultureFeature>();

但是,它返回 null。获取语​​言的正确方法或替代方法是什么?

【问题讨论】:

  • 本地化中间件添加了吗?

标签: c# azure asp.net-core localization asp.net-core-2.0


【解决方案1】:

IRequestCultureFeature 提供您的应用程序支持的第一个匹配语言。支持语言的声明在 Startup 类的 Configure() 中定义(请参阅example)。如果您仍然需要所有可接受的语言作为简单的string[] 就像旧的Request.UserLanguages 属性,那么使用Microsoft.AspNetCore.Http 命名空间中定义的HeaderDictionaryTypeExtensions.GetTypedHeaders() 扩展:

// In your action method.
var languages = Request.GetTypedHeaders()
                       .AcceptLanguage
                       ?.OrderByDescending(x => x.Quality ?? 1) // Quality defines priority from 0 to 1, where 1 is the highest.
                       .Select(x => x.Value.ToString())
                       .ToArray() ?? Array.Empty<string>();

数组languages 包含根据优先级参数q 接受的语言列表。优先级最高的语言排在第一位。要获取默认语言,请获取数组 languages 的第一个元素。

作为扩展方法:

using System.Collections.Generic;
using System.Linq;

using Microsoft.AspNetCore.Http;

public static class HttpRequestExtensions
{
    public static string[] GetUserLanguages(this HttpRequest request)
    {
        return request.GetTypedHeaders()
            .AcceptLanguage
            ?.OrderByDescending(x => x.Quality ?? 1)
            .Select(x => x.Value.ToString())
            .ToArray() ?? Array.Empty<string>();
    }
}

【讨论】:

  • 赞成。我不明白为什么有人反对它,因为这是一个很好的答案
  • @JérômeMEVEL 反对可能是报复,因为我反对接受的答案。
  • 谢谢,这很有用。我不明白为什么 Core 中的事情要复杂得多??
【解决方案2】:

您需要添加本地化中间件才能获得IRequestCultureFeature 功能:

public void Configure(IApplicationBuilder app)
{
    //...

    //Add this:
    app.UseRequestLocalization();

    //...
}

现在在您的控制器中,您可以请求这样的功能:

var requestCulture = Request.HttpContext.Features.Get<IRequestCultureFeature>();

【讨论】:

  • 不是回答。 IRequestCultureFeature 不是字符串[]。
  • @EvgeniNabokov 当然它不是一个字符串,它是一个实现IRequestCultureFeature 接口的服务,正如OP 在问题中使用的那样。 OP 认为它是正确的并被接受,所以谢谢你的反对!
  • @DavidG 如何使用此功能获取接受的语言列表?我曾经使用 Request.UserLanguages 这是 string[].
  • @EvgeniNabokov 就像我上面说的,使用requestCulture 对象。所以像var requestedCulture = requestCulture.RequestCulture;
  • @DavidG 首先,从您的示例中不清楚如何从 IRequestCultureFeature 获取任何语言。请提供更多信息示例。其次,IRequestCultureFeature 不能替代 UserLanguages。我有将用户语言作为字符串 [] 使用的接口。我不能更改接口,也不能只从 Culture 或 UICulture(与第一种支持的语言匹配)创建一个元素数组,因为我需要所有接受的语言才能进一步传递它们。我得出的结论是,我必须手动解析 accept-languages 标头(由 Carlos Tenorio 编写)。太可惜了。
【解决方案3】:

您可以从Request Headers获取浏览器语言

写在你的控制器上:

//For example --> browserLang = 'en-US'
var browserLang= Request.Headers["Accept-Language"].ToString().Split(";").FirstOrDefault()?.Split(",").FirstOrDefault();

【讨论】:

  • 丢弃优先级参数“q”是个坏主意。
【解决方案4】:

您必须添加本地化中间件以启用文化头解析,然后通过 IRequestCultureFeature 获取值。

查看此链接:https://github.com/aspnet/Mvc/issues/3549

【讨论】:

    【解决方案5】:

    也许我的解决方案对某人有用。不同之处在于,如果标头没有 Accept-Language,则使用默认语言。

    此代码适用于 NET 6。

    builder.Services.Configure<RequestLocalizationOptions>(config =>
    {
        CultureInfo en = new CultureInfo("en");
        CultureInfo ru = new CultureInfo("ru");
        var langs = new List<CultureInfo> { en, ru };
        config.DefaultRequestCulture = new RequestCulture(en);
        config.SupportedCultures = langs;
        config.SupportedUICultures = langs;
    });
    
    app.UseRequestLocalization();
    
    public IActionResult Index()
    {
        var languageRequest = HttpContext.Features.Get<IRequestCultureFeature>()?.RequestCulture.Culture.Name;
    
        // use switch with languageRequest or another your logic
    }
    

    另外,您不能使用 builder.Services.Configure,然后在 languageRequest 中您将收到语言的全名。例如:“en-En”、“ru-RU”等...

    【讨论】:

      猜你喜欢
      • 2018-03-29
      • 1970-01-01
      • 2023-03-08
      • 2012-08-04
      • 1970-01-01
      • 1970-01-01
      • 2019-04-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多