Web Deployment Project: Publish without Precompilation
Asked Answered
S

3

6

The Question

Is it possible to publish a web application project using a web deployment project without precompilation?

Notes

In order to split out web controls and pages into a separate assembly, I am using a custom VirtualPathProvider to load these resources. I am using web deployment projects and msbuild at cmd line to deploy these projects.

The crux of the matter is that VirtualPathProviders are not supported for precompiled applications. I have found a workaround for regular files here. However, this does not work for application files such as ascx and aspx pages. It throws an exception along the lines of "the file has not been pre-compiled, and cannot be requested".

As a result, I have decided to attempt to abandon precompilation altogether and take the initial request performance hit since our site traffic isn't particularly high. However, I can't figure out how to do this using Web Deployment Projects, which are already very baked into our build process.

[update]

I am looking into customizing the Microsoft.WebDeployment.targets file in order to accomplish this, but I haven't had any luck so far.

[update]

In digging around in the Microsoft.WebDeployment.targets file, I have found that there is no straightforward way of decoupling Web Deployment projects from Web Application Precompilation. In fact, I'm not certain there's any need to. What I am now using instead is something akin to the following snippet. I just put it into the project file with a condition attr to not deploy for Debug builds.

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

It seems as though this is all that's needed in order to deploy a project without precompilation. Let me know if you find anything better.

Sculpin answered 7/8, 2009 at 14:42 Comment(1)
+1: I'd like to know the answer too so hopefully that helps with the bounty :)Despain
Y
2

To make VirtualPathProvider work with precompiled website (or at most partially precompiled), you need to do what Alconja say in conjunction to this http://sunali.com/2008/01/09/virtualpathprovider-in-precompiled-web-sites/

Instead common "AppInitialize":

public static void AppInitialize()
{
    HostingEnvironment.RegisterVirtualPathProvider(new MyVirtualPathProvider())
}

Use this:

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()});
}

According to reference, original action filter precompiled websites. You can achieve what you want intercepting RegisterVirtualPathProviderInternal using reflection, besides normal RegisterVirtualPathProvider method.

Yerxa answered 26/5, 2011 at 21:51 Comment(0)
E
1

Maybe I'm missing something (I don't have any experience with VirtualPathProviders), but if you just want your aspx & ascx files to not be precompiled ticking the "Allow this precompiled site to be updatable" box in the Compilation section of the deployment project's property pages (for whichever configuration you're using).

From MSDN:

Allow this precompiled site to be updatable

Specifies that the content of .aspx pages are not compiled into an assembly; instead, the markup is left as-is, allowing you to change HTML and client-side functionality after precompiling the Web site. Selecting this check box is equivalent to adding the -u option to the aspnet_compiler.exe command.

Epicycloid answered 11/8, 2009 at 1:9 Comment(1)
Yes, this leaves the client-side code updatable but the site is still precompiled, meaning I can't use a Virtual Path Provider.Sculpin
M
0

I have had success updating ASPX files without recompiling by simply opening the individual ASPX files in Visual Studio without opening the entire Project/Solution.

Hope this helps.

Monstrous answered 11/8, 2009 at 20:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.