2018-06-29 19:52:40 +02:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.Web.Mvc ;
using System.Web.Routing ;
using Umbraco.Core ;
using Umbraco.Core.Configuration ;
using Umbraco.Core.Composing ;
using Umbraco.Web.WebApi ;
namespace Umbraco.Web.Mvc
{
/// <summary>
/// A custom area for controllers that are plugins
/// </summary>
internal class PluginControllerArea : AreaRegistration
{
private readonly IGlobalSettings _globalSettings ;
private readonly IEnumerable < PluginControllerMetadata > _surfaceControllers ;
private readonly IEnumerable < PluginControllerMetadata > _apiControllers ;
private readonly string _areaName ;
/// <summary>
/// The constructor accepts all types of plugin controllers and will verify that ALL of them have the same areaName assigned to them
/// based on their PluginControllerAttribute. If they are not the same an exception will be thrown.
/// </summary>
/// <param name="globalSettings"></param>
/// <param name="pluginControllers"></param>
public PluginControllerArea ( IGlobalSettings globalSettings , IEnumerable < PluginControllerMetadata > pluginControllers )
{
_globalSettings = globalSettings ;
var controllers = pluginControllers . ToArray ( ) ;
if ( controllers . Any ( x = > x . AreaName . IsNullOrWhiteSpace ( ) ) )
{
throw new InvalidOperationException ( "Cannot create a PluginControllerArea unless all plugin controllers assigned have a PluginControllerAttribute assigned" ) ;
}
_areaName = controllers . First ( ) . AreaName ;
foreach ( var c in controllers )
{
if ( c . AreaName ! = _areaName )
{
throw new InvalidOperationException ( "Cannot create a PluginControllerArea unless all plugin controllers assigned have the same AreaName. The first AreaName found was " + _areaName + " however, the controller of type " + c . GetType ( ) . FullName + " has an AreaName of " + c . AreaName ) ;
}
}
//get the controllers
_surfaceControllers = controllers . Where ( x = > TypeHelper . IsTypeAssignableFrom < SurfaceController > ( x . ControllerType ) ) ;
_apiControllers = controllers . Where ( x = > TypeHelper . IsTypeAssignableFrom < UmbracoApiController > ( x . ControllerType ) ) ;
}
public override void RegisterArea ( AreaRegistrationContext context )
{
MapRouteSurfaceControllers ( context . Routes , _surfaceControllers ) ;
MapRouteApiControllers ( context . Routes , _apiControllers ) ;
}
public override string AreaName
{
get { return _areaName ; }
}
/// <summary>
/// Registers all surface controller routes
/// </summary>
/// <param name="routes"></param>
/// <param name="surfaceControllers"></param>
/// <remarks>
/// The routes will be:
///
/// /Umbraco/[AreaName]/[ControllerName]/[Action]/[Id]
/// </remarks>
private void MapRouteSurfaceControllers ( RouteCollection routes , IEnumerable < PluginControllerMetadata > surfaceControllers )
{
foreach ( var s in surfaceControllers )
{
var route = this . RouteControllerPlugin ( _globalSettings , s . ControllerName , s . ControllerType , routes , "" , "Index" , UrlParameter . Optional , "surface" ) ;
//set the route handler to our SurfaceRouteHandler
route . RouteHandler = new SurfaceRouteHandler ( ) ;
}
}
/// <summary>
/// Registers all api controller routes
/// </summary>
/// <param name="routes"></param>
/// <param name="apiControllers"></param>
private void MapRouteApiControllers ( RouteCollection routes , IEnumerable < PluginControllerMetadata > apiControllers )
{
foreach ( var s in apiControllers )
{
this . RouteControllerPlugin ( _globalSettings , s . ControllerName , s . ControllerType , routes , "" , "" , UrlParameter . Optional , "api" ,
isMvc : false ,
areaPathPrefix : s . IsBackOffice ? "backoffice" : null ) ;
}
}
}
}