This question already has an answer here:
We are currently rewriting/converting our ASP.NET WebForms application using ASP.NET Core. Trying to avoid re-engineering as much as possible.
There is a section where we use HttpContext
in a class library to check the current state. How can I access HttpContext.Current
in .NET Core 1.0?
var current = HttpContext.Current;
if (current == null)
{
// do something here
// string connection = Configuration.GetConnectionString("MyDb");
}
I need to access this in order to construct current application host.
$"{current.Request.Url.Scheme}://{current.Request.Url.Host}{(current.Request.Url.Port == 80 ? "" : ":" + current.Request.Url.Port)}";
Necromancing.
YES YOU CAN, and this is how.
A secret tip for those migrating large
junkschunks of code:The following method is an evil carbuncle of a hack which is actively engaged in carrying out the express work of satan (in the eyes of .NET Core framework developers), but it works:
In
public class Startup
add a property
And then add a singleton IHttpContextAccessor to DI in ConfigureServices.
Then in Configure
add the DI Parameter
IServiceProvider svp
, so the method looks like:Next, create a replacement class for System.Web:
Now in Configure, where you added the
IServiceProvider svp
, save this service provider into the static variable "ServiceProvider" in the just created dummy class System.Web.HttpContext (System.Web.HttpContext.ServiceProvider)and set HostingEnvironment.IsHosted to true
this is essentially what System.Web did, just that you never saw it (I guess the variable was declared as internal instead of public).
Like in ASP.NET Web-Forms, you'll get a NullReference when you're trying to access a HttpContext when there is none, such as it used to be in
Application_Start
in global.asax.I stress again, this only works if you actually added
like I wrote you should.
Welcome to the ServiceLocator pattern within the DI pattern ;)
For risks and side effects, ask your resident doctor or pharmacist - or study the sources of .NET Core at github.com/aspnet, and do some testing.
Perhaps a more maintainable method would be adding this helper class
And then calling HttpContext.Configure in Startup->Configure
There is a solution to this if you really need a static access to the current context. In Startup.Configure(….)
And when you need it you can get it with :
I hope that helps. Keep in mind this workaround is when you don’t have a choice. The best practice is to use de dependency injection.
As a general rule, converting a Web Forms or MVC5 application to ASP.NET Core will require a significant amount of refactoring.
HttpContext.Current
was removed in ASP.NET Core. Accessing the current HTTP context from a separate class library is the type of messy architecture that ASP.NET Core tries to avoid. There are a few ways to re-architect this in ASP.NET Core.HttpContext property
You can access the current HTTP context via the
HttpContext
property on any controller. The closest thing to your original code sample would be to passHttpContext
into the method you are calling:HttpContext parameter in middleware
If you're writing custom middleware for the ASP.NET Core pipeline, the current request's
HttpContext
is passed into yourInvoke
method automatically:HTTP context accessor
Finally, you can use the
IHttpContextAccessor
helper service to get the HTTP context in any class that is managed by the ASP.NET Core dependency injection system. This is useful when you have a common service that is used by your controllers.Request this interface in your constructor:
You can then access the current HTTP context in a safe way:
IHttpContextAccessor
isn't always added to the service container by default, so register it inConfigureServices
just to be safe: