无法调试通过自定义VirtualPathProvider加载的EmbeddedResource视图

mci*_*321 10 asp.net compiler-construction debugging virtualpathprovider embedded-resource

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

什么是无效的是调试.如果我向视图添加断点,则不会加载符号.我可以看出为什么这很困难(ASP编译器如何知道源文件的位置,以便发现断点?),但我正在寻找一种方法来提示可以找到源文件的编译器.

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

编辑:

我一直在试验通过VPP加载的ASPX页面,并查看Compiled Source(使用David Ebbo的技术),生成的行编译指示如下:

Line 275:              #line 1 "http://server/EmbeddedPage.aspx"
Line 276:              this.InitializeCulture();
Run Code Online (Sandbox Code Playgroud)

通常,这些是沿着这些线生成的

Line 275:              #line 1 "d:/somesln/someproj/EmbeddedPage.aspx"
Run Code Online (Sandbox Code Playgroud)

不知道这有助于任何人,或不...

编辑2:

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

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

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

--- 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:如果我将Debugger.Break()调用到我的Index.cshtml中,调试器在反汇编视图中停止,并且根本没有编译指示,不正确或其他

  1. 如果我@{ #line 1 "C:\Users\Harry\Desktop\VppDebugTest\VppDebugTest.Views\Views\Home\Index.cshtml" }在我的视图中手动写入,则调试将在文件中停止.那么也许解决方案是我的VPP将#line编译指示插入到cshtml文件本身?

小智 2

我遇到了同样的问题,最终通过使用自定义 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
    }
}
Run Code Online (Sandbox Code Playgroud)

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

<system.web.webPages.razor>
    <host factoryType="My.Custom.Namespace.MyCustomRazorHostFactory" />
</system.web.webPages.razor>
Run Code Online (Sandbox Code Playgroud)

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