ASP.NET Web Application中使用链接文件

最近重构一个内部的平台系统,作为一个平台,其下有几个子系统,每个子系统有自己的网站系统。而每个网站使用的是统一的风格,统一的验证机制,反馈系统,等等。所以,为了避免几个子系统中重复出现相同的资源或文件,我打算将以前的ASP.NET Web Site全部转换为ASP.NET Web Application,然后通过链接外部公共文件的方式解决这个问题。同时:

  1. Web Application是Web Site的升级产品。
  2. Web Application允许添加链接方式,把其他目录的文件作为链接加入工程,更具备灵活性。
  3. Web Application编译,构建,部署更加简单,快速,便捷。

当然,Web Application和Web Site还有很多不同的地方,比如:

  1. Web Application有designer.cs文件,Web Site没有。
  2. Web Application有命名空间,Web Site默认没有。
  3. Web Application默认没有App_Code目录,需手工添加,且添加的cs文件默认属性为Content,需手工修改为Compile才加入编译。 …

等等。本文主要讲述,在ASP.NET Web Application中使用链接文件时,遇到的一些问题,以及解决办法。

首先,介绍一下将Web Site页面转换为Web Application页面的方法。如果了解了两者的区别,将会非常容易。主要分为几步: 1. 新建一个Web Application工程,将原Web Site页面添加到该工程中。 2. 在aspx.cs文件中,给类加上命名空间。同时,aspx文件头部的Inherits属性也加上命名空间。 3. 右键aspx文件或工程名,点击”Convert to Web Application”。这时,自动生成的designer.cs文件了。(aspx页面中的控件的定义。)

好了,添加外部的链接文件:

添加链接的文件很简单,也很方便。但是调试过程中,会遇到很大的麻烦。因为调试时,默认使用VS内置的Web Server,网站的根目录是源代码目录,调试时,遇到链接文件时,会因为找不到文件而出错。

而如果使用”publish“菜单发布网站时,会将链接的资源文件拷贝过去,这才是我们想要的。每次调试都需要进行发布,然后在本机的iis里设置虚拟目录,太麻烦了。

同时,我们希望通过MSBuild自动构建和发布网站,构建时也希望能自动的将链接的文件拷贝一份过去。MSBuild中编译ASP.NET Web Application工程的命令是:

