using System;
using System.Web.Mvc;
using System.Web.Routing;
using MvcContrib;
using MvcContrib.Filters;
namespace MvcContrib
{
///
/// SubController base class for subcontrollers. SubControllers can be infinitely nested.
///
[SubControllerActionToViewData]
public class SubController : Controller, ISubController
{
public virtual Action GetResult(ControllerBase parentController)
{
RequestContext requestContext = GetNewRequestContextFromController(parentController);
return () => Execute(requestContext);
}
///
/// Gets new RequestContext using objects from parent controller. This ensures subcontrollers have their own state that doesn't conflict with the parent.
///
///Parent controller
///RequestContext
public RequestContext GetNewRequestContextFromController(ControllerBase parentController)
{
RouteData parentRouteData = parentController.ControllerContext.RouteData;
var routeData = new RouteData(parentRouteData.Route, parentRouteData.RouteHandler);
string controllerName = GetControllerName();
routeData.Values["controller"] = controllerName;
routeData.Values["action"] = controllerName;
return new RequestContext(parentController.ControllerContext.HttpContext, routeData);
}
///
/// Gets the name from the type by trimming "controller" and "subcontroller" from the type name. The subcontroller action must match the controller name.
///
///
public string GetControllerName()
{
string typeNameLowered = GetType().Name.ToLowerInvariant();
int index = typeNameLowered.IndexOf("subcontroller");
if(index == -1)
{
index = typeNameLowered.IndexOf("controller");
}
if(index == -1)
{
return typeNameLowered;
}
return typeNameLowered.Substring(0, index);
}
}
///
/// SubController with generic Model property.
///
///
public class SubController : SubController, ISubController
{
public virtual T Model { get; set; }
}
}