Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you overload MVC Controllers to avoid repeating common code?

I'm working on a new MVC 5 project. It's a single multi tenanted site that allows many organisations and branches to maintain a page. All pages start with the following url format:

http://mysite.com/{organisation}/{branch}/...

For example:

http://mysite.com/contours/albany/...   
http://mysite.com/contours/birkenhead/...   
http://mysite.com/lifestyle/auckland/...   

I've declared my RouteConfig with the {organisation} and {branch} before the {controller} and {action}:

routes.MapRoute(
    name: "Default",
    url: "{organisation}/{branch}/{controller}/{action}/{id}",
    defaults: new { controller = "TimeTable", 
                    action = "Index", 
                    id = UrlParameter.Optional });

This is working just fine. However EVERY single controller now has identical code in the top of it that examines the organisation and branch.

public ActionResult Index(string organisation, string branch, string name, int id)
{
    // ensure the organisation and branch are valid
    var branchInst = _branchRepository.GetBranchByUrlPath(organisation, branch);
    if (branchInst == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    // start the real code here...
}

I'm keen on the DRY principle (Don't Repeat Yourself) and I'm wondering if it's possible to somehow isolate that common code and change my controller signatures to something like this:

public ActionResult Index(Branch branch, string name, int id)
{
    // start the real code here...
}
like image 937
Derek Tomes Avatar asked Dec 28 '25 01:12

Derek Tomes


1 Answers

You can create a common controller and have your other controllers inherit from it. For example:

public class YourCommonController : Controller
    {
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var organisation = filterContext.RouteData.Values["organisation"];
            var branch = filterContext.RouteData.Values["branch"];

            // Your validation code here

            base.OnActionExecuting(filterContext);
        }
    }

Now, just inherit from YourCommonController when you want to have this shared code.

like image 66
GvM Avatar answered Dec 31 '25 00:12

GvM