我正在尝试将来自不同库的一些静态文件(css、图像、脚本)和一些视图共享给几个 MVC 应用程序,这是我的目录结构:
Solution
Directory 1
MyContent
css
site.css
images
img.png
MyViews
Account
Login.cshtml
Directory 2
MVCApp1
Directory 3
MVCApp2
这是我的 ResolveVppPath 方法:
public static string ResolveVppPath(string path)
{
// path before looks like ex. ~/shared/content/css/site.css
path = path.ToLower().Replace("~/shared/","~/my");
var vp = Path.GetFullPath(Path.Combine(HostingEnvironment.MapPath("~"), "../" + path));
// returns full path + ... /mycontent/css/site.css ...
return vp;
}
public static string ResolveSharedControllerPath(string path)
{
// path before looks like, "~/shared" is ommited in by routing ex. /content/css/site.css
path = "/my" + path.ToLower().TrimStart(new char[]{'/'})
var vp = Path.GetFullPath(Path.Combine(HostingEnvironment.MapPath("~"), "../" + path));
// returns full path + ... /mycontent/css/site.css ...
return vp;
}
最初的想法是创建抽象控制器,每个应用程序都将从该控制器继承一个控制器,它用于解析路径并从 dll 返回静态文件,整个工作正常,但我无法使用捆绑,因为文件不是物理的。
每个应用程序继承一次的抽象控制器:
public FilesController : Controller
{
public ActionResult(string path)
{
var vp = ResolveSharedControllerPath(path);
return File(path, MethodToGetMIMEType(path));
}
}
每个应用程序一次:
public SharedController : FilesController {}
路线:
routes.MapRoute(
"Shared",
"shared/{*path}",
new { controller = "Files", action = "Index" }
);
然后我了解到 System.Web.Optimization 的新 beta 版本支持从 VirtualPathProvider 捆绑(这是我第一次听说)。所以我创建了两个类:一个从 VPP 继承,一个从 VirtualFile 继承。
代码很长,但简而言之,因为我有物理文件,所以实现起来很容易,我的 Exists() 覆盖只需调用 File.Exist,Open 只是将它作为流打开,所以我设置:
BundleTable.VirtualPathProvider = new SharedVirtualPathProvider();
现在捆绑开始工作,我得到了要渲染的 css 和脚本。
但是我感觉文件是从我创建的用于提供文件的控制器中获取的,所以我尝试删除它并共享路由,因为让控制器同时提供文件和 VirtualPathProvider 是没有意义的。在我删除控制器包后停止工作并且我可以在 firebug 20 not found 请求中看到,所以我在 VPP 中放置断点以查看它是否被调用,并且我可以清楚地看到它在 VPP 和 GetFile 中调用 FileExists 方法并具有正确的路径并打开. 但是这个静态资源不能通过浏览器获得。
所以我决定将 IgnoreRoutes 用于具有静态扩展名的文件:
{file}.css
{file}.js
...etc
没运气...
由于那没有做任何事情,我包括控制器和路由 agian 来提供文件。一切又开始工作了。
下一步是将一些视图移动到 DLL,我将视图剪切并粘贴到 MyViewsDLL 但现在我在 "@model.." 的第一行的 firefox 中遇到 XML 解析错误,此外这无法正常工作,因为我不想要人们看到我的意见未呈现的代码。我还必须实现自定义 ViewEngine,它覆盖了引擎查找视图的路径,我补充说
"~/Shared/views/{1}/{0}
到路径,并将我的 ViewEngine 添加到 global.asax 中的 ViewEngines 集合中,我想这可能就是为什么 evrything 正在通过控制器,我也注册了我的 VirtualPathProvider 但没有任何改变
我的问题是:
我有 VPS 主机(所以我可以完全控制 IIS),我会在尝试从应用程序中向上文件夹(然后在 DLL 文件夹中)获取文件时遇到麻烦吗?
我真的需要 VPP 和 Controller 来返回静态文件吗?
我如何从 DLL 获取视图而不通过浏览器获得视图,以便任何人都可以看到它们?
我可以仅使用 VPP 提供静态文件吗?
更新:更新的目录结构