Skip to content
This repository has been archived by the owner on Nov 20, 2018. It is now read-only.

IHttpContextAccessor resolved as null #646

Closed
JakeGinnivan opened this issue Jun 1, 2016 · 18 comments
Closed

IHttpContextAccessor resolved as null #646

JakeGinnivan opened this issue Jun 1, 2016 · 18 comments

Comments

@JakeGinnivan
Copy link

I am using IdentityServer3 with dotnet core and am upgrading to RC2 and have hit a snag.

I have a custom user service which I want to resolve out of the aspnet core container. So I get access to the Request services like this:

var idsrvOptions = new IdentityServerOptions
{
    Factory = new IdentityServerServiceFactory
    {
        UserService = new Registration<IUserService>(r =>
        {
            var owin1 = r.Resolve<OwinEnvironmentService>();
            var httpContext1 = (HttpContext) owin1.Environment["Microsoft.AspNetCore.Http.HttpContext"];
            return httpContext1.RequestServices.GetService<CustomUserService>();
        })
    }
...

Not pretty, but I couldn't figure out how else to go from identity servers internal container to the request container without doing this. It calls into my factory fine:

services.AddScoped(p =>
{
    var httpContextAccessor = p.GetService<IHttpContextAccessor>();
    var portalOptions = p.GetService<IOptions<AuthenticationApiOptions>>();
    return new IdentityStoresApi(
        portalOptions,
        _portalApiHandler(),
        httpContextAccessor,
        _selfApiHandler);
});

Inside the AddScoped callback, httpContextAccessor is null. Any ideas what I have missed? The options are resolved fine.

@khellang
Copy link
Contributor

khellang commented Jun 1, 2016

In RC2, IHttpContextAccessor isn't registered by default. You have to register it yourself, explicitly; https://github.com/aspnet/Mvc/blob/dd774366f6fb18af9382ca84c276e6eb73c66b3a/test/WebSites/BasicWebSite/Startup.cs#L23

Related: aspnet/Razor#768, aspnet/Mvc#3936

I really think it's time there's an announcement for this... See aspnet/Mvc#3936 (comment) // @Eilon

@manikandan05
Copy link

Following is my startup.cs file code snippet

` public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

        services.AddMvc();
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
        //services.AddCaching();
        services.AddSession();
        // Add application services.
        services.AddTransient<IEmailSender, AuthMessageSender>();
        services.AddTransient<ISmsSender, AuthMessageSender>();
    }`

I'm unable to get Httpcontext in my static class

` public static class TestHelper
{
public static IHttpContextAccessor HttpContextAccessor;

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

public static string UrlFinder(this IHtmlHelper helper, string controlid)
{
HttpContextAccessor httpContextObj = new HttpContextAccessor();
//This line worked in RC1
var urlHelper = httpContextObj.HttpContext.RequestServices.GetRequiredService();
};
}

`

I already tried the steps said in following link comments

  1. Can't resolve IHttpContextAccessor, IActionContextAccessor, IUrlHelper in RC2 Mvc#3936
  2. HttpContext returns null for Httpcontextaccessor instance in RC2 Razor#768

Please help us to find out solution.

@khellang
Copy link
Contributor

khellang commented Jun 1, 2016

@manikandan05 You can't just create an instance of HttpContextAccessor and expect it to know about the current HttpContext. You need to get it from the container. That's why you're registering it.

@manikandan05
Copy link

manikandan05 commented Jun 1, 2016

Hi @khellang , I just want to get the urlHelper for my action. I tried out get the value from the below mentioned way.

var urlHelper = httpContextObj.HttpContext.RequestServices.GetRequiredService<IUrlHelper>();

@JakeGinnivan
Copy link
Author

@khellang so the behaviour of the DI in core is to return null when things are not registered rather than throw an error? That seems broken =/

I didn't even check for it not being registered because I assumed if something is not registered it would throw saying it cannot resolve.

@khellang
Copy link
Contributor

khellang commented Jun 1, 2016

@JakeGinnivan Yes, when calling GetService. If you want to make sure it throws for invalid configurations, you need to call GetRequiredService 😄

@khellang
Copy link
Contributor

khellang commented Jun 1, 2016

@manikandan05 I'm not sure what you're trying to do. You want to resolve IHtmlHelper from the services? You already have it as a parameter?

You could do something like

public static class TestHelper
{
    public static string UrlFinder(this IHtmlHelper helper, string controlid)
    {
        var httpContext = helper.ViewContext.HttpContext;

        // Do something with httpContext...
    }
}

BTW, it sounds like you want to get the URL for something. You know there's already a utility called IUrlHelper?

@JakeGinnivan
Copy link
Author

Sweet, i'm all sorted. will leave this issue open for @manikandan05

@JakeGinnivan
Copy link
Author

Gonna close this, @manikandan05's issue doesn't seem to be related.

@manikandan05
Copy link

Hi @JakeGinnivan, still i'm trying to resolve from my end. i didn't get solution for get the value from IUrlHelper in GetRequiredService<>()

@khellang
Copy link
Contributor

khellang commented Jun 2, 2016

@manikandan05 I suggest you file a separate issue with a good description of what you're trying to achieve and why it's not working. It doesn't seem related to this...

@manikandan05
Copy link

manikandan05 commented Jun 2, 2016

Hi @khellang, i have tried your solution also, but i'm cant escape from this UrlHelper. Now i have the face some other problem.

Please help to find out the solution.

@khellang
Copy link
Contributor

khellang commented Jun 2, 2016

I'd prefer not to download and unpack a random zip on my computer. Can you post it as a gist or something? Create a GitHub repo?

It would be nice if you could try to explain what you're trying to achieve. Or provide more info on what's wrong. 😄

@manikandan05
Copy link

Hi @khellang, I have posted my code snippet (gist) in the following online link.

https://gist.github.com/manikandan05/5fa6bc50ae739675834fa75ec5025024

@khellang
Copy link
Contributor

khellang commented Jun 2, 2016

@manikandan05 I've basically give you the solution above. Get the HttpContext from the IHtmlHelper: helper.ViewContext.HttpContext

@manikandan05
Copy link

ok @khellang , After HttpContext, i'm not further using RequestServices.GetRequiredService<>() get the UrlHelper value to call Action(controller,method). This is the issue form my starting point.

@khellang
Copy link
Contributor

khellang commented Jun 2, 2016

@manikandan05 I still can't remember reading what your original issue is. Are you not getting the IUrlHelper from the services? Can't you just create it? new UrlHelper(helper.ViewContext)

@manikandan05
Copy link

Hi @khellang, Thanks for your valuable suggestion. Now i got the solution 😄

Thanks...

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants