我编写了一个自定义的VirtualPathProvider(此处为源代码(,它将从EmbeddedResources返回内容,或者如果被告知在哪里可以找到原始文件,则从原始文件返回内容(这允许您编辑和更新文件而无需重建(。到目前为止,这工作正常。
不起作用的是调试。如果我向视图添加断点,它不会加载符号。我可以看到为什么这很困难(ASP编译器如何知道源文件的位置,以便发现断点?(,但是我正在寻找一种方法来提示编译器在哪里可以找到源文件。
此处的示例项目:http://dl.dropbox.com/u/2808109/VppDebugTest.zip
编辑:
我一直在尝试通过VPP加载的ASPX页面,并通过查看编译源代码(使用David Ebbo的技术(,行编译指示生成如下:
Line 275: #line 1 "http://server/EmbeddedPage.aspx"
Line 276: this.InitializeCulture();
通常,这些是沿着以下行生成的
Line 275: #line 1 "d:/somesln/someproj/EmbeddedPage.aspx"
不知道这是否对任何人都有帮助,或者没有帮助...
编辑2:
在David将他的代码发送给我之后,我做了一些进一步的调查,以下事情似乎是正确的:
- 除非引用 system.web,否则无法在.aspx中设置断点(在 VS 2010 中(
如果使用指令
<%@ Page Language="C#" %>
创建最小.aspx页并设置断点,则 VS 将在源文件中的断点处停止如果您使用指令
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="VppDebugTest.WebForm1" %>
创建非最小.aspx并设置断点,则在查看时 VS 将带您进入 dissasembly debug 视图
--- 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((,调试器会在反汇编视图停止,并且根本没有杂注、不正确或其他
- 如果我在视图中手动写入
@{ #line 1 "C:UsersHarryDesktopVppDebugTestVppDebugTest.ViewsViewsHomeIndex.cshtml" }
,则调试将在文件中停止。所以也许解决方案是让我的 VPP 将 #line 编译指示插入 cshtml 文件本身?
我遇到了同样的问题,最终通过使用自定义 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>
我知道我的回答来得有点晚,但希望其他人可以像我一样偶然发现这个问题时利用它。 :)
我尝试了一下您的代码,当我在资源中添加测试 aspx 时,调试似乎工作正常。我能够在Page_Load中设置一个BP,它在那里。
你可以在 https://github.com/davidebbo/EmbeddedResourceVirtualPathProvider 中看到我的更改
请注意,我禁用了回退逻辑,因为我想专注于嵌入式案例,尽管我认为这没有什么区别。
请注意,我使用的是VS2012,所以我还必须升级项目/sln(但它们在2010年仍然可以工作(。
ASP.NET 生成 http 行杂注的原因是它无法在标准位置找到物理 aspx 文件(即 MapPath 将返回的内容(。实际上有一种鲜为人知的方法可以始终打开此行为:在 (http://msdn.microsoft.com/en-us/library/system.web.configuration.compilationsection.urllinepragmas.aspx( 部分中设置 urlLinePragmas=true。