views:

1332

answers:

2

I'd like to get access to the current executing Controller so I can offload the return of the appropriate ActionResult onto a helper method. To this end, I'm looking for the equivalent of what I would have thought would be ControllerContext.Current but isn't. Thanks!

Edit for clarification: I've got a generic form control which is JavaScript-based but I'd like to add an option so that it works with noscript. At the moment my Controller sets the ViewData.Model to a JSON-ified Models.FormResponse<T>.

This FormReponse is set up with the status of the post and any error messages that were generated, so I'd like a GetActionResult() method which does the script/noscript check (a hidden form input) and either:

  1. Sets the Model to the JSONed FormResponse and returns a View(), or
  2. Serializes the FormResponse to the Session and returns a Redirect().

As this obviously changes the return value and I don't want to do the check myself every time, I need to call View or Redirect from the FormResponse's GetActionResult method in order to call this as:

return formResponse.GetActionResult();

I know with a more astronautical design this could be made even more robust but as the noscript option is not a major feature at the moment, I just need to get a quick solution working that doesn't break other things.

Update #2

The following, implemented in an ActionResult class, does the job for me. Thanks CVertex!

public override void ExecuteResult(ControllerContext context)
    {
        if (CMSEnvironment.NoScript)
        {
            Oracle.Response.Redirect(Oracle.Request.UrlReferrer.ToString(), true);
        }

        context.Controller.ViewData.Model = _model.ToJSON();

        new ViewResult()
        {
            ViewName = Areas.Site.Helpers.SharedView.Service,
            ViewData = context.Controller.ViewData
        }.ExecuteResult(context);
    }
+3  A: 

Statics are bad for testability, and very much discouraged in MVC.

Why do you want to access the current controller and action method?

The best way to do this is to implement your own ActionFilter. This gives you a means of intercepting requests before or after actions methods execute.

EDIT: By intercepting the result inside OnActionExecuted of a filter, you can do your noscript/script checks and modify your ViewData accordingly for consumption by the View. Inside OnActionExecuted, you can also do the noscript check and have complete control over the final ActionResult or the ViewData, as you please.

Or, you can write your own ActionResult that makes all these decisions. So, your controller action ultimately does

return new MyActionResult(format_and_view_agnostic_model_object);
CVertex
A: 

There doesn't appear to be a way to navigate to the current Controller from a thread. That is you could get the ControllerBuilder and you can get the MvcHttpHandler but neither then lets you access the controller instance that the handler is using.

AnthonyWJones