5

我有一个使用 WebForms .Net 4.0 的解决方案。我计划在同一个解决方案中使用 MVC3。我关注了 Scott Hanselman的博客,事情进展顺利。

我不得不承认我对此很陌生。但是,我似乎错过了路由在命名空间方面的真正工作方式的很大一部分。

目前,我们的解决方案有:

WebApplicatin: 
  Accounting
      Receivables
         ReceivablesGrid.aspx
         ReceivableForm.aspx
      Payables
        PayablesGrid.aspx
        PayablesForm
 ..etc.

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

Domain/Accounting/Receivables/ReceivablesGrid.aspx
Domain/Accounting/Receivables/ReceivableForm.aspx?Key=1
Domain/Accounting/Payables/PayablesGrid.aspx
Domain/Accounting/Payables/PayablesForm.aspx?Key=1

……

我打算添加另一层来类似于 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.

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

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

我最终尝试的另一个解决方案是扩展 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"}. 

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

谢谢,

4

1 回答 1

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 中的使用。桑德森在他的个人博客上也有一篇类似的帖子,讨论了同样的话题。

于 2011-05-02T19:14:17.753 回答