使用预编译时从App_Themes提供图像时出错? [英] Getting an error serving images from App_Themes when using precompilation?

查看:94
本文介绍了使用预编译时从App_Themes提供图像时出错?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ASP.NET站点,其中包含WebForms和MVC部分.当我尝试对网站进行预编译时,除了在App_Themes下提供图片/css之外,其他所有内容都可以正常工作.

I have an ASP.NET site with both WebForms and MVC sections to it. When I try to precompile the site, everything works except serving images/css from under App_Themes.

如果我请求类似/foo/App_Themes/themeName/my.png的内容,则会出现此错误:

If I request something like /foo/App_Themes/themeName/my.png, I get this error:

The file '/foo/App_Themes/themeName/my.png.cshtml' is in the special directory 'App_Themes', which is not allowed.

我只能在预编译时得到它,否则它可以正常工作.大概MVC路由会以某种方式干扰,但我不知道为什么或如何禁用它.

I only get this when precompiling, it works fine otherwise. Presumably MVC routing is interfering somehow, but I don't know why or how to disable it.

如果有帮助,这是堆栈跟踪:

In case it's helpful, here's the stack trace:

System.Web.Compilation.BuildManager.ValidateVirtualPathInternal(VirtualPath virtualPath, Boolean allowCrossApp, Boolean codeFile) +9930801
System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate) +455
System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate) +103
System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean throwIfNotFound) +165
System.Web.Compilation.BuildManager.GetObjectFactory(String virtualPath, Boolean throwIfNotFound) +33
System.Web.WebPages.BuildManagerWrapper.GetObjectFactory(String virtualPath) +26
System.Web.WebPages.BuildManagerWrapper.ExistsInPrecompiledSite(String virtualPath) +80
System.Web.WebPages.BuildManagerWrapper.Exists(String virtualPath) +13
System.Web.WebPages.<>c__DisplayClass1.<Exists>b__0(IVirtualPathFactory factory) +15
System.Linq.Enumerable.Any(IEnumerable`1 source, Func`2 predicate) +146
System.Web.WebPages.VirtualPathFactoryManager.Exists(String virtualPath) +73
System.Web.WebPages.DefaultDisplayMode.GetDisplayInfo(HttpContextBase httpContext, String vir tualPath, Func`2 virtualPathExists) +42
System.Web.WebPages.<>c__DisplayClassb.<GetDisplayInfoForVirtualPath>b__8(IDisplayMode mode) +22
System.Linq.WhereSelectListIterator`2.MoveNext() +104
System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source, Func`2 predicate) +94
System.Web.WebPages.DisplayModeProvider.GetDisplayInfoForVirtualPath(String virtualPath, HttpContextBase httpContext, Func`2 virtualPathExists, IDisplayMode currentDisplayMode, Boolean requireConsistentDisplayMode) +204
System.Web.WebPages.WebPageRoute.GetRouteLevelMatch(String pathValue, IEnumerable`1 supportedExtensions, IVirtualPathFactory virtualPathFactory, HttpContextBase context, DisplayModeProvider displayModeProvider) +201
System.Web.WebPages.WebPageRoute.MatchRequest(String pathValue, IEnumerable`1 supportedExtensions, IVirtualPathFactory virtualPathFactory, HttpContextBase context, DisplayModeProvider displayModes) +281
System.Web.WebPages.WebPageRoute.DoPostResolveRequestCache(HttpContextBase context) +235
System.Web.WebPages.WebPageHttpModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e) +89
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +136
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69 

推荐答案

我遇到了同样的问题,但仅在发布Web应用程序时才会发生,并且可以在本地正常运行.我想出了两个潜在的解决方案.

I was having the same issue but it only occured when I published my web application and would work fine locally. I came up with two potential solutions.

棘手的解决方案

通过查看源代码,我可以看到它引发了此错误,因为"BuildManager"对象具有字段"_forbiddenTopLevelDirectories",如果路径位于多个特殊目录"App_Themes"中,它将检查并引发期望成为其中的一员.

By looking at the source code I could see it was throwing this error as the "BuildManager" object had a field "_forbiddenTopLevelDirectories" which it would check and throw an expection if the path was in a number of special directories, "App_Themes" being one of them.

因此,通过使用反射,我可以通过在全局文件Application_Start方法中调用以下代码来从集合中删除"App_Themes"对象.

So by using reflection I remove the "App_Themes" object from the collection by calling the following code in the global file Application_Start method.

        var buildManagerType = typeof(BuildManager);
        var theBuilderManager = buildManagerType.GetField("_theBuildManager"
             , BindingFlags.Static | BindingFlags.NonPublic)
             .GetValue(null);

        var forbiddenDirectoryField = buildManagerType
        .GetField("_forbiddenTopLevelDirectories",
        BindingFlags.Instance | BindingFlags.NonPublic)
       .GetValue(theBuilderManager);

        var removeMethod = forbiddenDirectoryField.GetType().GetMethod("Remove");

        removeMethod.Invoke(forbiddenDirectoryField, new object[] { "App_Themes" });

这解决了该问题,部署后我的css +映像文件现在可以正确使用了. 警告-我对编辑_forbiddenTopLevelDirectories字段的后果不太了解,这样做可能会带来意想不到的副作用.

This solved the issue and my css + image files would now be correctly served when deployed. Warning - I do not have a good understanding of the consequences of editing the _forbiddenTopLevelDirectories field and doing this may have unintended side effects.

替代解决方案

我注意到的另一件事是,当webconfig中模块节点的runAllManagedModulesForAllRequests属性设置为false时,我不会收到错误.因此,如果您的应用程序可以将此设置设置为false,请考虑使用此解决方案

Another thing i noticed was I would not recieve the errors when the runAllManagedModulesForAllRequests attribute of the modules node in the webconfig was set to false. So if your application can work with this set to false consider this solution

<modules runAllManagedModulesForAllRequests="false">

这篇关于使用预编译时从App_Themes提供图像时出错?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