无法调试通过自定义VirtualPathProvider加载的EmbeddedResource视图 [英] Cannot debug EmbeddedResource views loaded via custom VirtualPathProvider

查看:224
本文介绍了无法调试通过自定义VirtualPathProvider加载的EmbeddedResource视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编写了一个自定义的VirtualPathProvider(源代码 here ),这将从EmbeddedResources或原始文件,如果它被告知在哪里找到它(这允许您编辑和更新文件而不必重建)。这是正常的,到目前为止。



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

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



编辑:



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



<$ p $第275行:#line 1http://server/EmbeddedPage.aspx
行276:this.InitializeCulture();

通常,这些按照



第275行:#line 1d:/somesln/someproj/EmbeddedPage.aspx

不知道这是否有助于任何人,否则...



编辑2:


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


  1. 您不能在.aspx中设置断点,除非引用system.web(在VS 2010中)

  2. 如果您使用指令<$ c创建了一个最小的.aspx页面$ c><%@ Page Language =C#%> 并设置断点,VS将停止在源文件中的断点


  3. 如果您创建一个非最小的.aspx与指令<%@ Page Language =C#AutoEventWireup =trueCodeBehind =WebForm1.aspx.csInherits =VppDebugTest .WebForm1%> 并设置一个断点,当看到VS会带你去拆卸调试vie w


--- 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 1C:\Users\Harry\Desktop\VppDebugTest\VppDebugTest.Views\Views\Home\Index.cshtml} 在我看来,被调试的文件将停止。所以也许解决方案是为我的VPP插入#line编译指示到cshtml文件本身?


解决方案

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



我做了什么:

  public class MyCustomRazorHostFactory:WebRazorHostFactory 
{
public override System.Web.WebPages.Razor.WebPageRazorHost CreateHost(string virtualPath,string physicalPath)
{
//从MvcRazorHostFactory中执行的实现:)
var host = base.CreateHost(virtualPath,physicalPath);

if(!host.IsSpecialPage)
{
返回新的MyCustomRazorHost(virtualPath,physicalPath);
}

返回主机;

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

//简化为演示目的
public static class MyMagicHelper
{
public static bool IsEmbeddedFile (string virtualPath)
{
// ...检查路径是否是嵌入式文件路径
}

public static string GetPhysicalFilePath(string virtualPath)
{
// ...解析虚拟文件并返回正确的物理文件路径
}
}

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

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

我知道我的答案有点迟了,但希望别人可以利用它,当绊倒这个问题像我一样。 :)


I have written a custom VirtualPathProvider (source here) which will return content from EmbeddedResources, or from the original file if it has been told where to find it (this allows you to edit and update the files without having to rebuild). This is working fine, so far.

What isn't working is debugging. If I add a breakpoint to the view, it doesn't load the symbols. I can see why this is difficult (how can the ASP compiler know where the source file is, in order to spot the breakpoints?), but am looking for a way to hint to the compiler where the source file can be found.

Example project here: http://dl.dropbox.com/u/2808109/VppDebugTest.zip

edit:

I've been experimenting with an ASPX page loaded via the VPP, and by viewing the Compiled Source (using David Ebbo's technique), and the line pragmas are generated like so:

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

Normally, these are generated along the lines of

Line 275:              #line 1 "d:/somesln/someproj/EmbeddedPage.aspx"

Don't know if that helps anyone, or not...

edit 2:

After David sent me his code, I have done some further investigation and the following things seem to be true:

  1. you can't set a breakpoint in a .aspx unless system.web is referenced (in VS 2010)
  2. if you create a minimal .aspx page with the directives <%@ Page Language="C#" %> and set a breakpoint, VS will stop at the breakpoint in the source file

  3. if you create a non minimal .aspx with directives <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="VppDebugTest.WebForm1" %> and set a breakpoint, when viewed VS will take you to the dissasembly debug view

--- 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]

It still wont stop at any breakpoints in the Razor views, which is unfortunately what I really need to be able to do! This .aspx stuff may be a red herring.

edit:

5: If I put a call to Debugger.Break() into my Index.cshtml, the debugger stops at disassembly view, and there are no pragmas at all, incorrect or otherwise

  1. If I manually write @{ #line 1 "C:\Users\Harry\Desktop\VppDebugTest\VppDebugTest.Views\Views\Home\Index.cshtml" } in my view, the debugged will stop in the file. So maybe the solution is for my VPP to insert the #line pragmas into the cshtml files itself??

解决方案

I had the same problem and finally got it working by using a custom RazorHost. It seems that the physical file location is resolved using the HostingEnvironment.MapPath() method which does not return the correct result for embedded files.

What I did:

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
    }
}

As a last step you need to tell ASP.NET which host factory it should use. This is done in the web.config:

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

I know my answer comes a bit late but hopefully someone else can make use of it when stumbling across this question as I did. :)

这篇关于无法调试通过自定义VirtualPathProvider加载的EmbeddedResource视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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