Web部署项目:无需预编译即可发布
问题
是否可以使用 Web 部署项目无需预编译来发布 Web 应用程序项目?
为了
将 Web 控件和页面拆分为单独的程序集,我使用自定义 VirtualPathProvider 来加载这些资源。 我正在 cmd 行使用 Web 部署项目和 msbuild 来部署这些项目。
问题的关键是预编译应用程序不支持 VirtualPathProvider。 我在此处找到了常规文件的解决方法。 但是,这不适用于 ascx
和 aspx
页面等应用程序文件。 它抛出“文件尚未预编译,无法请求”的异常。
因此,我决定尝试完全放弃预编译并承受初始请求性能的影响,因为我们的网站流量不是特别高。 但是,我不知道如何使用 Web 部署项目来做到这一点,这些项目已经融入我们的构建过程中。
[update]我正在考虑自定义 Microsoft.WebDeployment.targets 文件以实现此目的,但到目前为止我还没有任何运气。
[update]在深入研究 Microsoft.WebDeployment.targets 文件时,我发现没有直接的方法可以将 Web 部署项目与 Web 应用程序预编译解耦。 事实上,我不确定是否有必要这样做。 我现在使用的是类似于以下代码片段的东西。 我只是将其放入项目文件中,并带有一个条件属性,以便不部署调试版本。
<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>
似乎这就是在没有预编译的情况下部署项目所需的全部内容。 如果您发现更好的东西,请告诉我。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
要使 VirtualPathProvider 与预编译网站(或最多部分预编译)配合使用,您需要执行 Alconja 结合此 http://sunali.com/2008/01/09/virtualpathprovider-in-precompiled-web-sites/
代替常见的“AppInitialize”:
使用这个:
根据参考一下,原版动作过滤器预编译网站。 除了普通的 RegisterVirtualPathProvider 方法之外,您还可以使用反射来拦截 RegisterVirtualPathProviderInternal 来实现您想要的目的。
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":
Use this:
According to reference, original action filter precompiled websites. You can achieve what you want intercepting RegisterVirtualPathProviderInternal using reflection, besides normal RegisterVirtualPathProvider method.
也许我错过了一些东西(我没有任何 VirtualPathProviders 的经验),但如果你只想要你的 aspx & 勾选部署项目属性页(无论您使用哪种配置)的编译部分中的“允许此预编译站点可更新”框,以防止预编译 .ascx 文件。
来自 MSDN:
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:
我已经成功更新了 ASPX 文件,而无需重新编译,只需在 Visual Studio 中打开各个 ASPX 文件,而无需打开整个项目/解决方案。
希望这可以帮助。
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.