Asp.net mvc 在ASP.NETMVC中处理手册样式页面

Asp.net mvc 在ASP.NETMVC中处理手册样式页面,asp.net-mvc,razor,routing,asp.net-mvc-routing,Asp.net Mvc,Razor,Routing,Asp.net Mvc Routing,我已经建立了许多ASP.NETMVC站点,其中每个站点都有许多适合MVC控制器和操作的页面,还有一些页面实际上只是手册页面-/why、/why/ouradvantage、/about等等-这些页面没有真正的功能,只是一个视图,可能是一个布局,仅此而已 对于这些宣传册样式的页面,我真的更希望只有视图和找到它的好路线,这样我就可以将/why放在/宣传册/why.cshtml或/宣传册/why/Index.cshtml上,无论哪种方式都可以很好地找到它。我希望避免使用愚蠢的控制器和操作(就像我过去所做

我已经建立了许多ASP.NETMVC站点,其中每个站点都有许多适合MVC控制器和操作的页面,还有一些页面实际上只是手册页面-/why、/why/ouradvantage、/about等等-这些页面没有真正的功能,只是一个视图,可能是一个布局,仅此而已

对于这些宣传册样式的页面,我真的更希望只有视图和找到它的好路线,这样我就可以将/why放在/宣传册/why.cshtml或/宣传册/why/Index.cshtml上,无论哪种方式都可以很好地找到它。我希望避免使用愚蠢的控制器和操作(就像我过去所做的那样)来处理这组URL和页面

如何在ASP.NETMVC项目中实现这一点?这一定是一个共同的需要

编辑:我如何以详细的方式执行此操作的示例:

我可以使用标准的MVC路由({controller}/{action}/{id})和垃圾发送一堆无用的控制器来获得我想要的URL和页面集。每次我想添加宣传册样式(没有功能,只有视图)页面时,我都会添加一个控制器或操作,如下所示:

为什么选择控制器:

public class WhyController : Controller
{
    public ViewResult Index()
    {
        return View();
    }

    public ViewResult OurAdvantage()
    {
        return View();
    }
}
这将查看/why和/why/ouradvantage-clean URL。如果我想要一个/about页面,我可以添加另一个控制器,它只返回一个名为AboutController的视图。如果它有5个子页面,我可以向该控制器添加5个操作,所有这些操作都只返回一个视图

如果MVC站点中的这些小册子样式的页面达到100页,那么我会有很多不必要的控制器和操作,它们实际上什么都不做。不是很干。我感兴趣的是如何将视图放在我项目的一个文件夹中,并让它们可以访问(通过约定进行配置),在像/why和/why/ouradvantage这样干净的URL上

有几种方法可以让我接近:

我可以放入一堆.cshtml页面并直接访问它们,但是我必须在URL中有文件扩展名,并且视图文件本身必须位于根目录中

我可以使用ASP.Net区域为这些页面定义一个区域,但是所有手册样式的页面都必须至少有一个URL段深,而且我仍然存在上述URL中文件扩展名的问题

我可以定义一些疯狂的路线

我怀疑在MVC项目中经常会出现这种情况,因为MVC项目中有少量或大量的宣传册样式的页面——似乎应该有一种干净的方法来做到这一点

编辑:一个垃圾处理路由引擎的糟糕解决方案

创建映射路线的类,如:

public static void MapRoutes(RouteCollection routes, string appRoot, string path)
{
    if (!path.Contains("~/"))
        throw new NotSupportedException("Pages path must be virtual (use ~/ syntax).");

    var physicalPath = appRoot + path.Substring(2).Replace("/", "\\");

    var dir = new DirectoryInfo(physicalPath);
    var pages = dir.GetFiles("*.cshtml", SearchOption.AllDirectories);

    int rootLength = appRoot.Length;
    var rootParsed = pages.Select(p => "~/" + p.FullName.Substring(rootLength).Replace("\\", "/"));
    int folderPathLength = path.Length + 1;

    var mapped = rootParsed.Select(p => new {
        Url = p.Substring(folderPathLength, p.Length - 7 - folderPathLength),
        File = p
    });

    var routedPages = mapped.Select(m => routes.MapRoute(
        name: m.Url,
        url: "{*url}",
        defaults: new { path = m.File, Controller = "Brochure", Action = "Catchall" },
        constraints: new { url = m.Url }
    )).ToArray();
}
您可以在RouteConfig中调用它,如下所示:

BrochureRoute.MapRoutes(routes, Server.MapPath("~/"), "~/Brochure");
这显然将所有这些页面映射到一个小册子控制器,您也需要它:

public class BrochureController : Controller
{
    public ViewResult Catchall(string path)
    {
        return View(path);
    }
}
2个问题:

  • 正如我提到的,它会对路由引擎进行垃圾处理——如果你有100个页面,那么你就有100条路由
  • 如上所述传递路径似乎打乱了正常的Razor管道-以这种方式访问页面会导致如下错误:
  • “~/宣传册/About.cshtml”上的视图必须派生自WebViewPage

    可以使用映射单个页面的方法

    routes.MapPageRoute("", "why", "~/Brochure/Why.aspx");
    
    当然,您可以使用Razor视图引擎(.cshtml)而不是WebForms


    更新2

    您是对的。您将无法将此用于.cshtml页面。但是,您不需要使用路由来访问网页(.cshtml文件)。创建文件并在URL中省略扩展名就足够了。要实现所需的结构,您可以执行以下操作:

    • 您的web项目必须允许呈现网页。要启用此功能,请转到
      web.config
      并将
      webpages.Enabled
      设置为
      true
      。(
    • 添加名为
      ouradvantages.cshtml
      的MVC视图页面。可从
    • 您还可以使用
      @UrlData
      集合访问url数据
    更多关于此的信息。更多关于网页的一般信息

    如果出于某种原因确实需要使用路由,则需要自定义RouteHandler。您可以。此包的使用示例如下


    更新

    如果您希望避免手动添加每条路线,那么您几乎没有选择

    1)创建一个约定来标识手册页面

    默认情况下,您可以将URL预期为手册页面,并将“非手册”页面隔离到特定部分:

    routes.MapPageRoute("Default", "{brochurepage}", "~/Brochure/{brochurepage}.aspx");
    // isolate non-brochure pages to "site" section
    routes.MapRoute(
        "",
        "site/{controller}/{action}/{id}",                      // URL with parameters
        new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
    );
    
    2)将宣传册页面名称保存在收藏中

    List<string> brochurePages = new List<string>()
    { "about", "why", "contact" }; // add more pages here
    ....
    foreach (var brochurePage in brochurePages)
        routes.MapPageRoute("", brochurePage, "~/Brochure/" + brochurePage + ".aspx");
    
    列表手册页=新列表()
    {“关于”、“为什么”、“联系”};//在此处添加更多页面
    ....
    foreach(手册中的var手册页)
    routes.MapPageRoute(“,小册子页,~/宣传册/“+小册子页+”.aspx”);
    

    我必须非常具体的两个网址,你在你的问题中提到。要实现“/why”和“/why/ouradvantage”的路由,您将无法编写优雅的代码。这将需要特殊处理。

    可以使用映射单个页面的方法

    routes.MapPageRoute("", "why", "~/Brochure/Why.aspx");
    
    当然,您可以使用Razor视图引擎(.cshtml)而不是WebForms


    更新2

    您是对的。您将无法将此用于.cshtml页面。但是,您不需要使用路由来访问网页(.cshtml文件)。创建文件并在URL中省略扩展名就足够了。要实现所需的结构,您可以执行以下操作:

    • 您的web项目必须允许呈现网页。要启用此功能,请转到
      web.config
      并将
      webpages.Enabled
      设置为
      true
      。(
    • 添加名为
      ouradvantages.cshtml
      的MVC视图页面。可从
    • 您还可以使用
      @UrlData
      集合访问url数据
    更多关于此的信息。更多关于网页的一般信息

    如果出于某种原因确实需要使用路由,则需要自定义RouteHandler。您可以。此包的使用示例如下


    更新

    如果您希望避免手动添加