【问题标题】:Is it possible to access MVC Views located in another project?是否可以访问位于另一个项目中的 MVC 视图?
【发布时间】:2014-08-12 01:00:21
【问题描述】:

我想将我的 MVC 项目分成几个项目

首先,我创建了两个项目FrontViews

Front 项目是一个包含控制器和模型的 Web 应用程序

Views 项目是一个仅包含视图的类库项目

我的问题是如何让控制器调用位于 Views 项目中的视图

我有这样的控制器:

public ActionResult Default()
        {
            return this.View();
        }

【问题讨论】:

  • 你怎么把 MVC 分解成 MC & V 作为项目并使用 mvc 。我不会建议你这样做。
  • 我曾经在某家公司工作,他们有一个 mvc 项目,分为数千个项目、控制器项目、模型项目、视图项目、资源项目(包含样式和皮肤..)和服务项目。甚至视图项目,如果我记忆力好的话,根据用户代理和使用的设备分为很多项目。
  • @supercool 如果遵循某种架构或设计模式,有人可以这样做
  • ya ehsan 这也是可能的。但是让事情变得复杂
  • 貌似VS2017和MVC6支持这个stackoverflow.com/a/34360726/222748

标签: asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-4


【解决方案1】:

对于包含控制器,您需要更改路由注册以告诉他们在哪里寻找控制器:

routes.MapRoute(name: "Default", url: "{controller}/{action}/{id}",
                namespaces: new[] {"[Namespace of the Project that contains your controllers]"},
                defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional});

对于包含视图,创建自定义ViewEngine

public class CustomViewEngine: RazorViewEngine
{
    public CustomViewEngine()
    {
        MasterLocationFormats = new string[]
        {
            "~/bin/Views/{1}/{0}.cshtml",
            "~/bin/Views/{1}/{0}.vbhtml",
            "~/bin/Views/Shared/{0}.cshtml",
            "~/bin/Views/Shared/{0}.vbhtml"

        };
        ViewLocationFormats = new string[]
        {
             "~/bin/Areas/{2}/Views/{1}/{0}.cshtml",
             "~/bin/Areas/{2}/Views/{1}/{0}.vbhtml",
             "~/bin/Areas/{2}/Views/Shared/{0}.cshtml",
             "~/bin/Areas/{2}/Views/Shared/{0}.vbhtml"
        };
        .
        .
        .
    }
}
protected void Application_Start()
{
    ViewEngines.Engines.Add(new CustomViewEngine());

有关更多信息,请查看RazorViewEngin 的默认实现。

这里有一些不错的文章:

A Custom View Engine with Dynamic View Location

Using controllers from an external assembly in ASP.NET Web API

How to call controllers in external assemblies in an ASP.NET MVC application

How do I implement a custom RazorViewEngine to find views in non-standard locations?

Views in separate assemblies in ASP.NET MVC

【讨论】:

  • MvcCodeRouting 内置了embedded views 的功能,而不是自己创建。
  • 我们是否需要将外部程序集作为 MVC 项目?如果是类库,我需要包含哪些参考 dll?
  • @Mohsen Esmailpour 我们应该如何在 ViewLocationFormats 中引用特定的项目名称?例如,它像“Library2\Views\Accounts\List.cshtml”吗?
  • 链接已损坏
  • 添加了新链接@YahyaHussein
【解决方案2】:

MVC 不会将视图编译成 DLL,而是将它们作为文件从站点目录的根目录中引用。按照惯例,该位置是 ~/Views 并遵循搜索路径。这或多或少是硬编码到默认视图引擎中的。

因为视图是文件,所以当您将它们分解为一个单独的项目时,它们将不会存在于您的主 Web 应用程序项目中。因此,视图引擎找不到它们。当您编译应用程序时,任何引用的项目都只会复制 DLL(可能还有其他一些东西,如 pdb 等)

现在,有一些方法可以解决这个问题,但老实说,它们通常带来的麻烦多于其价值。您可以查看 mvc contrib 项目中的“Portable Areas”,但这些都没有得到很好的支持,并且有人谈论用 NuGet 打包替换它们。

您也可以按照@mo.esmp 的建议创建自定义视图引擎,但您仍然需要想办法将视图复制到站点在构建和/或部署时可以访问它们的位置。

我的建议是不要以您描述的方式分解项目。我看不出它有什么价值。如果您的项目变得如此之大,我会将您的代码分成多个区域,并将您的所有区域代码和数据放在一起。

将明显相互依赖的项目分成单独的程序集,而这些程序集的唯一目的是根据它们的目的收集东西,这有什么价值?我看到了将模型分离到他们自己的项目中的一些价值,因为模型可以被多个程序集使用。但是,控制器和视图仅由 MVC 主站点使用。

【讨论】:

  • 这是一个很好的见解,我完全同意你的看法erikI would instead separate your code into areas 说得好,我更喜欢相同的,即为业务逻辑创建一个单独的层并将服务方法调用到控制器。干杯
  • 分离控制器、视图、客户端脚本的一个原因可能是在其他项目中重用它们。例如,我有两个原本不相关的项目,都需要管理用户管理。
  • 这样做的一个很好的原因是使用了单页应用程序,该应用程序将由 MVC 提供服务并在其他地方(例如移动设备)使用。
  • 一个原因是拥有特定于一位客户的控制器和视图,因此您可以保持网站的通用性
  • @user2326106 - 我不认为你说的和我们一样。事实上,我不确定你在说什么。
【解决方案3】:

您可以预编译您的视图 - 这样它们就会包含在 dll 中,并且您可以从另一个项目中引用它们。

怎么做:

  1. 将视图移至另一个项目
  2. 在 Visual Studio 中安装 Razor Generator 扩展
  3. 将自定义工具更改为 RazorGenerator 观看次数
  4. 将 RazorGenerator.Mvc NuGet 包添加到视图项目
  5. 从您的主项目中参考视图项目

就是这样!

尽管您需要对模型做一些事情,但要么将它们与视图放在一起,要么为它们创建第三个项目 - 否则您将产生循环依赖。

另一个缺点是每个将使用视图的人都需要 Razor Generator 扩展。

这种工作方式基本上是您让 Visual Studio 在设计时从您的视图生成 .cs 文件,这些文件是已编译 dll 的一部分,与任何其他代码相同。

【讨论】:

  • 哦...很好。我想我要试试这个。你能再解释一下第 3 步吗?这是在哪里发生的?
  • 找到了!它在 cshtml 文件的属性中。
  • 听起来很有希望,但我只能找到带有 Nuget GUI 的 RazorEngine.Generator,这是不一样的,当我尝试从 marketplace.visualstudio.com/… 安装时,它说它找不到要安装的兼容产品虽然页面说它支持 VS 2013,这就是我正在使用的:(
  • 你提到你试图在 NuGets 中寻找扩展 - 它略有不同。您可以尝试在 Visual Studio 的“工具”>“扩展和更新”中的某处查找菜单项吗?我有不同的版本,所以我不完全确定它在 VS2013 中的同一个地方 - 但你应该寻找扩展和更新而不是 NuGet。
  • 谢谢,这点对我来说很好,问题完全解决了。
猜你喜欢
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
  • 2020-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多