Я хочу написать DefaultControllerFactory, чтобы он обрабатывал все запросы, в том числе те, у которых нет совпадений по контроллеру / действию.
Я собираюсь написать Систему управления контентом (CMS) для обработки всех запросов, таких как http://somedomain.com/somepage/somesubpage, и она будет поддерживать любое количество доменов и страниц / подстраниц. Информация о домене и странице хранится в базе данных, и это означает, что у нее не будет соответствующего контроллера / действия. Поэтому я надеюсь создать свою собственную фабрику контроллеров, чтобы перенаправлять любые запросы без совпадения с контроллером / действием в CMSController для генерации содержимого страницы.
Мой собственный исходный код ControllerFactory, как показано ниже
public class STControllerFactory : DefaultControllerFactory
{
public STControllerFactory(
IControllerActivator controllerActivator,
IEnumerable<Microsoft.AspNetCore.Mvc.Internal.IControllerPropertyActivator> propertyActivators
)
: base(controllerActivator, propertyActivators)
{
}
public override object CreateController(ControllerContext context)
{
object baseController = null;
try
{
baseController = base.CreateController(context);
}
catch { }
if (baseController == null)
{
// If controller is not found, then redirect to a specific controller and action to look up from database for specific site and page and generate content response
}
return baseController;
}
}
А при запуске:
public void ConfigureServices(IServiceCollection services)
{
....
// We need essential Mvc services and DI support to host the template pages
services.AddMvc().AddControllersAsServices()
.AddJsonOptions( options =>
{
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
services.AddTransient<IControllerFactory, STControllerFactory>();
// We allow our routes to be in lowercase
services.AddRouting(options => options.LowercaseUrls = true);
...
// Cache 200 (OK) server responses; any other responses, including error pages, are ignored.
services.AddResponseCaching();
}
Моя предыдущая реализация в ASP.Net MVC работает должным образом:
public object CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
{
var controllerType = GetControllerType(requestContext, controllerName);
// This is where a 404 is normally returned
// Replaced with route to catchall controller
if (controllerType == null)
{
// Build the dynamic route variable with all segments
var dynamicRoute = string.Join("/", requestContext.RouteData.Values.Values);
// Route to the Catchall controller
requestContext.RouteData.Values["action"] = "Index";
controllerName = "CMS";
controllerType = GetControllerType(requestContext, controllerName);
requestContext.RouteData.Values["Controller"] = controllerName;
requestContext.RouteData.Values["dynamicRoute"] = dynamicRoute;
}
IController controller = GetControllerInstance(requestContext, controllerType);
return controller;
}
Хотя метод в ASP.Net MVC работает хорошо. Но теперь, переходя к Asp.Net MVC Core, исходный код в DefaultControllerFactory
вызывается, если контроллер / действие существует. Но сразу показывает страницу HTTP Error 404 без вызова метода CreateController
, если контроллер / действие не существует.