Проект веб-развертывания: публикация без предварительной компиляции
Вопрос
Можно ли опубликовать проект веб-приложения, используя проект веб-развертывания, без предварительной компиляции?
Заметки
Чтобы разделить веб-элементы управления и страницы на отдельную сборку, я использую пользовательский VirtualPathProvider для загрузки этих ресурсов. Я использую проекты веб-развертывания и msbuild в строке cmd для развертывания этих проектов.
Суть в том, что VirtualPathProviders не поддерживаются для предварительно скомпилированных приложений. Я нашел обходной путь для обычных файлов здесь. Однако это не работает для файлов приложений, таких как ascx
а также aspx
страницы. Он выдает исключение в духе "файл не был предварительно скомпилирован и не может быть запрошен".
В результате я решил попытаться полностью отказаться от прекомпиляции и принять первоначальный удар по производительности запросов, так как трафик нашего сайта не особенно высок. Однако я не могу понять, как это сделать с помощью проектов веб-развертывания, которые уже очень встроены в наш процесс сборки.
[Обновить]Я пытаюсь настроить файл Microsoft.WebDeployment.targets для достижения этой цели, но мне пока не повезло.
[Обновить]Изучая файл Microsoft.WebDeployment.targets, я обнаружил, что не существует простого способа отделения проектов веб-развертывания от предварительной компиляции веб-приложения. На самом деле, я не уверен, что в этом есть необходимость. Вместо этого я использую нечто похожее на следующий фрагмент. Я просто поместил его в файл проекта с условием attr, чтобы не развертывать для сборок Debug.
<Target Name="AfterBuild">
<!-- clean output dir -->
<CreateItem Include="$(output)**\*.*">
<Output TaskParameter="Include" ItemName="OldFiles"/>
</CreateItem>
<Delete ContinueOnError="true"
TreatErrorsAsWarnings="true" Files="@(OldFiles)"/>
<!-- copy content -->
<Copy SourceFiles="@(Content)"
DestinationFolder="$(output)%(Content.RelativeDir)" />
<CreateItem Include="$(OutputPath)\*">
<Output TaskParameter="Include" ItemName="Binaries" />
</CreateItem>
<Copy SourceFiles="@(Binaries)" DestinationFolder="$(output)bin" />
<ReplaceConfigSections RootPath="$(output)"
WebConfigReplacementFiles="@(ConfigFiles)"
UseExternalConfigSource="true"
ValidateSectionElements="true"/>
</Target>
Кажется, что это все, что нужно для развертывания проекта без предварительной компиляции. Дай мне знать, если найдешь что-нибудь получше.
3 ответа
Чтобы заставить VirtualPathProvider работать с предварительно скомпилированным веб-сайтом (или, по большей части, частично скомпилированным), вам нужно сделать то, что Alconja говорит в связи с этим http://sunali.com/2008/01/09/virtualpathprovider-in-precompiled-web-sites/
Вместо обычного "AppInitialize":
public static void AppInitialize()
{
HostingEnvironment.RegisterVirtualPathProvider(new MyVirtualPathProvider())
}
Использовать этот:
public static void AppInitialize()
{
HostingEnvironment hostingEnvironmentInstance=(HostingEnvironment)typeof(HostingEnvironment).InvokeMember("_theHostingEnvironment", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField, null, null, null);
MethodInfo mi = typeof(HostingEnvironment).GetMethod("RegisterVirtualPathProviderInternal", BindingFlags.NonPublic | BindingFlags.Static);
mi.Invoke(hostingEnvironmentInstance, new object[] { (VirtualPathProvider)new MyVirtualPathProvider()});
}
Согласно ссылке, оригинальный фильтр действий предварительно скомпилированных сайтов. Вы можете добиться того, что хотите, перехватывая RegisterVirtualPathProviderInternal с помощью отражения, помимо обычного метода RegisterVirtualPathProvider.
Может быть, я что-то упускаю (у меня нет опыта работы с VirtualPathProviders), но если вы просто хотите, чтобы ваши файлы aspx и ascx не были предварительно скомпилированы, отметьте флажок "Разрешить обновление этого предварительно скомпилированного сайта" в разделе "Компиляция" Страницы свойств проекта развертывания (для любой конфигурации, которую вы используете).
Из MSDN:
Разрешить обновление этого предварительно скомпилированного сайта
Указывает, что содержимое страниц ASPX не компилируется в сборку; вместо этого разметка остается как есть, что позволяет вам изменять HTML и функциональность на стороне клиента после предварительной компиляции веб-сайта. Установка этого флажка эквивалентна добавлению опции -u к команде aspnet_compiler.exe.
Я успешно обновил файлы ASPX без перекомпиляции, просто открыв отдельные файлы ASPX в Visual Studio, не открывая весь проект / решение.
Надеюсь это поможет.