如何创建一个动态控制器来处理 ASP.NET MVC 中的许多静态视图



我有一堆大部分是静态的页面(大约 40 个),例如:订单表格01.html、订单表格02.html、订单表格03.html等。

它们中的每一个都应该有自己的控制器/操作,还是可以为所有这些控制器/操作提供一个动态控制器/操作?

我的 URL 应如下所示:http://MyProject/GlobalController/IndividualView,对于上面的例子:http://MyProject/OrderForm/order-form01、http://MyProject/OrderForm/order-form02 等。

提前谢谢。

是的,这很容易,你不需要 switch 语句或任何其他冗余逻辑。

public class MyController
{
  public ActionResult  Page(string file)
  {
    return View(file);
  }
}

神奇之处在于路线图:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        // New MapRoute for your 40+ files..
        routes.MapRoute(
            "OrdeForm",
            "OrderForm/{file}",
            new { controller = "MyController", action = "Page", {file} = "" }
        );
        routes.MapRoute(
            "Default",
            "{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = "" }
        );
    }

此外:

我在查询字符串中传递视图名称。

不是必需的,但受支持。 以下网址将起作用:

// Url Parameters
http://MyProject/OrderForm/order-form01
http://MyProject/OrderForm/order-form02
// Querystring Parameters
http://MyProject/OrderForm?file=order-form01
http://MyProject/OrderForm?file=order-form02

唯一的问题是您需要将html文件重命名为cshtml并将它们放在正确的目录中以供 ViewEngine 查找。

@Erik,我对 mvc 也有点陌生。您能否解释一下您的路线图,如何一次又一次地使用默认 raute

路由分为 3 个值

Controller
Action
Parameter(s)

至少需要控制器和操作。 值的来源不依赖于 URL。 例如,在以下 URL 和地图路线...

// Url
http://MyProject/
// MapRoute
routes.MapRoute(
  name: "Default",
  url: "{controller}/{action}/{id}",
  defaults: new { controller = "Home", action = "Index", id = "" }
);
// Controller named "Home" matches the default in the above route
// Method named "Index" matches the default in the above route
public class HomeController {
  public ActionResult Index() {
    return new EmptyResult();
  }
}

。一切仍然有效,因为我们为控制器和操作提供了默认值。

好的,让我们分解您想要的 URL:

http://MyProject/OrderForm/order-form01
http://MyProject/OrderForm/order-form02
http://MyProject/<identifier>/{parameter}

您有一个告诉我路由 (OrderForm) 的标识符和一个不断变化的值,因为它发生了变化并且您想要一个值,所以应该是一个参数。

http://MyProject/<identifier>/{file}

只要参数的名称与控制器方法的签名匹配,它就没有区别:

http://MyProject/{Controller}/{file}
public class HomeController {
  public ActionResult Index(string file) {
    return new EmptyResult();
  }
}

http://MyProject/{Controller}/{einstein}
public class HomeController {
  public ActionResult Index(string einstein) {
    return new EmptyResult();
  }
}

我命名了参数文件,因为它告诉我参数是一个文件的名称,而爱因斯坦这个名字没有固有的描述,所以对于变量来说是一个糟糕的名字。

http://MyProject/{Controller}/{file}
// MapRoute
routes.MapRoute(
  name: "Default",
  url: "{controller}/{action}/{id}",
  defaults: new { controller = "Home", action = "Index", id = "" }
);
// Controller named "Home" matches the default in the above route
// Method named "Index" matches the default in the above route
public class HomeController {
  public ActionResult Index() {
    return new EmptyResult();
  }
}

现在,我们只希望此路由在标识符为 OrderForm 时运行,因此我们不允许将其作为值,而是对其进行硬编码。

url: "OrderForm/...

接下来我们有一个不断变化的值,所以我们添加 url 参数:

url: "OrderForm/{file}"

现在我们遇到了一个问题,因为我们不允许 MVC 解析 url 中的值来填充控制器操作,因此我们必须提供它们。

routes.MapRoute(
  name: "",
  url: "OrderForm/{file}",
  defaults: new { controller = "Home", action = "Index", file = "" }
);

在这里,我们将 url http://MyProject/OrderForm/{file}映射到:

public class HomeController {
  public ActionResult Index(string file) {
    return new EmptyResult();
  }
}

现在,我将选择将默认值更新为更具体和更具描述性的内容:

routes.MapRoute(
  name: "",
  url: "OrderForm/{file}",
  defaults: new { controller = "OrderForm", action = "Index", file = "" }
);
public class OrderFormController {
  public ActionResult Index(string file) {
    return new EmptyResult();
  }
}

希望一切都有意义。

在问题编辑后:我的解决方案是,你可以有一个控制器/操作,它应该调用视图(cshtml)。您的查询字符串数据应作为 viewbag 变量传递到 view,并且应根据 viewbag 变量调用部分视图。甚至不需要编辑路由表(如果您愿意将其作为查询字符串传递)。

//your routeconfig will be
routes.MapRoute(
  name: "default",
  url: "{controller}/{file}",
  defaults: new { controller = "OrderForm", action = "Index", file = "" }
);
//here no need to have 40 routing table one is enough
//your controller/action will be
public class OrderForm
{
  public ActionResult  Index(string file)
  {
    ViewBag.Orderform=file
    return View(file);
  }
    }
//view bag variable is accessible in view as well as in javascript

但我想说的是,作为最佳实践,您可以修改默认路由以访问所有 url 并将其导航到相同的控制器/操作,然后让该操作返回视图。之后,使用角度/挖空js来处理客户端路由,并基于它加载部分视图。(对于您的 40 个页面,您的 URL 仍然会有所不同,但无需将其作为查询字符串传递)

//your route table will be
 routes.MapRoute(
      name: "default",
      url: "{controller}/{file}",
      defaults: new { controller = "OrderForm", action = "Index"}
    );
//your controller will be
 public class OrderForm
    {
      public ActionResult  Index()
      {
        return View(file);
      }

导航应由客户端路由处理

最新更新