Simple ASP.NET MVC views without writing a controller

后端 未结 5 492
一整个雨季
一整个雨季 2021-01-04 10:50

We\'re building a site that will have very minimal code, it\'s mostly just going to be a bunch of static pages served up. I know over time that will change and we\'ll want

相关标签:
5条回答
  • 2021-01-04 11:22

    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.

    0 讨论(0)
  • 2021-01-04 11:25

    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
        }
    
    0 讨论(0)
  • 2021-01-04 11:26

    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.

    0 讨论(0)
  • 2021-01-04 11:34

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

    0 讨论(0)
  • 2021-01-04 11:47

    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);
                }
            }
        }
    
    0 讨论(0)
提交回复
热议问题