I need to be able to access a value that I want to pass through to multiple DelegatingHandler (basically an ID for the entire request) and have available outside of the handlers as well (to add logging in Log4Net). I was thinking of using the global HttpContext
as a way to pass this info around, but I am wondering if that is a safe approach given the asynch nature of the DelegatingHandlers. Is this an appropriate concern and if it is, what is a better way to accomplish what I need?
Here is the code I have now - its simply a static class that I call when I need to get the id of the current request.
public static string GetCurrentContextid()
{
var ctx = HttpContext.Current;
if (ctx==null)
return null;
var val = ctx.Items["RequestId"];
if (val != null)
return val.ToString();
How do I get access to the Properties dictionary from a process that is not part of the WebApi pipeline? What I specifically need to do is set a GlobalContext in Log4Net.
log4net.GlobalContext.Properties["RequestcontextId"] = new ContextRequestProvider();
The ContextRequestProvider then has a simple ToString method that retrieves the ID I have stashed away in the context. I don't see how I can get access to the HttpRequestMessage property dictionary in this way. Sorry, I am new to WebApi and am finding
there are a lot of things that are close enough to the MVC way of doing things but different enough that its taking some getting used to.
Also, one last question, if two handlers are operating on different threads, will they still have the same Properties dictionary?
I was thinking of using the global HttpContext as a way to pass this info around, but I am wondering if that is a safe approach given the asynch nature of the DelegatingHandlers. Is this an appropriate concern and if it is, what is a better way to accomplish
what I need?
Using HttpContext is not recommended as it might not work in all host cases (i.e. self host, unit testing, etc). Instead, you should use HttpRequestMessage.Properties to stash per-request data.
You might want to look at creating a LogActionFilter : ActionFilterAttribute to handle your logging. Filters give you access to the Properties dictionary and therefore you could populate the log4net properties as needed.
It is my understanding that the HttpRequestMessage only has an affinity to the request and not the underlying the thread. The request would contain the same dictionary over mutlitple threads.
>>>> Using HttpContext is not recommended as it might not work in all host cases (i.e. self host, unit testing, etc). Instead, you should use HttpRequestMessage.Properties to stash per-request data.
Are there other problems inherent in the use of HttpContext from WebAPI. For this particular purpose, its only ever going to be used with the WebApi (of course, until someone tells me otherwise next week - LOL), and I don't care about unit testing this.
I am more concerned with thread safety issues.
You might want to look at creating a LogActionFilter : ActionFilterAttribute to handle your logging. Filters give you access to the Properties dictionary and therefore you could populate the log4net properties as needed.
Thanks, its good to know that there may not be any threading issues with it. The problem is that the LogActionFilter is going to be too broad stroked for me as it can only control what's going in and out of the method and not what is occuring within it.
I guess I can create a custom log handler to use from within controllers that refer to HttpRequestMessage and wrap the call to Log4Net. I think that's what I'll try next.
Are there other problems inherent in the use of HttpContext from WebAPI. For this particular purpose, its only ever going to be used with the WebApi (of course, until someone tells me otherwise next week - LOL), and I don't care about unit testing this. I
am more concerned with thread safety issues.
Would you ever self-host this api? If so, this is another reason to stay away from HttpContext.
Would you ever self-host this api? If so, this is another reason to stay away from HttpContext.
No, probably won't ever self host this app. So if its only the self-host argument and the bad for UnitTesting argument, I think I may stick with HttpContext.
Oh well, I can't use HttpContext anyway. It seems to change during the entire request - not sure if its thread related or something else - but the HttpContext is null when the response is being processed. Does it look like I am handling SendAsynch properly
below? The line that is bolded is the one where HttpContext no longer exists and is null.
alex.gadea
Member
27 Points
19 Posts
Safe to call HttpContext from Delegating Handler?
Feb 28, 2012 06:35 PM|LINK
I need to be able to access a value that I want to pass through to multiple DelegatingHandler (basically an ID for the entire request) and have available outside of the handlers as well (to add logging in Log4Net). I was thinking of using the global HttpContext as a way to pass this info around, but I am wondering if that is a safe approach given the asynch nature of the DelegatingHandlers. Is this an appropriate concern and if it is, what is a better way to accomplish what I need?
Here is the code I have now - its simply a static class that I call when I need to get the id of the current request.
public static string GetCurrentContextid()
{
var ctx = HttpContext.Current;
if (ctx==null)
return null;
var val = ctx.Items["RequestId"];
if (val != null)
return val.ToString();
return null;
}
davebettin
Member
313 Points
94 Posts
Re: Safe to call HttpContext from Delegating Handler?
Feb 28, 2012 06:57 PM|LINK
I would stay away from HttpContext.Current, unit testing becomes the bane of your existence when you start using this approach.
The HttpRequestMessage Properties dictionary is exactly what you need; you can set/get properties from both your handlers and actions.
Cheers,
Dave
@dbettin
alex.gadea
Member
27 Points
19 Posts
Re: Safe to call HttpContext from Delegating Handler?
Feb 28, 2012 07:15 PM|LINK
How do I get access to the Properties dictionary from a process that is not part of the WebApi pipeline? What I specifically need to do is set a GlobalContext in Log4Net.
log4net.GlobalContext.Properties["RequestcontextId"] = new ContextRequestProvider();
The ContextRequestProvider then has a simple ToString method that retrieves the ID I have stashed away in the context. I don't see how I can get access to the HttpRequestMessage property dictionary in this way. Sorry, I am new to WebApi and am finding there are a lot of things that are close enough to the MVC way of doing things but different enough that its taking some getting used to.
Also, one last question, if two handlers are operating on different threads, will they still have the same Properties dictionary?
Thanks,
Alex
marcind
Contributor
3344 Points
609 Posts
Microsoft
Re: Safe to call HttpContext from Delegating Handler?
Feb 28, 2012 07:16 PM|LINK
Using HttpContext is not recommended as it might not work in all host cases (i.e. self host, unit testing, etc). Instead, you should use HttpRequestMessage.Properties to stash per-request data.
ASP.NET Team
@marcind
Blog
davebettin
Member
313 Points
94 Posts
Re: Safe to call HttpContext from Delegating Handler?
Feb 28, 2012 07:25 PM|LINK
You might want to look at creating a LogActionFilter : ActionFilterAttribute to handle your logging. Filters give you access to the Properties dictionary and therefore you could populate the log4net properties as needed.
It is my understanding that the HttpRequestMessage only has an affinity to the request and not the underlying the thread. The request would contain the same dictionary over mutlitple threads.
Cheers,
Dave
@dbettin
alex.gadea
Member
27 Points
19 Posts
Re: Safe to call HttpContext from Delegating Handler?
Feb 28, 2012 07:55 PM|LINK
>>>> Using HttpContext is not recommended as it might not work in all host cases (i.e. self host, unit testing, etc). Instead, you should use HttpRequestMessage.Properties to stash per-request data.
Are there other problems inherent in the use of HttpContext from WebAPI. For this particular purpose, its only ever going to be used with the WebApi (of course, until someone tells me otherwise next week - LOL), and I don't care about unit testing this. I am more concerned with thread safety issues.
alex.gadea
Member
27 Points
19 Posts
Re: Safe to call HttpContext from Delegating Handler?
Feb 28, 2012 07:59 PM|LINK
davebettin
Member
313 Points
94 Posts
Re: Safe to call HttpContext from Delegating Handler?
Feb 28, 2012 08:05 PM|LINK
Would you ever self-host this api? If so, this is another reason to stay away from HttpContext.
@dbettin
alex.gadea
Member
27 Points
19 Posts
Re: Safe to call HttpContext from Delegating Handler?
Feb 28, 2012 09:45 PM|LINK
No, probably won't ever self host this app. So if its only the self-host argument and the bad for UnitTesting argument, I think I may stick with HttpContext.
alex.gadea
Member
27 Points
19 Posts
Re: Safe to call HttpContext from Delegating Handler?
Feb 28, 2012 10:16 PM|LINK
Oh well, I can't use HttpContext anyway. It seems to change during the entire request - not sure if its thread related or something else - but the HttpContext is null when the response is being processed. Does it look like I am handling SendAsynch properly below? The line that is bolded is the one where HttpContext no longer exists and is null.
protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
// Do stuff with request here
var response = base.SendAsync(request, cancellationToken);
response.ContinueWith((responseMsg) =>{
var responseLoggingInfo = ExtractResponseLoggingInfo(responseMsg.Result);
});
return response;
}