Проект веб-развертывания: публикация без предварительной компиляции

Вопрос

Можно ли опубликовать проект веб-приложения, используя проект веб-развертывания, без предварительной компиляции?

Заметки

Чтобы разделить веб-элементы управления и страницы на отдельную сборку, я использую пользовательский 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, не открывая весь проект / решение.

Надеюсь это поможет.

Другие вопросы по тегам