If I have a service, IService
, that needs to access the Request or Response objects given by ControllerBase like I would in a controller:
[HttpGet]
public async Task<IActionResult> HelloWorldAsync() {
Response.Cookies.Append("Hello World", "Goodbye World");
return Ok();
}
How would I access Response
from within a service? What would I need to inject? Or do I need to resort to passing it through the method of the service, like so:
[HttpGet]
public async Task<IActionResult> HelloWorldAsync() {
await _myService.FooWithCookies(Response);
return Ok();
}
CodePudding user response:
If you need the Request
or the Response
then you may inject an IHttpContextAccessor
into you service through ctor injection.
public class YourService
{
private readonly IHttpContextAccessor httpContextAccessor;
public YourService(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
public void SomeMethod()
{
var response = httpContextAccessor.HttpContext.Response;
}
}
In your Startup.cs
file:
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
// rest is omitted for clarity.
}
CodePudding user response:
In your ConfigureServices
code, you'll want to ensure you're adding the HTTP Context accessor:
services.AddHttpContextAccessor();
And then in your service you can inject it:
public class MyService
{
private readonly IHttpContextAccessor _contextAccessor;
public MyService(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
public async Task FooWithCookies()
{
HttpRequest request = _contextAccessor.HttpContext.Request;
HttpResponse response = _contextAccessor.HttpContext.Response;
}
}
Note that IHttpContextAccessor
is registered as singleton, which can be useful in some situations.
See more info in the documentation: Use HttpContext from custom components
Depending on what your actual needs are, you might want to look at implementing a custom IActionResult
, which contains a method with the following signature:
public System.Threading.Tasks.Task ExecuteResultAsync (Microsoft.AspNetCore.Mvc.ActionContext context);
This gives you access to the context via ActionContext
, and also includes details of the specific action being executed.
Then FooWithCookies
could return it (e.g. return new MyActionResult(someConstructorParameter);
) and then you could simply pass it on in the action (e.g. return await _myService.FooWithCookies();
).