1. 程式人生 > >ASP.NET Web Application中使用鏈接文件

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

快速 構建 remove linked link lsp rep 增加 是我

最近重構一個內部的平臺系統,作為一個平臺,其下有幾個子系統,每個子系統有自己的網站系統。而每個網站使用的是統一的風格,統一的驗證機制,反饋系統,等等。所以,為了避免幾個子系統中重復出現相同的資源或文件,我打算將以前的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\ 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進行調試了!

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