4

I am trying to assign a response filter in the MVC OnActionExecuting event to modify the html outputted by the ActionResult of a Sitecore controller rendering. This works fine with plain MVC. However, in Sitecore, assigning a stream to the Response.Filter throws System.Web.HttpException: Filtering is not allowed.

Has anyone successfully implemented this in Sitecore?

public class UpperCaseFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Filter =
            new UpperCaseFilterStream(filterContext.HttpContext.Response.Filter);
    }
}
  • Are you trying to do this as a controller rendering or just a direct hit to the controller/action via MVC? – Richard Seal Nov 2 '16 at 21:07
  • This is as a controller rendering. With a direct hit, this works fine. I updated the question to reflect this. – Ben Verhees Nov 2 '16 at 21:08
  • What are you trying to achieve with this. Sitecore just takes the rendered output of each rendering and builds the rendered markup to send to the browser. You might need to do this different with a controller rendering. – Richard Seal Nov 2 '16 at 21:09
  • In this case I want to add an html attibute to the first html node in each rendering. I figured this would be a nice approach, as this would eliminate the need to modify each view, and makes it easier to toggle this feature by configuration. – Ben Verhees Nov 2 '16 at 21:11
  • Default MVC assumes one controller and one view (along with partials). Sitecore MVC allows calling multiple controllers for the same http request. I don't think you can apply action filters because the response has already started by the time you are getting to your rendering's controller. – sestocker Nov 3 '16 at 0:43
2

This is by design in Sitecore MVC, and Sitecore has provided alternative means to reach the same result. Instead of implementing filtering the standard "MVC way", you can hook into pipelines that Sitecore will invoke instead.

  • mvc.actionExecuting: Before invoking an MVC action method
  • mvc.actionExecuted: After invoking an MVC action method
  • mvc.exception: After an unhandled exception in an MVC request
  • mvc.resultExecuting: Before invoking the ExecuteResult() method of an ActionResult
  • mvc.resultExecuted: After invoking the ExecuteResult() method of an ActionResult

All of these pipelines are empty by default, but defined in Sitecore.Mvc.config.

Additional information:

| improve this answer | |
  • I tried this approach while finding a solution, unfortunately this gives the same exception. ActionFilters work just fine the standard MVC way e.g. using attributes, it's assigning a response filter that goes wrong. – Ben Verhees Nov 2 '16 at 22:47
0

Create a processor like this:

  public class MySampleFilterProcessor : ResultExecutedProcessor
    {
        public override void Process(ResultExecutedArgs args)
        {
            var response = args.Context.HttpContext.Response;

            if (response.Filter == null)
            {
                return;
            }

            response.Filter = new MySampleFilter(response.Filter, response.ContentEncoding);
        }
    }

Then register the processor mvc.resultExecuted pipeline

<mvc.resultExecuted>
        <processor type="MyNamespace.MySampleFilterProcessor , SampleAssembly"/>
</mvc.resultExecuted>
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.