3

我正在尝试将来自不同库的一些静态文件(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 提供静态文件吗?

更新:更新的目录结构

4

1 回答 1

4

我的 EmbeddedResourceVirtualPathProvider 将帮助您。它允许在其他项目中拥有一些或所有静态文件和视图。

http://nuget.org/packages/EmbeddedResourceVirtualPathProvider/

您不需要控制器,VPP 和一些映射(由 Nuget 包在 web.config 中设置)就足够了。

编辑:我没有用 Bundler 测试过它,但我不明白为什么它不应该工作。

于 2013-05-23T12:56:14.590 回答