使用WebForms进行MVC3路由

Sam*_*Sam 5 webforms hybrid asp.net-mvc-3

我有一个使用WebForms .Net 4.0的解决方案.我计划在同一解决方案中使用MVC3.我跟着Scott Hanselman的博客,事情很好.

我不得不承认我对此很陌生.但是,似乎我在路由器如何真正起作用的命名空间方面缺少很大的一部分.

目前,我们的解决方案有以下几点:

WebApplicatin: 
  Accounting
      Receivables
         ReceivablesGrid.aspx
         ReceivableForm.aspx
      Payables
        PayablesGrid.aspx
        PayablesForm
 ..etc.
Run Code Online (Sandbox Code Playgroud)

因此,您可以请求使用页面

Domain/Accounting/Receivables/ReceivablesGrid.aspx
Domain/Accounting/Receivables/ReceivableForm.aspx?Key=1
Domain/Accounting/Payables/PayablesGrid.aspx
Domain/Accounting/Payables/PayablesForm.aspx?Key=1
Run Code Online (Sandbox Code Playgroud)

....

我计划添加另一层类似于MVC.

WebApplicatin: 
      Accounting
          Receivables
             ReceivablesGrid.aspx
             ReceivableForm.aspx
             Mobile
              Controllers
                ReceivableConroller.cs
              Models
              Views
                Receivables
                   Index
                   Update
                   Edit
                   Create
          Payables
            PayablesGrid.aspx
            PayablesForm
            Mobile
              Controllers
                PayablesConroller.cs
              Models
              Views
                Payables
                   Index
                   Update
                   Edit
                   Create

     ..etc.
Run Code Online (Sandbox Code Playgroud)

当然,这不是真名.但是,我试图尽可能接近我的情况.不幸的是,如果我遵循这个是最好的,因为我可以使用可能在同一名称空间中添加的一些逻辑.此外,在根目录下创建类似于控制器,视图,模型的文件夹不适用于我的解决方案.

在Global.asax中,我添加了一条路线:

routes.MapRoute(
      "AccountingReceivablesMobile", // Route name
      "Accounting/Receivables/Mobile/{controller}/{action}/{id}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional });

routes.MapRoute(
      "AccountingPayablesMobile", // Route name
      "Accounting/Payables/Mobile/{controller}/{action}/{id}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional });
Run Code Online (Sandbox Code Playgroud)

我最终尝试的另一个解决方案是扩展RazorViewEngine.在新引擎的构造函数中,我设置了两个属性,如下所示:

base.ViewLocationFormats = new string[] { "~/Accounting/Receivables/Mobile/Views/{1}/{0}.cshtml",
"~/Accounting/Payables/Mobile/Views/{1}/{0}.cshtml"
 };

base.MasterLocationFormats = new[] { "~/Views/Shared/{0}.cshtml"}. 
Run Code Online (Sandbox Code Playgroud)

这很有效.但是,我只是觉得添加这些路由并不像添加webForm那样可扩展.我的问题是我真的不想为每条可能的路线添加路线.这意味着,当我添加新视图时,我会有另一个路径或数组条目.那么,我怎样才能使这更简单?我究竟做错了什么?我查看了区域,但它似乎强制创建一个区域文件夹并放入其中.

谢谢,

ada*_*kan 4

由于 ASP.NET MVC(以及 Rails 和许多其他 MVC 实现)依赖于配置约定,因此框架确实希望在站点根目录中包含\controllers\views和目录。\models您所做的让路由引擎发现您对约定的偏差的工作正是 MVC 试图阻止您做的事情。

您可以扩展框架的一部分,例如使用 Razor 引擎进行的测试...但就我个人而言,我接受框架的约定,这使得像您遇到的一些场景有点棘手,但我知道另一个开发人员拥有对 ASP.NET MVC 的简单了解可以立即打开代码并找到他们需要关注的区域。将这些基于约定的文件夹嵌套在其他文件夹下会使这一点变得不那么明显,除非它们被定义为 MVC 区域。

我有两个混合了 ASP.NET WebForms 和 MVC3 的生产解决方案。在这两种情况下,我都采用了默认方法(根目录中的控制器、模型、视图文件夹),并开始重构我的遗留 Web 表单代码库,以利用存储库模式等现代标准,并将通用业务逻辑转移到“服务”命名空间或解决方案中的新程序集。

通过退后一步重构代码以可能使用业务逻辑/存储库类的接口(我假设您目前没有这样做,因为大多数人不使用 Web 表单),您可以使用 Ninject 或另一个 IoC 容器来使遗留 Web 表单和 MVC 控制器中的逻辑连接变得更容易,从而允许更好的结构和单点关注点;通常在你的App_Start().

对于在命名空间之外的情况,using如果您针对另一个命名空间编写代码,ReSharper 或 CodeRush 等生产力工具将自动检测并填充您的语句。

我知道这不是您正在寻找的答案,有些可能会消失,但我认为退一步看看您想要解决的问题很重要。如果我没有时间/资源来重构一些遗留的业务逻辑或接受内置的约定,那么使 MVC 的基本架构复杂化以适应您的场景会促使我推迟;从几个简单的控制器开始,以消除 Web 表单应用程序中的痛点,然后在时间允许的情况下,开始将页面移植到 MVC。过渡时期可能并不美好,但会很简单。

这是一个非常好的问题,您通过扩展 Razor 很好地调查了您的选择。我很想知道是否有其他人有关于偏离标准 MVC 文件夹约定的想法。也许我只是挑剔?

如果您的主要最终目标是让您的网站支持移动设备,那么最后要检查的是Steve Sanderson 撰写的这篇文章。它利用出色的 51Degrees.mobi 程序集进行移动设备检测,并涵盖 ASP.NET 和 ASP.NET MVC 中的使用。桑德森在他的个人博客上也发表了一篇类似的文章,讨论了同一主题。