<MSBuild Projects=“d:\Demo\Web.csproj” Targets=”ResolveReferences;_CopyWebApplication;” Properties=“WebProjectOutputDir=d:\Publish\;OutDir=d:\Publish\Bin\;Configuration=Release”></MSBuild>
但是,上面的命令不会把链接的文件拷贝过去。这个问题困扰了我,难道要我写一个Copy的Task,自己将需要的文件拷贝过去?后来google了一下,发现也有人遇到我一样的问题,并且提供了一个绝佳的解决方案,同时解决了调试和发布的问题,真是太完美了!
方法是,修改csproj文件,重新定义默认的_CopyWebApplication Target,同时,增加拷贝链接文件的Target。将下面这段代码加入到csproj文件中:
  <!–    ============================================================   _CopyWebApplication   MODIFIED: Ignores linked files as part of normal deployment logic.    This target will copy the build outputs along with the   content files into a _PublishedWebsites folder.   This Task is only necessary when $(OutDir) has been redirected   to a folder other than ~\bin such as is the case with Team Build.    ============================================================   –>   <Target Name=”_CopyWebApplication” Condition=“‘$(OutDir)’ != ’$(OutputPath)‘”>     <!– Log tasks –>     <Message Text=“Copying Web Application Project Files for $(MSBuildProjectName)” />     <!– Create the _PublishedWebsites\app\bin folder –>     <MakeDir Directories=“$(WebProjectOutputDir)\bin” />     <!– Copy build outputs to _PublishedWebsites\app\bin folder –>     <Copy SourceFiles=“@(IntermediateAssembly)” DestinationFolder=“$(WebProjectOutputDir)\bin” SkipUnchangedFiles=“true” />     <Copy SourceFiles=“@(AddModules)” DestinationFolder=“$(WebProjectOutputDir)\bin” SkipUnchangedFiles=“true” />     <Copy SourceFiles=“$(IntermediateOutputPath)$(_SGenDllName)” DestinationFolder=“$(WebProjectOutputDir)\%(Content.SubFolder)%(Content.RecursiveDir)” SkipUnchangedFiles=“true” Condition=“‘$(_SGenDllCreated)‘==‘true’” />     <Copy SourceFiles=“$(IntermediateOutputPath)$(TargetName).pdb” DestinationFolder=“$(WebProjectOutputDir)\bin” SkipUnchangedFiles=“true” Condition=“‘$(_DebugSymbolsProduced)‘==‘true’” />     <Copy SourceFiles=“@(DocFileItem)” DestinationFolder=“$(WebProjectOutputDir)\bin” SkipUnchangedFiles=“true” Condition=“‘$(_DocumentationFileProduced)‘==‘true’” />     <Copy SourceFiles=“@(IntermediateSatelliteAssembliesWithTargetPath)” DestinationFiles=“@(IntermediateSatelliteAssembliesWithTargetPath->’$(WebProjectOutputDir)\bin\%(Culture)\$(TargetName).resources.dll’)” SkipUnchangedFiles=“true” />     <Copy SourceFiles=“@(ReferenceComWrappersToCopyLocal); @(ResolvedIsolatedComModules); @(_DeploymentLooseManifestFile); @(NativeReferenceFile)” DestinationFolder=“$(WebProjectOutputDir)\bin” SkipUnchangedFiles=“true” />     <!– copy any referenced assemblies to _PublishedWebsites\app\bin folder –>     <Copy SourceFiles=“@(ReferenceCopyLocalPaths)” DestinationFolder=“$(WebProjectOutputDir)\bin” SkipUnchangedFiles=“true” />     <!– MODIFICATION HERE: Copy local content files (i.e. non-linked files) recursively to _PublishedWebsites\app&nbsp;folder –>     <Copy Condition=” ’%(Content.Link)’ == “ “ SourceFiles=“%(Content.Identity)” DestinationFolder=“$(WebProjectOutputDir)\%(Content.RelativeDir)” />   </Target>

  <!–

  CopyLinkedContentFiles   A new target to copy any linked content files into the   web application output folder. 

  NOTE: This is necessary even when ’$(OutDir)’ has not been redirected.

  –>   <Target Name=“CopyLinkedContentFiles”>     <!– Remove any old copies of the files –>     <Delete Condition=” ’%(Content.Link)’ != “ AND Exists(‘$(WebProjectOutputDir)\%(Content.Link)‘) “ Files=“$(WebProjectOutputDir)\%(Content.Link)” />     <!– Copy linked content files recursively to the project folder –>     <Copy Condition=” ’%(Content.Link)’ != “ “ SourceFiles=“%(Content.Identity)” DestinationFiles=“$(WebProjectOutputDir)\%(Content.Link)” />   </Target>   <!– Override the default target dependencies to –>   <!– include the new _CopyLinkedContentFiles target. –>   <PropertyGroup>     <PrepareForRunDependsOn>       $(PrepareForRunDependsOn);       _CopyWebApplication;       CopyLinkedContentFiles;       _BuiltWebOutputGroupOutput     </PrepareForRunDependsOn>   </PropertyGroup> </Project>

其实就是写了一些通用的Copy,而不必手工指定哪些需要拷贝。然后,在MSBuild脚本中,增加CopyLinkedContentFiles Target:

<MSBuild Projects=“D:\Demo\Web.csproj” Targets=”ResolveReferences;_CopyWebApplication;CopyLinkedContentFiles Properties=“WebProjectOutputDir=D:\Publish\;OutDir=D:\Publish\Bin\;Configuration=Release”></MSBuild>
搞定!这时MSBuild编译出来的文件将会包括所有我们需要的文件了。同时,在VS里点击”Build“编译,会将链接的文件也复制一份过来源码目录,这样就能非常方便的使用内置的Web Server进行调试了!
参考链接:
http://consultingblogs.emc.com/jamesdawson/archive/2008/06/03/using-linked-files-with-web-application-projects.aspx

[温馨提示]:该文章由原博客园导入而来,如排版效果不佳,请移步:http://www.cnblogs.com/coderzh/archive/2010/09/16/build-linked-files-with-web-application.html

微信扫一扫交流

作者:CoderZh
微信关注:hacker-thinking (一个程序员的思考)
本文出处:https://blog.coderzh.com/2010/09/16/build-linked-files-with-web-application/
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。