简体   繁体   中英

HttpContext.Current.Features.Get<IRequestCultureFeature>() is null in asp.net Core

I am trying to get the current culture from a user class in ASP.NET Core 1.1.

I have the following under ConfigureServices in Startup.cs :

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new List<CultureInfo>
    {
        new CultureInfo("en-US"),
        new CultureInfo("fil-PH")
    };

    options.DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US");
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;
});

I have the following under Configure in Startup.cs :

IHttpContextAccessor httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
Extensions.Context.Configure(httpContextAccessor);

IOptions<RequestLocalizationOptions>  localizationOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();
app.UseRequestLocalization(localizationOptions.Value);

I have the following user class:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Localization;
using System;
using System.Globalization;

namespace Framework.Extensions
{
    public class Context
    {
        public HttpContext Current { get; set; }
        public Uri AbsoluteUri { get; set; }
        public string AbsolutePath { get; set; }
        public string Url { get; set; }
        public CultureInfo Culture { get; set; }

        private static IHttpContextAccessor HttpContextAccessor;
        public static void Configure(IHttpContextAccessor httpContextAccessor)
        {
            HttpContextAccessor = httpContextAccessor;
        }

        public Context()
        {
            Current = HttpContextAccessor.HttpContext;
            AbsoluteUri = GetAbsoluteUri();
            AbsolutePath = GetAbsoluteUri().AbsolutePath;
            Url = GetAbsoluteUri().ToString();
            Culture = GetCultureInfo();
        }

        private Uri GetAbsoluteUri()
        {
            UriBuilder uriBuilder = new UriBuilder();
            uriBuilder.Scheme = Current.Request.Scheme;
            uriBuilder.Host = Current.Request.Host.Host.ToString();
            if (Current.Request.Host.Port != null)
            {
                uriBuilder.Port = Current.Request.Host.Port ?? default(int);
            }
            uriBuilder.Path = Current.Request.Path.ToString();
            uriBuilder.Query = Current.Request.QueryString.ToString();
            Uri absoluteUri = uriBuilder.Uri;
            return uriBuilder.Uri;
        }

        private CultureInfo GetCultureInfo() {
            IFeatureCollection requestFeatures = Current.Features; /* POPULATED */
            RequestCultureFeature requestCultureFeature = requestFeatures.Get<RequestCultureFeature>(); /* NULL */
            RequestCulture requestCulture = requestCultureFeature.RequestCulture;
            return requestCulture.Culture;
        }
    }
}

Looking at the GetCultureInfo() method, Current appears to be correctly populated with info as I can see things like the host and port, etc. Features is also populated - at least not null. But calling Get<RequestCultureFeature>() on the Features is null?

Any ideas at why this would be empty, and how to fix it?

The reason I am trying to access it is to get the CurrentUICulture.

Try creating a parameterized constructor in Context class with IOptions<RequestLocalizationOptions> and once you register the RequestLocalizationOptions for Dependency Injection Service inside ConfigureServices of Startup.cs , framework will provide the registered instance into the Context class.

As you suggested concluding our comments here in case if it would be useful for someone else as well.

if your UseRequestLocalization() is coming after the call for UseMvc() try to Call UseRequestLocalization() before UseMvc() . and use the following code

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

Looks like you aren't registering the RequestLocalizationMiddleware middleware:

app.UseRequestLocalization() is the extension method that should add the middleware, which will set the feature for you.

The right answer for the initial question has been provided by @shikyo:

The reason Get<RequestCultureFeature>() is null is because you need to use Get<IRequestCultureFeature>() the interface instead of the implementation.

The answer by @Siva-Gopal has some sense but the results are slightly different.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM