Простые представления ASP.NET MVC без написания контроллера
Мы создаем сайт, который будет иметь минимальный код, в основном это будет просто набор статических страниц. Я знаю, что со временем это изменится, и мы захотим обменяться более динамичной информацией, поэтому я решил пойти дальше и создать веб-приложение, используя ASP.NET MVC2 и механизм представления Spark. Будет несколько контроллеров, которые должны будут выполнять реальную работу (как в области /products), но большинство из них будут статическими.
Я хочу, чтобы мой дизайнер мог создавать и изменять сайт, не прося меня написать новый контроллер или маршрут каждый раз, когда они решают добавить или переместить страницу. Поэтому, если он хочет добавить страницу " http://example.com/News", он может просто создать папку "Новости" в разделе "Представления" и поместить в нее страницу index.spark. Затем, если он решит, что ему нужна страница /News/Community, он может поместить файл community.spark в эту папку и заставить его работать.
Я могу иметь представление без определенных действий, заставляя мои контроллеры переопределять HandleUnknownAction, но мне все еще нужно создать контроллер для каждой из этих папок. Кажется глупым добавлять пустой контроллер и перекомпилировать каждый раз, когда они решают добавить область на сайт.
Есть ли способ сделать это проще, поэтому мне нужно только написать контроллер и перекомпилировать, если есть реальная логика, которую нужно сделать? Какой-то "главный" контроллер, который будет обрабатывать любые запросы, если не был определен конкретный контроллер?
5 ответов
Вы должны будете написать отображение маршрута для фактического контроллера / действий и убедиться, что по умолчанию индекс имеет значение как действие, а идентификатор - "catchall", и это будет сделано!
public class MvcApplication : System.Web.HttpApplication {
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "catchall" } // Parameter defaults
);
}
protected void Application_Start() {
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new CatchallControllerFactory());
}
}
public class CatchallController : Controller
{
public string PageName { get; set; }
//
// GET: /Catchall/
public ActionResult Index()
{
return View(PageName);
}
}
public class CatchallControllerFactory : IControllerFactory {
#region IControllerFactory Members
public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) {
if (requestContext.RouteData.Values["controller"].ToString() == "catchall") {
DefaultControllerFactory factory = new DefaultControllerFactory();
return factory.CreateController(requestContext, controllerName);
}
else {
CatchallController controller = new CatchallController();
controller.PageName = requestContext.RouteData.Values["action"].ToString();
return controller;
}
}
public void ReleaseController(IController controller) {
if (controller is IDisposable)
((IDisposable)controller).Dispose();
}
#endregion
}
Эта ссылка может помочь,
Если вы создадите cshtml в папке View\Public, он появится на веб-сайте с тем же именем. Я добавил также 404 страницы.
[HandleError]
public class PublicController : Controller
{
protected override void HandleUnknownAction(string actionName)
{
try
{
this.View(actionName).ExecuteResult(this.ControllerContext);
}
catch
{
this.View("404").ExecuteResult(this.ControllerContext);
}
}
}
Не могли бы вы создать отдельный контроллер для всех статических страниц и перенаправить на него все (кроме действительных контроллеров, которые работают), используя маршруты MVC, и включить параметры пути? Тогда в этом контроллере у вас может быть логика для отображения правильного представления на основе параметра папки / пути, отправленного ему маршрутами.
Несмотря на то, что я не знаю, как работает движок искрового представления, нужно ли его компилировать? Я действительно не уверен.
Размышляя об ответе Пола. Я не использую никаких специальных движков представления, но вот что я делаю:
1) Создать PublicController.cs.
// GET: /Public/
[AllowAnonymous]
public ActionResult Index(string name = "")
{
ViewEngineResult result = ViewEngines.Engines.FindView(ControllerContext, name, null);
// check if view name requested is not found
if (result == null || result.View == null)
{
return new HttpNotFoundResult();
}
// otherwise just return the view
return View(name);
}
2) Затем создайте общедоступный каталог в папке Views и поместите туда все ваши представления, которые вы хотите сделать общедоступными. Я лично нуждался в этом, потому что я никогда не знал, хочет ли клиент создавать больше страниц без перекомпиляции кода.
3) Затем измените RouteConfig.cs для перенаправления на действие Public/Index.
routes.MapRoute(
name: "Public",
url: "{name}.cshtml", // your name will be the name of the view in the Public folder
defaults: new { controller = "Public", action = "Index" }
);
4) Тогда просто сослаться на это с вашей точки зрения, как это:
<a href="@Url.RouteUrl("Public", new { name = "YourPublicPage" })">YourPublicPage</a> <!-- and this will point to Public/YourPublicPage.cshtml because of the routing we set up in step 3 -->
Не уверен, что это лучше, чем использование фабричного шаблона, но мне кажется, что его проще всего реализовать и понять.
Я думаю, что вы можете создать свою собственную фабрику контроллеров, которая всегда будет создавать экземпляр одного и того же класса контроллеров.