Mike Flynn
Mike Flynn

Reputation: 24325

Get HttpRequestMessage from ActionFilter or ASP.NET MVC Web Controller outside of Web API

I am having a tuff time trying to get an instace of a HttpRequestMessage so I can pass it to the method GetCacheOutputProvider below from an ActionFilter and/or normal ASP.NET MVC Controller. I know I can from the Web API, but what about these instances.

public class CacheResetFilter : ActionFilterAttribute
    {
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            var cache = GlobalConfiguration.Configuration.CacheOutputConfiguration().GetCacheOutputProvider(HTTPREQUESTMESSAGE);
                cache.Contains("eventid=" + eventId);

            base.OnActionExecuted(filterContext);
        }

Upvotes: 7

Views: 6957

Answers (3)

Ashish Pandey
Ashish Pandey

Reputation: 21

I had the same issue in retrieving the httpRequestMessage and I went down a different route.

  1. Identify: Why am I using the httpRequestMessage for? - In my case, I was using to know if the request is an ajax request.

  2. Fix: Just replace the usages of httpRequestMessage's features with their counterparts.

How did I fix?

ActionExecutingContext doesn't have a way to retrieve httpRequestmessage, atleast none that I am aware of and I needed httpRequestmessage to obtain the headers "X-Requested-With".

Instead I used actionExecutedContext's HttpContext's headers property to see if i have these headers and that solved my issue on depending on httpRequestMessage.

I know this is not what you're looking for, but this gives a different view of solving this, so posting it here.

Thank you!

Upvotes: 0

SergGr
SergGr

Reputation: 23788

I don't think there is a simple way. You want an instance of HttpRequestMessage class which sematically represents a (current) request to WebAPI. But you are not inside WebAPI and don't handle any WebAPI requests. Thus it is logical that you can't easily have a valid instance of HttpRequestMessage (if you could, what URL would it point to?). IMHO the most obvious way to work this around is to use RegisterCacheOutputProvider method from CacheOutputConfiguration to inject your own cache provider that would return an instance of IApiOutputCache that you can directly access using other means (such as globally visible singleton). It looks there is only one standard implementation of IApiOutputCache: MemoryCacheDefault. So it looks like if you return it from your registered provider, you'll be OK.

If you want to be a more hacky, it looks like all MemoryCacheDefault instances internally use the same shared (static) field to do the actual work so you probably can just create new MemoryCacheDefault in your filter or controller and still be OK for now, but to me this sounds way to hacky comparing to the alternative from the first part of my answer.

Upvotes: 0

Ashiquzzaman
Ashiquzzaman

Reputation: 5284

1.In a MVC Controller you can do like:

public class HomeController : Controller
{
   public ActionResult Test()
        {
            HttpRequestMessage httpRequestMessage =
                HttpContext.Items["MS_HttpRequestMessage"] as HttpRequestMessage;
            return View();        
        }
 }

2.In action filter you can do like :

public class HttpRequestMessageAttribute : System.Web.Mvc.ActionFilterAttribute
{
    public override void OnActionExecuted(System.Web.Mvc.ActionExecutedContext filterContext)
    {
        HttpRequestMessage httpRequestMessage =
            filterContext.HttpContext.Items["MS_HttpRequestMessage"] as HttpRequestMessage;
        //var cache = GlobalConfiguration.Configuration.CacheOutputConfiguration().GetCacheOutputProvider(httpRequestMessage);
        //cache.Contains("eventid=" + eventId);

        base.OnActionExecuted(filterContext);
    }
}

OR

    public class HttpRequestMessageAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            HttpRequestMessage httpRequestMessage =
                filterContext.HttpContext.Items["MS_HttpRequestMessage"] as HttpRequestMessage;

            base.OnActionExecuting(filterContext);
        }
   }

Hopefully it's help for you.

Upvotes: 1

Related Questions