Простые представления 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 -->

Не уверен, что это лучше, чем использование фабричного шаблона, но мне кажется, что его проще всего реализовать и понять.

Я думаю, что вы можете создать свою собственную фабрику контроллеров, которая всегда будет создавать экземпляр одного и того же класса контроллеров.

Другие вопросы по тегам