filipw / Strathweb.CacheOutput

ASP.NET Web API CacheOutput - library to allow you to cache the output of ApiControllers
Other
882 stars 253 forks source link

WebAPI2: Controller GET action with return type IHttpResultAction fails with System.NullReferenceException #99

Closed brunosfernandes closed 9 years ago

brunosfernandes commented 10 years ago

Hello Filip, I have a controller GET action that returns IHttpResultAction decorated with CacheOutput attribute. When i try to execute the GET request i get the a System.NullReferenceException:

"Object reference not set to an instance of an object." at WebApi.OutputCache.V2.CacheOutputAttribute.GetExpectedMediaType(HttpConfiguration config, HttpActionContext actionContext)

So i have grabbed your source code from github. The problem is the content negotiator result is null when the return type of the action is a IHttpActionResult. I have changed the GetExpectedMediaType in the CacheOutputAttribute class and it worked like a charm:

        protected virtual MediaTypeHeaderValue GetExpectedMediaType(HttpConfiguration config, HttpActionContext actionContext)
        {
            MediaTypeHeaderValue responseMediaType = null;

            var negotiator = config.Services.GetService(typeof(IContentNegotiator)) as IContentNegotiator;
            var returnType = actionContext.ActionDescriptor.ReturnType;

            if (negotiator != null && returnType != typeof(HttpResponseMessage))
            {
                var negotiatedResult = negotiator.Negotiate(returnType, actionContext.Request, config.Formatters);
                if (negotiatedResult != null)
                {
                    responseMediaType = negotiatedResult.MediaType;                
                    if (string.IsNullOrWhiteSpace(responseMediaType.CharSet))
                    {
                        responseMediaType.CharSet = Encoding.UTF8.HeaderName;
                    }
                }
                else
                {
                    return DefaultMediaType;
                }
            }
            else
            {
                if (actionContext.Request.Headers.Accept != null)
                {
                    responseMediaType = actionContext.Request.Headers.Accept.FirstOrDefault();
                    if (responseMediaType == null ||
                        !config.Formatters.Any(x => x.SupportedMediaTypes.Contains(responseMediaType)))
                    {
                        return DefaultMediaType;
                    }
                }
            }

            return responseMediaType;
        }

Please let me know i this is ok.

Regards, BrunoF

mackayj commented 10 years ago

Works great for me as well, I ran into the same issue. Thank you so much for tracking this down! Do you know how to create a pull request for it?

brunosfernandes commented 10 years ago

It's done. Thanks for your feedback.

goldytech commented 10 years ago

Is the nuget package not updated after this fix ?I get the same error after I downloaded the library from the nuget package manager

mackayj commented 10 years ago

@goldytech Hey just replied to you on the other cache github. You'll need to go to the pull requests section and compile it from there. It hasn't been merged by the main developer for this yet :(.

I have a pull request in which fixes quite a few problems if you want to try it out.

https://github.com/mackayj/AspNetWebApi-OutputCache/commit/c98314b9e1ba2578dfe462419cfc497d4838cbb4?w=1

You'll need to download the latest master, and then make those changes yourself, or download directly from my github fork here: https://github.com/mackayj/AspNetWebApi-OutputCache if you don't want to manually merge.

jfritchman commented 10 years ago

@filipw Is there a time frame for when you might be able to review the changes by @mackayj ?

filipw commented 9 years ago

closed by #138