Не удается отладить просмотры EmbeddedResource, загруженные через пользовательский VirtualPathProvider
Я написал пользовательский VirtualPathProvider (источник здесь), который будет возвращать контент из EmbeddedResources или из исходного файла, если было сказано, где (это позволяет редактировать и обновлять файлы без необходимости их восстановления). Пока все работает нормально.
Что не работает, это отладка. Если я добавлю точку останова в представление, она не загрузит символы. Я могу понять, почему это сложно (как компилятор ASP знает, где находится исходный файл, чтобы определить точки останова?), Но я ищу способ подсказки компилятору, где можно найти исходный файл.
Пример здесь: http://dl.dropbox.com/u/2808109/VppDebugTest.zip
изменить:
Я экспериментировал с ASPX-страницей, загружаемой через VPP, и просмотрел Compiled Source (используя метод Дэвида Эббо) и линейные прагмы генерируются так:
Line 275: #line 1 "http://server/EmbeddedPage.aspx"
Line 276: this.InitializeCulture();
Обычно они генерируются вдоль линий
Line 275: #line 1 "d:/somesln/someproj/EmbeddedPage.aspx"
Не знаю, помогает ли это кому-либо, или нет...
edit 2:
После того, как Дэвид прислал мне свой код, я провел некоторое дальнейшее расследование, и следующие вещи выглядят правдоподобно:
- вы не можете установить точку останова в .aspx, если не указана система system.web(в VS 2010)
-
если вы создаете минимальную страницу .aspx с директивами <%@ Page Language="C#" %>
и задаете точку останова, VS остановится в точке останова в исходном файле
-
если вы создаете не минимальный .aspx с директивами <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="VppDebugTest.WebForm1" %>
и устанавливаете точку останова, при просмотре 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: Если я поместил вызов Debugger.Break() в мой Index.cshtml, отладчик остановится на разборном представлении, и нет прагм вообще, некорректно или иначе
- Если я вручную напишу
@{ #line 1 "C:\Users\Harry\Desktop\VppDebugTest\VppDebugTest.Views\Views\Home\Index.cshtml" }
, на мой взгляд, отладка остановится в файле. Так, может быть, решение для моего VPP вставить прайсы #line в сами файлы cshtml??
Ответы
Ответ 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, на котором размещен factory он должен использовать. Это делается в файле web.config:
<system.web.webPages.razor>
<host factoryType="My.Custom.Namespace.MyCustomRazorHostFactory" />
</system.web.webPages.razor>
Я знаю, что мой ответ наступает немного поздно, но, надеюсь, кто-то другой сможет его использовать, когда споткнулся об этом вопросе, как и я.:)
Ответ 2
Я немного поиграл с вашим кодом, и когда я добавил тестовый aspx в ресурсы, отладка, похоже, работала нормально. Я смог установить BP в Page_Load, а там git.
Вы можете увидеть мое изменение https://github.com/davidebbo/EmbeddedResourceVirtualPathProvider
Обратите внимание, что я отключил логику возврата, поскольку я хотел сосредоточиться на встроенном случае, хотя я не думаю, что это имеет значение.
Обратите внимание, что я использую VS2012, поэтому мне также пришлось обновить проект /sln (но они все равно будут работать в 2010 году).
Причина, по которой ASP.NET генерирует прагму http-строки, заключается в том, что она не может найти физический файл aspx в стандартном местоположении (то есть, что вернет MapPath). На самом деле существует малоизвестный способ всегда включать это поведение: set urlLinePragmas = true в разделе (http://msdn.microsoft.com/en-us/library/system.web.configuration.compilationsection.urllinepragmas.aspx).