Simple ASP.NET MVC views without writing a controller

我们两清 提交于 2019-11-30 18:42:42

You will have to write a route mapping for actual controller/actions and make sure the default has index as an action and the id is "catchall" and this will do it!

    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
    }

This link might be help,

If you create cshtml in View\Public directory, It will appears on Web site with same name. I added also 404 page.

[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);
            }
        }
    }

Couldn't you create a separate controller for all the static pages and redirect everything (other than the actual controllers which do work) to it using MVC Routes, and include the path parameters? Then in that controller you could have logic to display the correct view based on the folder/path parameter sent to it by the routes.

Allthough I don't know the spark view engine handles things, does it have to compile the views? I'm really not sure.

Reflecting on Paul's answer. I'm not using any special view engines, but here is what I do:

1) Create a 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) Then create a Public directory in the Views folder, and put all of your views there that you want to be public. I personally needed this because I never knew if the client wanted to create more pages without having to recompile the code.

3) Then modify RouteConfig.cs to redirect to the Public/Index action.

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) Then just reference it from your views like this:

<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 -->

Not sure if this is any better than using a factory pattern, but it seems to me the easiest to implement and to understand.

I think you can create your own controller factory that will always instantiate the same controller class.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!