C# 如何使用MEF在MVC 3 Razor中呈现控件
首先是我的错误: 找不到类型或命名空间名称“Web”(是否缺少using指令或程序集引用?) } My_Layout.cshtmlC# 如何使用MEF在MVC 3 Razor中呈现控件,c#,asp.net-mvc-3,razor,mef,C#,Asp.net Mvc 3,Razor,Mef,首先是我的错误: 找不到类型或命名空间名称“Web”(是否缺少using指令或程序集引用?) } My_Layout.cshtml <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>@ViewBag.Title</title> <link href="@Url.Content("~/Content/Web.Plugins.Presentation
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Web.Plugins.Presentation/Site.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/Web.Plugins.Presentation/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/Web.Plugins.Presentation/modernizr-1.7.min.js")" type="text/javascript"></script>
</head>
<body>
<div class="page">
<header>
<div id="title">
<h1>My MVC Application</h1>
</div>
<div id="logindisplay">
@Html.Partial("_LogOnPartial")
</div>
<nav>
<ul id="menu">
@*<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>*@
@{
Html.Action("Menu", "Controls");
}
</ul>
</nav>
</header>
<section id="main">
@RenderBody()
</section>
<footer>
</footer>
</div>
@视图包。标题
我的MVC应用程序
@Html.Partial(“\u lognPartial”)
@*- @Html.ActionLink(“主页”、“索引”、“主页”)
- @ActionLink(“关于”、“关于”、“主页”)
*@
@{
动作(“菜单”、“控件”);
}
@RenderBody()
我的MefViewEngine.cs
public class MefViewEngine : RazorViewEngine
{
private readonly string _defaultMaster;
public MefViewEngine(string pluginPath, IEnumerable<IPluginRegistration> plugins, string defaultMaster)
{
_defaultMaster = defaultMaster;
CreateViewLocations(pluginPath, plugins);
}
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
// Set default master page
if (string.IsNullOrWhiteSpace(masterName) && !controllerContext.IsChildAction)
{
masterName = _defaultMaster;
}
// Ensure name is correct
if (masterName.ToLowerInvariant().EndsWith(".cshtml"))
{
masterName = masterName.ToLowerInvariant().Replace(".cshtml", string.Empty);
}
if (string.IsNullOrWhiteSpace(masterName))
{
return base.FindPartialView(controllerContext, viewName, useCache);
//masterName = _defaultMaster;
}
return base.FindView(controllerContext, viewName, masterName, useCache);
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
// If view isn't .aspx, remove master page
if (!viewPath.ToLowerInvariant().EndsWith(".cshtml"))
{
masterPath = string.Empty;
}
var nameSpace = controllerContext.Controller.GetType().Namespace;
//return base.CreateView(controllerContext, viewPath.Replace("%1", nameSpace), masterPath.Replace("%1", nameSpace));
return base.CreateView(controllerContext, viewPath, masterPath);
}
#region Helper Methods
private void CreateViewLocations(string pluginPath, IEnumerable<IPluginRegistration> plugins)
{
IList<string> viewLocations = new List<string>();
IList<string> masterLocations = new List<string>();
string pluginLocation;
foreach (IPluginRegistration plugin in plugins)
{
pluginLocation = string.Format("~/{0}/Views/{1}/", pluginPath, plugin.AssemblyName);
AddViewLocation(viewLocations, pluginLocation);
AddMasterLocation(masterLocations, pluginLocation);
}
pluginLocation = "~/Views/";
AddViewLocation(viewLocations, pluginLocation);
ViewLocationFormats = viewLocations.ToArray();
PartialViewLocationFormats = viewLocations.ToArray();
MasterLocationFormats = masterLocations.ToArray();
AreaViewLocationFormats = new[] {
"~/" + pluginPath + "/Views/{2}/{1}/{0}.cshtml",
"~/" + pluginPath + "/Views/{2}/{1}/{0}.cshtml",
"~/" + pluginPath + "/Views/{2}/Shared/{0}.cshtml",
"~/" + pluginPath + "/Views/{2}/Shared/{0}.cshtml",
};
AreaPartialViewLocationFormats = AreaViewLocationFormats;
AreaMasterLocationFormats = new[] {
"~/" + pluginPath + "/Views/{2}/{1}/{0}.cshtml",
"~/" + pluginPath + "/Views/{2}/Shared/{0}.cshtml",
};
}
private static void AddViewLocation(IList<string> viewLocations, string pluginLocation)
{
viewLocations.Add(pluginLocation + "{1}/{0}.cshtml");
viewLocations.Add(pluginLocation + "{1}/{0}.cshtml");
viewLocations.Add(pluginLocation + "Shared/{0}.cshtml");
viewLocations.Add(pluginLocation + "Controls/{0}.cshtml");
viewLocations.Add(pluginLocation + "Shared/{0}.cshtml");
}
private static void AddMasterLocation(IList<string> viewLocations, string pluginLocation)
{
viewLocations.Add(pluginLocation + "{0}.cshtml");
viewLocations.Add(pluginLocation + "{1}/{0}.cshtml");
viewLocations.Add(pluginLocation + "Shared/{0}.cshtml");
}
#endregion
}
公共类MefViewEngine:RazorViewEngine
{
私有只读字符串_defaultMaster;
公共MefViewEngine(字符串pluginPath、IEnumerable plugins、字符串defaultMaster)
{
_defaultMaster=defaultMaster;
CreateViewLocations(插件路径、插件);
}
public override ViewEngineResult FindView(ControllerContext ControllerContext、string viewName、string masterName、bool useCache)
{
//设置默认母版页
if(string.IsNullOrWhiteSpace(masterName)&&!controllerContext.IsChildAction)
{
主机名=_defaultMaster;
}
//确保名称正确
if(masterName.ToLowerInvariant().EndsWith(“.cshtml”))
{
masterName=masterName.ToLowerInvariant().Replace(“.cshtml”,string.Empty);
}
if(string.IsNullOrWhiteSpace(masterName))
{
返回base.FindPartialView(controllerContext、viewName、useCache);
//主机名=_defaultMaster;
}
返回base.FindView(controllerContext、viewName、masterName、useCache);
}
受保护的覆盖IView CreateView(ControllerContext ControllerContext、字符串视图路径、字符串主路径)
{
//如果视图不是.aspx,请删除母版页
如果(!viewPath.ToLowerInvariant().EndsWith(“.cshtml”))
{
masterPath=string.Empty;
}
var nameSpace=controllerContext.Controller.GetType().nameSpace;
//返回base.CreateView(controllerContext,viewPath.Replace(“%1”,命名空间),masterPath.Replace(“%1”,命名空间));
返回base.CreateView(controllerContext、viewPath、masterPath);
}
#区域辅助方法
私有void CreateViewLocations(字符串插件路径、IEnumerable插件)
{
IList viewLocations=新列表();
IList masterLocations=新列表();
字符串插入定位;
foreach(插件中的IPluginRegistration插件)
{
pluginLocation=string.Format(“~/{0}/Views/{1}/”,pluginPath,plugin.AssemblyName);
添加视图位置(视图位置、插件位置);
AddMasterLocation(主位置、插件位置);
}
pluginLocation=“~/Views/”;
添加视图位置(视图位置、插件位置);
ViewLocationFormats=viewLocations.ToArray();
PartialViewLocationFormats=viewLocations.ToArray();
MasterLocationFormats=masterLocations.ToArray();
AreaViewLocationFormats=新[]{
“~/”+pluginPath+“/Views/{2}/{1}/{0}.cshtml”,
“~/”+pluginPath+“/Views/{2}/{1}/{0}.cshtml”,
“~/”+pluginPath+“/Views/{2}/Shared/{0}.cshtml”,
“~/”+pluginPath+“/Views/{2}/Shared/{0}.cshtml”,
};
AreaPartialViewLocationFormats=AreaViewLocationFormats;
AreaMasterLocationFormats=新[]{
“~/”+pluginPath+“/Views/{2}/{1}/{0}.cshtml”,
“~/”+pluginPath+“/Views/{2}/Shared/{0}.cshtml”,
};
}
私有静态void AddViewLocation(IList viewLocations、字符串pluginLocation)
{
Add(pluginLocation+“{1}/{0}.cshtml”);
Add(pluginLocation+“{1}/{0}.cshtml”);
Add(pluginLocation+“Shared/{0}.cshtml”);
Add(pluginLocation+“Controls/{0}.cshtml”);
Add(pluginLocation+“Shared/{0}.cshtml”);
}
私有静态void AddMasterLocation(IList viewLocations、字符串pluginLocation)
{
Add(pluginLocation+“{0}.cshtml”);
Add(pluginLocation+“{1}/{0}.cshtml”);
Add(pluginLocation+“Shared/{0}.cshtml”);
}
#端区
}
是否已将所有名称空间添加到视图文件夹中的web.config?您还应该在您的区域中向web.config文件添加相同的引用(如果有)
您在Razor视图中创建和引用的任何名称空间都必须添加到元素中包含的名称空间集合。我不知道MEF,但从我对MVC的了解来看,您不应该返回PartialViewResult而不是操作结果吗
public virtual PartialViewResult Menu()
{
var builder = new MenuModelBuilder(Context.MenuContainer);
ViewData.Model = builder.BuildModel();
return PartialView();
}
我会调查的。我正在尝试一种新方法。我只是很困惑我创建的所有插件是如何工作的,除了我创建的只是为了显示菜单的部分视图的插件。这不是问题所在。所有名称空间都已包含,文件夹已添加到生成事件中。
ActionResult
是一个抽象类,其中PartialViewResult
是派生类之一。所以他没事,我还是不知道我做错了什么。最初的代码是为.NET2编写的,我正在将其转换为与.NET4和RazorViewEngine一起使用。我想我还有一点工作要做,但为了解决我眼前的问题,我回到了2.0版本,并放弃了Razor,发布了这个项目的beta版。我在更高版本中修改了代码,以完全使用razor viewengine,但使用了不同的MEF方法,因此我认为插件加载的方式解决了这个问题。当我得到一个完整的解决方案时,我会发布代码的链接。这个链接就是我问题的解决方案。非常好的文章,所以你会非常高兴。
public class MefViewEngine : RazorViewEngine
{
private readonly string _defaultMaster;
public MefViewEngine(string pluginPath, IEnumerable<IPluginRegistration> plugins, string defaultMaster)
{
_defaultMaster = defaultMaster;
CreateViewLocations(pluginPath, plugins);
}
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
// Set default master page
if (string.IsNullOrWhiteSpace(masterName) && !controllerContext.IsChildAction)
{
masterName = _defaultMaster;
}
// Ensure name is correct
if (masterName.ToLowerInvariant().EndsWith(".cshtml"))
{
masterName = masterName.ToLowerInvariant().Replace(".cshtml", string.Empty);
}
if (string.IsNullOrWhiteSpace(masterName))
{
return base.FindPartialView(controllerContext, viewName, useCache);
//masterName = _defaultMaster;
}
return base.FindView(controllerContext, viewName, masterName, useCache);
}
protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
{
// If view isn't .aspx, remove master page
if (!viewPath.ToLowerInvariant().EndsWith(".cshtml"))
{
masterPath = string.Empty;
}
var nameSpace = controllerContext.Controller.GetType().Namespace;
//return base.CreateView(controllerContext, viewPath.Replace("%1", nameSpace), masterPath.Replace("%1", nameSpace));
return base.CreateView(controllerContext, viewPath, masterPath);
}
#region Helper Methods
private void CreateViewLocations(string pluginPath, IEnumerable<IPluginRegistration> plugins)
{
IList<string> viewLocations = new List<string>();
IList<string> masterLocations = new List<string>();
string pluginLocation;
foreach (IPluginRegistration plugin in plugins)
{
pluginLocation = string.Format("~/{0}/Views/{1}/", pluginPath, plugin.AssemblyName);
AddViewLocation(viewLocations, pluginLocation);
AddMasterLocation(masterLocations, pluginLocation);
}
pluginLocation = "~/Views/";
AddViewLocation(viewLocations, pluginLocation);
ViewLocationFormats = viewLocations.ToArray();
PartialViewLocationFormats = viewLocations.ToArray();
MasterLocationFormats = masterLocations.ToArray();
AreaViewLocationFormats = new[] {
"~/" + pluginPath + "/Views/{2}/{1}/{0}.cshtml",
"~/" + pluginPath + "/Views/{2}/{1}/{0}.cshtml",
"~/" + pluginPath + "/Views/{2}/Shared/{0}.cshtml",
"~/" + pluginPath + "/Views/{2}/Shared/{0}.cshtml",
};
AreaPartialViewLocationFormats = AreaViewLocationFormats;
AreaMasterLocationFormats = new[] {
"~/" + pluginPath + "/Views/{2}/{1}/{0}.cshtml",
"~/" + pluginPath + "/Views/{2}/Shared/{0}.cshtml",
};
}
private static void AddViewLocation(IList<string> viewLocations, string pluginLocation)
{
viewLocations.Add(pluginLocation + "{1}/{0}.cshtml");
viewLocations.Add(pluginLocation + "{1}/{0}.cshtml");
viewLocations.Add(pluginLocation + "Shared/{0}.cshtml");
viewLocations.Add(pluginLocation + "Controls/{0}.cshtml");
viewLocations.Add(pluginLocation + "Shared/{0}.cshtml");
}
private static void AddMasterLocation(IList<string> viewLocations, string pluginLocation)
{
viewLocations.Add(pluginLocation + "{0}.cshtml");
viewLocations.Add(pluginLocation + "{1}/{0}.cshtml");
viewLocations.Add(pluginLocation + "Shared/{0}.cshtml");
}
#endregion
}
public virtual PartialViewResult Menu()
{
var builder = new MenuModelBuilder(Context.MenuContainer);
ViewData.Model = builder.BuildModel();
return PartialView();
}