【问题标题】:Cannot debug EmbeddedResource views loaded via custom VirtualPathProvider无法调试通过自定义 VirtualPathProvider 加载的 EmbeddedResource 视图
【发布时间】:2012-05-24 21:19:46
【问题描述】:

我编写了一个自定义 VirtualPathProvider(来源 here),它将从 EmbeddedResources 返回内容,或者从原始文件(如果已被告知在哪里找到)返回内容(这允许您编辑和更新文件而无需重新构建)。到目前为止,一切正常。

不工作的是调试。如果我在视图中添加断点,它不会加载符号。我知道为什么这很困难(ASP 编译器如何知道源文件在哪里,以便发现断点?),但我正在寻找一种方法来提示编译器在哪里可以找到源文件。

这里的示例项目:http://dl.dropbox.com/u/2808109/VppDebugTest.zip

编辑:

我一直在试验通过 VPP 加载的 ASPX 页面,并通过查看编译源(使用 David Ebbo's technique),生成的行 pragma 如下所示:

Line 275:              #line 1 "http://server/EmbeddedPage.aspx"
Line 276:              this.InitializeCulture();

通常,这些是按照

的方式生成的
Line 275:              #line 1 "d:/somesln/someproj/EmbeddedPage.aspx"

不知道这是否对任何人有帮助...

编辑 2:

在大卫把他的代码发给我之后,我做了一些进一步的调查,以下事情似乎是真的:

  1. 您不能在 .aspx 中设置断点,除非引用了 system.web(在 VS 2010 中)
  2. 如果您使用指令<%@ Page Language="C#" %> 创建一个最小的.aspx 页面并设置断点,VS 将在源文件中的断点处停止

  3. 如果您使用指令 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="VppDebugTest.WebForm1" %> 创建非最小 .aspx 并设置断点,则查看时 VS 将带您进入反汇编调试视图

--- http://server/WebForm1.aspx ------------------------------------------------ 0000003a mov ecx,dword ptr [ebp-3Ch] 0000003d call 63EC54F0 00000042 mov dword ptr [ebp-44h],eax 00000045 mov edx,dword ptr ds:[03E62200h] 0000004b mov ecx,dword ptr [ebp-44h]

它仍然不会在 Razor 视图中的任何断点处停止,不幸的是,这是我真正需要做的!这个 .aspx 的东西可能是红鲱鱼。

编辑:

5:如果我在我的 Index.cshtml 中调用 Debugger.Break(),调试器会在反汇编视图中停止,并且根本没有编译指示,不正确或不正确

  1. 如果我在我的视图中手动写入@{ #line 1 "C:\Users\Harry\Desktop\VppDebugTest\VppDebugTest.Views\Views\Home\Index.cshtml" },调试将停止在文件中。所以也许解决方案是让我的 VPP 将#line pragma 插入 cshtml 文件本身?

【问题讨论】:

  • 在您附加的项目中,导致看到重现的确切步骤是什么?例如我要导航到什么,我什么时候附加,我在哪里设置 BP,等等......
  • 在 index.cshtml 中设置断点(例如在 @ViewBag.Message 行),如果您运行项目,调试器将不会停在那里。添加对 Debugger.Break() 的调用,您将获得反汇编,而不是源代码。
  • 嗯,这很奇怪。在这种情况下生成的文件根本不包含任何编译指示!请注意,aspx 和 cshtml(又名 Razor)页面的代码生成器完全不同,因此这可能是 Razor 特有的问题。
  • 是的,我想我提到 .aspxes 是把水弄混了
  • 我遇到了完全相同的问题。对于调试单个问题,插入 @{ #line 1 "..." } 是一种好的解决方法。但我想知道你是否找到了真正的解决方案?

标签: asp.net debugging compiler-construction embedded-resource virtualpathprovider


【解决方案1】:

我遇到了同样的问题,最后通过使用自定义 RazorHost 使其正常工作。似乎使用 HostingEnvironment.MapPath() 方法解析了物理文件位置,该方法不会返回嵌入文件的正确结果。

我做了什么:

public class MyCustomRazorHostFactory : WebRazorHostFactory
{
    public override System.Web.WebPages.Razor.WebPageRazorHost CreateHost( string virtualPath, string physicalPath )
    {
        // Implementation stolen from MvcRazorHostFactory :)
        var host = base.CreateHost( virtualPath, physicalPath );

        if( !host.IsSpecialPage )
        {
            return new MyCustomRazorHost( virtualPath, physicalPath );
        }

        return host;
    }
}

public class MyCustomRazorHost : MvcWebPageRazorHost
{
    public MyCustomRazorHost( string virtualPath, string physicalPath )
        : base( virtualPath, physicalPath )
    {
        if( MyMagicHelper.IsEmbeddedFile( virtualPath ) )
        {
            PhysicalPath = MyMagicHelper.GetPhysicalFilePath(virtualPath);
        }
    }
}

// Simplified for demonstration purpose
public static class MyMagicHelper
{
    public static bool IsEmbeddedFile(string virtualPath)
    {
        // ... check if the path is an embedded file path
    }

    public static string GetPhysicalFilePath(string virtualPath)
    {
        // ... resolve the virtual file and return the correct physical file path
    }
}

作为最后一步,您需要告诉 ASP.NET 它应该使用哪个主机工厂。这是在 web.config 中完成的:

<system.web.webPages.razor>
    <host factoryType="My.Custom.Namespace.MyCustomRazorHostFactory" />
</system.web.webPages.razor>

我知道我的答案来得有点晚,但希望其他人在遇到这个问题时可以像我一样使用它。 :)

【讨论】:

  • 哇,太好了,有机会我看看能不能把它集成到我的 nuget 包中
  • 终于搞定了,而且成功了!!!我在我的 EmbeddedResourceVirtualPathProvider 项目中公开了一些属性来实现这些方法,要点在gist.github.com/mcintyre321/ff67ffa8e2f0c8ef86da
【解决方案2】:

我尝试了一下你的代码,当我在资源中添加一个测试 aspx 时,调试似乎工作正常。我能够在 Page_Load 中设置一个 BP,然后它就在那里。

你可以在https://github.com/davidebbo/EmbeddedResourceVirtualPathProvider看到我的变化

请注意,我禁用了回退逻辑,因为我想专注于嵌入式案例,但我认为这没有什么不同。

请注意,我使用的是 VS2012,因此我还必须升级项目/sln(但它们在 2010 年仍然可以使用)。

ASP.NET 生成 http 行编译指示的原因是它无法在标准位置(即 MapPath 将返回的内容)找到物理 aspx 文件。实际上有一种鲜为人知的方法可以始终打开此行为:在部分中设置 urlLinePragmas=true (http://msdn.microsoft.com/en-us/library/system.web.configuration.compilationsection.urllinepragmas.aspx) .

【讨论】:

  • 感谢您对此进行调查!您提出了一些有趣的事情,我会更新问题以反映它们。
  • 有什么方法可以挂钩到 ASP 正在为 urlLinePragmas 执行的查找并告诉它真正的源文件在哪里? (这会解决我的 Razor 视图问题吗)
猜你喜欢
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-19
  • 2011-06-11
  • 2014-11-11
相关资源
最近更新 更多