使用WebForms进行MVC3路由

时间:2011-04-23 00:02:59

标签: asp.net-mvc-3 webforms hybrid

我有一个使用WebForms .Net 4.0的解决方案。我计划在同一解决方案中使用MVC3。我跟着斯科特汉塞尔曼blog,事情正在发生变化。

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

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

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那样可扩展。我的问题是我真的不想为每条可能的路线添加路线。这意味着,当我添加新视图时,我会有另一个路径或数组条目。 那么,我怎样才能让这更简单?我做错了什么?我查看了区域,但它似乎强制创建一个区域文件夹并放入其中。

谢谢,

1 个答案:

答案 0 :(得分: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()

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

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

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

最后要检查的是,如果您的主要目标是让您的网站启用移动功能,那么Steve Sanderson就是this article。它利用优秀的51Degrees.mobi程序集进行移动设备检测,并涵盖ASP.NET和ASP.NET MVC中的使用。桑德森在他的个人博客上也有类似的帖子来讨论同一主题。