asp.net mvc将控制器放入一个单独的项目


107

我只是在学习asp.net mvc,并且试图弄清楚如何将控制器移动到单独的项目中。通常,当我之前设计过asp.net Web应用程序时,我为模型创建了一个项目,为逻辑创建了另一个项目,然后有了Web。

现在,我正在学习asp.net mvc,我希望遵循类似的模式,将模型和控制器分别放入各自的独立项目中,并将视图/脚本/ css留在网络中。模型部分很简单,但是我不了解的是如何“找到”我在单独项目中的控制器。另外,我想知道这是否明智。谢谢!

Answers:


92

首先,将模型放入一个单独的项目中肯定是一个好主意。正如您所发现的,这是微不足道的。

关于控制器和视图,对于大多数基本项目,我看不出将它们分开有任何明显的优势,尽管您可能需要在特定的应用程序中这样做。

如果确实选择执行此操作,则将需要告诉框架如何查找控制器。实现此目的的基本方法是提供自己的ControllerFactory。您可以查看DefaultControllerFactory的源代码,以了解实现方式。对此类进行子类化并重写GetControllerType(string controllerName)方法可能足以完成您所要的内容。

创建自己的自定义ControllerFactory后,将以下行添加到global.asax的Application_Start中,以告诉框架在哪里找到它:

ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());

更新:阅读此文章 及其链接到的文章以了解更多信息。另请参阅Phil Haack关于该帖子的评论:

ControllerBuilder.Current.DefaultNamespaces.Add(
    "ExternalAssembly.Controllers");

...这不是一个完整的解决方案,但对于简单的情况可能已经足够了。


2
谢谢克雷格!这正是我一直在寻找的东西。该信息甚至存在于网络上吗?运气不好,我一直在搜寻它。StackOverflow再次通过!
亚伦·帕尔默

11
我同意,控制器处理用户输入,操纵模型,然后将数据传递给视图。它们通常非常特定于应用程序。在库或模型中,并非特定于应用程序的任何逻辑都可能会更好。但是控制器通常应该与Web项目一起使用。
哈克

2
我有一个错误控制器,并且两个应用程序之间的视图相同。对我来说,将它们放在一个可以被两个应用程序使用的程序集中是很有意义的。
帆船柔道

3
这难道不是更容易测试控制器和使用的IoC当控制器是在一个单独的项目-这将是主要的原因
塞缪尔摹

1
@Chev,我认为那没有任何区别。控制器的可测试性与编码方式有关,而不与它们的居住地有关。
Craig Stuntz'2

19

尽管创建自己的ControllerFactory是合理的,但我发现在每个项目中定义所有Controller更为方便,但可以从Shared项目中的Controller派生它们:

namespace MyProject1.Controllers
{
   public class MyController : MySharedProject.Controllers.MyController
   {
      // nothing much to do here...
   }
}

namespace MySharedProject.Controllers
{
   public abstract class MyController : System.Web.Mvc.Controller
   {
      // all (or most) of my controller logic here...
   }
}

这样做还有一个好处,就是您可以放置​​一个控制器逻辑,该逻辑因项目而异。而且,其他开发人员更容易快速找到您的Controller逻辑,因为Controllers存在于标准位置。

关于这是否可取,我认为绝对是。我创建了一些常见的帐户管理逻辑,希望在项目之间共享这些逻辑,否则这些项目将具有非常不同的业务逻辑。因此,我共享我的“帐户”和“管理员”控制器,但其他控制器专用于它们各自的项目。


1
效果很好,但是我必须消除一些冗余代码以防止路由错误
Ken Mc13年

嗨,我如何管理此类项目中的路由?我想用属性路由...
محمد

您可以像平常一样使用属性路由。
ThisGuy

2
我想不知道为什么它没有更多的赞誉……比公认的答案要优雅得多。谢谢!
jleach

这对我不起作用。您能说一下这是.Net Core还是.Net Framework?
Homayoun Behzadian

4
  • 为您的mvc项目添加类库。
  • 在该类中添加以下代码(针对您的控制器代码)

    namespace ContactController
    {
    public class ContactController : Controller
    {
        public ActionResult Call()
        {
            ViewBag.Title = "Inside MyFirst Controller.";
            return View();
        }
    }

    }

  • 在mvc项目视图文件夹上,添加Contact文件夹并创建一个Call.cshtml文件。 查看文件夹

  • 将类库项目引用添加到您的主MVC项目中。

参考

  • 最后,将联系人控制器名称空间引用到路由配置中。

路由配置


3
不幸的是,您拥有与控制器同名的名称空间。
Mariusz Jamro'3


1

我使用的最简单的分离形式是在原始MVC项目中按原样保留Views,但删除Controllers。然后在一个新的ClassLibrary项目中添加Controller类,并确保它们从Controller继承。

MVC路由引擎将自动路由到ClassLibrary中的Controllers,并且Controllers将自动从原始MVC项目构造View,前提是您具有正确的引用和用法。

我正在使用此体系结构来实现可与主要解决方案分开编译和部署的Html Reports模块。最后,我摆脱了SSRS!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.