Try this approach based on ControllerFactory, HttpModule:
Steps:
1 # Create a new class library project. Add a link to your asp.net mvc web application project. Also add a link to the assemblies "System.Web", "System.Web.Mvc", "Microsoft.Web.Infrastructure.dll".
2 # Create a new controller class inherited from the controller (TargetController), which has an error:
public class FixedContorller : TargetController { [FixedActionSelector] [ActionName("Index")] public ActionResult FixedIndex() { ViewBag.Title = "I'm Fixed..."; return View(); } }
[FixedActionSelectorAttribute] is an ActionSelector attribute used to resolve the name of an action.
public class FixedActionSelector : ActionMethodSelectorAttribute { public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo) { return true; } }
3 # Define a custom ControllerFactory that will create a fixed controller instead of the target controller:
public class MyControllerFactory : DefaultControllerFactory { private static string targetControllerName = "Target"; private static string targetActionName = "Index"; protected override Type GetControllerType(System.Web.Routing.RequestContext requestContext, string controllerName) { var action = requestContext.RouteData.Values["action"].ToString(); if (targetControllerName.Equals(controllerName, StringComparison.InvariantCultureIgnoreCase) && targetActionName.Equals(action, StringComparison.InvariantCultureIgnoreCase)) { return typeof(FixedContorller); } return base.GetControllerType(requestContext, controllerName); } }
4 # Now define an HttpModule that will install the above controller - factory in the init application. HttpModule will be registered programmatically, no need to register in web.config.
using System; using System.Web; using System.Web.Mvc; [assembly: PreApplicationStartMethod(typeof(YourApp.Patch.FixerModule), "Register")] namespace YourApp.Patch { public class FixerModule : IHttpModule { private static bool isStarted = false; private static object locker = new object(); public void Dispose() { } public void Init(HttpApplication context) { if (!isStarted) { lock (locker) { if (!isStarted) { ControllerBuilder.Current.SetControllerFactory(typeof(MyControllerFactory)); isStarted = true; } } } } public static void Register() { Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(FixerModule)); } } }
Compile the project and copy the DLL to the bin folder of your web application.
Hope this helps ...