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

【ASP.NET Web Application中使用链接文件】要须心地收汗马,孔孟行世目杲杲。这篇文章主要讲述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页面中的控件的定义。)

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

文章图片


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

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

文章图片


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

文章图片


添加链接的文件很简单,也很方便。但是调试过程中,会遇到很大的麻烦。因为调试时,默认使用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文件中:


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

文章图片
    < !--   
  ============================================================
    _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\\  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>
ASP.NET Web Application中使用链接文件

文章图片

其实就是写了一些通用的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进行调试了! 

    推荐阅读