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

Can't resolve IHttpContextAccessor, IActionContextAccessor, IUrlHelper in RC2 #3936

Closed
ydogus opened this issue Jan 15, 2016 · 22 comments
Closed

Comments

@ydogus
Copy link

ydogus commented Jan 15, 2016

Hello,

I'm currently using the latest RC2 version (build 16854).
I can't inject some MVC special services (IHttpContextAccessor, IActionContextAccessor, IUrlHelper) into my controllers.

I searched but could not find anything about this. Did I misconfigure something? Or if I have to add them as services manually how can I do it?

@ydogus
Copy link
Author

ydogus commented Jan 15, 2016

Is this the proper way?

services.AddScoped<IHttpContextAccessor, HttpContextAccessor>();

And I think for IUrlHelper, I have to create the instance as new UrlHelper(actionContext)?

@davidfowl
Copy link
Member

Why would you need those services in you controller ? The http context and action context are available.

@ydogus
Copy link
Author

ydogus commented Jan 15, 2016

Oh, sorry. Actually I don't need them in my controller. I was just testing them there.

I have a service which needs IUrlHelper to create some urls and another service which is doing a little bit dirty things and needs the controller's name (I was getting it from ActionContext).
I also have a TagHelper using IUrlHelper.

@Eilon
Copy link
Member

Eilon commented Jan 15, 2016

@evorine can you show how you're trying to get the services? Are they constructor parameters of your tag helper?

@rynowak
Copy link
Member

rynowak commented Jan 15, 2016

We had to make IUrlHelper factory-based since it relies on state from the current request. Inject the IUrlHelperFactory instead

@Eilon
Copy link
Member

Eilon commented Jan 15, 2016

Ah indeed, need to depend on IUrlHelperFactory, from which you can get the IUrlHelper.

Closing this for now. If you can show some code that you think should work but doesn't, please let us know.

@Eilon Eilon closed this as completed Jan 15, 2016
@cwe1ss
Copy link
Contributor

cwe1ss commented Mar 9, 2016

Hi, I have the same problem. I would like to get access to HttpContext in a class. Injecting IHttpContextAccessor as a constructor parameter no longer works after the upgrade from RC1 to the daily builds. Should it work or is there a new way to get the context?

Same for IActionContextAccessor. We have an auditing class and I would like to get the ActionContext there.

@rynowak
Copy link
Member

rynowak commented Mar 9, 2016

You need to manually register these in your startup code.

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

@cwe1ss
Copy link
Contributor

cwe1ss commented Mar 9, 2016

ok great, thank you!

@Shazwazza
Copy link
Contributor

I require IUrlHelper mostly for the Content method and with this change it seems excessive because if I have a request scoped object, I'd need to inject IUrlHelperFactory and IActionContextAccessor just to create an IUrlHelper to access the Content method. I had a look at this method and it uses one single part of the request: Request.PathBase:

if (string.IsNullOrEmpty(path))
    return (string)null;
if ((int)path[0] == 126)
    return requestParts.PathBase.Add(new PathString(path.Substring(1))).Value;
return path;

I've created my own object with this copied logic to inject since it's much lighter so am wondering if maybe even a static method could be created on UrlHelper to contain this logic so we don't have to duplicate it? like:

public static string GetContentPath(string path, PathString requestPathBase)
{
    if (string.IsNullOrEmpty(path))
        return (string)null;
    if ((int)path[0] == 126)
        return requestParts.PathBase.Add(new PathString(path.Substring(1))).Value;
    return path;
}

which could then just be re-used by the non-static Content method?

@Eilon
Copy link
Member

Eilon commented May 20, 2016

@Shazwazza at this time that's not a method we're looking to introduce because we're concerned it might add more confusion around which method to call and what to pass in, and I'm not sure it's a particularly common scenario. In the meantime I recommend just having that code in your app (it's only a few lines anyway).

@Shazwazza
Copy link
Contributor

@Eilon no worries, i'll just keep the code in my app, thanks ! :)

@khellang
Copy link
Contributor

@Eilon @rynowak @davidfowl Think it would be a good idea to create an announcement on this (the removal of IHttpContextAccessor etc. by default)? There's quite a few issues popping up, asking why this changed and how to fix it.

@hikalkan
Copy link

hikalkan commented Jun 7, 2016

When I create a new project from "Web API" template, I can not inject IHttpContextAccessor, but if I create from "Web application" template, I can inject it. What is the difference? Both project has services.AddMvc(); in ConfigureServices method.

@Eilon
Copy link
Member

Eilon commented Jun 7, 2016

@Tratcher can we get an announcement posted for the issue that @khellang mentioned?

@Tratcher
Copy link
Member

Tratcher commented Jun 8, 2016

aspnet/Announcements#190

@Eilon
Copy link
Member

Eilon commented Jun 9, 2016

Thanks!

@khellang
Copy link
Contributor

khellang commented Jun 9, 2016

😁👍

@hikalkan
Copy link

hikalkan commented Jun 9, 2016

So, I answer my question: It's registered by Identity (aspnet/Hosting#793 (comment)).

kid-cavaquinho pushed a commit to voorhoede/dotnetcore-front-end-guide that referenced this issue Jul 21, 2016
@CGollhardt
Copy link

@rynowak regarding this post I am just wondering, why it could not be registered AddScoped<>()?

I am short before registering it myself, but want to be sure, I am not doing something realy bad.

@khellang
Copy link
Contributor

khellang commented Feb 12, 2018

@CGollhardt Because it's resolved as a singleton and assigned the HttpContext on each request. That will also let you inject it into your own singletons, while still accessing the HttpContext in request-scope, without capturing a request-scoped dependency.

See https://github.com/aspnet/HttpAbstractions/blob/f152b9863a5651755b8b9fef34e82a888562487e/src/Microsoft.AspNetCore.Http/HttpContextFactory.cs#L38-L42

Also, BTW, in 2.1, there's a helper method, AddHttpContextAccessor, to register the IHttpContextAccessor the correct way:

https://github.com/aspnet/HttpAbstractions/blob/d6a3c3f83e0abb54472f19103bf385ca9d8ead5f/src/Microsoft.AspNetCore.Http/HttpServiceCollectionExtensions.cs#L20-L29

@qJake
Copy link

qJake commented Jun 1, 2018

I googled the error that comes up and nothing came up, but found this thread via other means.

I'm including the original error so hopefully someone else Googling for this finds the answer:

System.InvalidOperationException: Cannot resolve 'Microsoft.AspNetCore.Http.IHttpContextFactory' from root provider because it requires scoped service 'Microsoft.AspNetCore.Http.IHttpContextAccessor'.

I originally had this line:

services.TryAddScoped<IHttpContextAccessor, HttpContextAccessor>();

I replaced it with:

services.AddHttpContextAccessor();

And that resolved the issue.

I'm going to open an issue on the 2.0 -> 2.1 migration page, this should be in the documentation. (Issue now opened here.)

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