维护单个项目区域视图的解决方案
我只在单个项目领域尝试过这个。因此,如果有人在多项目区域解决方案中尝试此操作,请告诉我们。
MVC2 中添加了区域支持。但是,控制器的视图必须位于主视图文件夹中。我在这里提出的解决方案将允许您在每个区域中保留您的区域特定视图。如果您的项目结构如下,其中博客是一个区域。
+ Areas <-- folder
+ Blog <-- folder
+ Views <-- folder
+ Shared <-- folder
Index.aspx
Create.aspx
Edit.aspx
+ Content
+ Controllers
...
ViewEngine.cs
将此代码添加到 Global.asax.cs 中的 Application_Start 方法中。它将清除您当前的视图引擎并使用我们新的 ViewEngine 代替。
// Area Aware View Engine
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new AreaViewEngine());
然后创建一个名为 ViewEngine.cs 的文件并添加以下代码。
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web.Mvc;
namespace MyNamespace
{
public class AreaViewEngine : WebFormViewEngine
{
public AreaViewEngine()
{
// {0} = View name
// {1} = Controller name
// Master Page locations
MasterLocationFormats = new[] { "~/Views/{1}/{0}.master"
, "~/Views/Shared/{0}.master"
};
// View locations
ViewLocationFormats = new[] { "~/Views/{1}/{0}.aspx"
, "~/Views/{1}/{0}.ascx"
, "~/Views/Shared/{0}.aspx"
, "~/Views/Shared/{0}.ascx"
, "~/Areas/{1}/Views/{0}.aspx"
, "~/Areas/{1}/Views/{0}.ascx"
, "~/Areas/{1}/Views/Shared/{0}.aspx"
, "~/Areas/{1}/Views/Shared/{0}.ascx"
};
// Partial view locations
PartialViewLocationFormats = ViewLocationFormats;
}
protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
return new WebFormView(partialPath, null);
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
return new WebFormView(viewPath, masterPath);
}
} // End Class AreaViewEngine
} // End Namespace
这将查找并使用您在您的区域中创建的视图。
这是一种可能的解决方案,允许我将视图保留在指定区域。还有其他人有不同的、更好的、增强的解决方案吗?
谢谢
I have only tried this in single project areas. So if anyone tries this in a multi-project areas solution please let us know.
Area support was added to MVC2. However the views for your controllers have to be in your main Views folder. The solution I present here will allow you to keep your area specific views in each area. If your project is structured like below, with Blog being an area.
+ Areas <-- folder
+ Blog <-- folder
+ Views <-- folder
+ Shared <-- folder
Index.aspx
Create.aspx
Edit.aspx
+ Content
+ Controllers
...
ViewEngine.cs
Add this code to the Application_Start method in Global.asax.cs. It will clear your current view engines and use our new ViewEngine instead.
// Area Aware View Engine
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new AreaViewEngine());
Then create a file named ViewEngine.cs and add the code below.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web.Mvc;
namespace MyNamespace
{
public class AreaViewEngine : WebFormViewEngine
{
public AreaViewEngine()
{
// {0} = View name
// {1} = Controller name
// Master Page locations
MasterLocationFormats = new[] { "~/Views/{1}/{0}.master"
, "~/Views/Shared/{0}.master"
};
// View locations
ViewLocationFormats = new[] { "~/Views/{1}/{0}.aspx"
, "~/Views/{1}/{0}.ascx"
, "~/Views/Shared/{0}.aspx"
, "~/Views/Shared/{0}.ascx"
, "~/Areas/{1}/Views/{0}.aspx"
, "~/Areas/{1}/Views/{0}.ascx"
, "~/Areas/{1}/Views/Shared/{0}.aspx"
, "~/Areas/{1}/Views/Shared/{0}.ascx"
};
// Partial view locations
PartialViewLocationFormats = ViewLocationFormats;
}
protected override IView CreatePartialView(ControllerContext controllerContext, string partialPath)
{
return new WebFormView(partialPath, null);
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
return new WebFormView(viewPath, masterPath);
}
} // End Class AreaViewEngine
} // End Namespace
This will find and use the views you have created in your areas.
This is one possible solution that allows me to keep views in the specified area. Does anyone else have a different, better, enhanced solution?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我很抱歉成为第一个告诉你这一点的人,但你一定错过了一些东西。我目前使用 ASP.NET MVC 2 RC 开箱即用地使用您的场景。
我假设您拥有所有注册路由并在您所在区域的视图文件夹中拥有正确的 web.config 文件?
也许看看这个演练,特别是关于创建区域的部分。
HTH,
查尔斯
编辑:
好吧,所以你不高兴加入额外的
new { area = "blog' }, null
- 很公平,我承认它有点小......但是你还打算做什么 ?当你有两个同名的控制器,一个在一个区域或两个不同的区域有同名的控制器时,会发生什么?
另外,我怎么办 发现您的
ViewLocationFormats
存在问题。所有区域视图位置都没有引用其区域...例如~/Areas/{1}/Views/{0}.ascx - 它如何知道哪个区域?
如果您建议将所有不同区域的视图全部放入其控制器名称下的
Areas
文件夹中,然后在Views
下找到和Views/Shared
- 我强烈建议不要这样做......它很快就会变得一团糟,那么这会让你在创建路线时需要指定区域。归根结底,虽然指定区域很麻烦,但确实没有其他办法。
I'm sorry to be the one to tell you this, but you must be missing something. I currently have your scenario working out of the box with ASP.NET MVC 2 RC.
I assume you have all the register routes and have the correct web.config files inside your area's view folder?
Maybe have a look at this walk through, especially the part about creating the areas.
HTHs,
Charles
EDIT:
Ok, so you're not happy about putting in the extra
new { area = "blog' }, null
- fair enough, I'll admit its niggly... but what else are you going to do?What happens when you have two controllers with the same name? One in your root project and one in an area or two controllers with the same name in two different areas? How is it going to find the correct view?
Also, I do see a problem with your
ViewLocationFormats
. All of the area view locations have no reference to their area... e.g.~/Areas/{1}/Views/{0}.ascx
- how does it know what area?If you are suggesting that all the different area's views and all thrown into the
Areas
folder under their controller name and then found underViews
andViews/Shared
- I would highly recommend against that... It'll become a mess very quickly.So where does that leave you? It really leaves you needing to specify the area when creating the route. It really boils down to the fact that although it's niggly having to specify the area, there really is no other way.
该解决方案在 Mvc2 中运行良好。在Mvc3中没有必要。
This solution works well in Mvc2. It is not necessary in Mvc3.