28

Visual Studio 2010を使用して、展開時にすべて同じWebサイトに格納されている約40の異なるWebアプリケーションを維持しています。これらのプロジェクトは同じソリューションに含まれていますが、それぞれが非常に異なることを行うため、異なるプロジェクトに収容されています。

「リンクとして追加」オプションを使用してさまざまなプロジェクト間でcss/jsファイルを共有しようとしています。これにより、cssまたはjsファイルを一度更新すると、それぞれをビルドして再デプロイしなくても、更新がさまざまなプロジェクトに自動的に反映されます。事業。

私が抱えている問題は、デバッグ目的でPC上でローカルにプロジェクトを実行しようとすると、それらのリンクされたファイルが機能しないことです。ファイルが見つかりません。

私の考え:これは、アプリケーションをローカルで実行するときにフォルダー構造が異なるためだと思います。デバッグモードでビルドしているときにのみファイルをプロジェクトにコピーし、それに応じて相対URLを調整して、Webサーバーに公開する前にアプリケーションを適切にテストできるようにする方法があるかどうか知りたいです。

ありがとう、

4

4 に答える 4

35

この問題の解決策は、各ビルド中にリンクとして追加されるコンテンツファイル(js、cssなど)をコピーすることです。これを行うにはいくつかの方法があります。さまざまなWebアプリケーションプロジェクトで再利用できるMSBuildターゲットを使用するようアドバイスできます。

したがって、次の内容で次のファイルを作成できます(たとえば、WebApplication.Extension.targetsという名前を付けます)。

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <!-- Override the default target dependencies to -->
    <!-- include the new CopyLinkedContentFiles target. -->
    <PropertyGroup>
        <BuildDependsOn>
            CopyLinkedContentFiles;
            $(BuildDependsOn);
        </BuildDependsOn>
    </PropertyGroup>

    <!--
    ============================================================
    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>
</Project>

次に、.csprojファイルに次の行を配置して、このターゲットをWebアプリケーションプロジェクトに追加します。

<Import Project="$(MSBuildProjectDirectory)[RelativePathToFile]\WebApplication.Extension.targets" />

基本的に、次の行の後に.csprojファイルにこの行を追加できます。

<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

リンクとして追加されたコンテンツファイルに関するこの問題の後、解決する必要があります。

編集: デバッグ構成がMSBUILDに組み込まれている場合にのみ次のロジックを実行するには、Condition要素を指定することができます。

たとえば、デバッグ構成のためにのみ指定されたターゲットをインポートするには、importステートメントを次のように更新できます。

<Import Project="$(MSBuildProjectDirectory)[RelativePathToFile]\WebApplication.Extension.targets" Condition=" '$(Configuration)' == 'Debug' "/>

Edit2:

この問題を少し前に克服するために、「MSBuild.WebApplication.CopyContentLinkedFiles」nugetパッケージを作成しました。このパッケージは、ビルド中にプロジェクトフォルダーへのリンクとして追加されたすべてのコンテンツファイルをコピーするMsBuildターゲットを追加します。

于 2012-12-13T20:50:10.887 に答える
33

MSBuildを使用して、リンクされたすべてのコンテンツファイルを各ビルドの「仮想」の場所に自動的にコピーするソリューションは次のとおりです。

http://mattperdeck.com/post/Copying-linked-content-files-at-each-build-using-MSBuild.aspx

これにより、F5キーを押したときに、リンクされたファイルがブラウザで利用できるようになります。

于 2013-05-10T00:37:44.543 に答える
7

リンクされたファイルを含む.projファイルの最後に次のスニペットを貼り付けることでも解決できます。

<Target Name="CopyLinkedContentFiles" BeforeTargets="Build">
<Copy SourceFiles="%(Content.Identity)" 
      DestinationFiles="%(Content.Link)" 
      SkipUnchangedFiles='true' 
      OverwriteReadOnlyFiles='true' 
      Condition="'%(Content.Link)' != ''" />

于 2016-04-06T21:28:02.173 に答える
0

リンクされたファイルを仮想の場所にコピーすることには大きな問題が1つあります。リンクされたファイルの1つを指すJavaScript参照で[定義に移動](Shift + F2)を使用すると、ローカルにコピーされたファイルに移動します。リンクされたファイルに。そうすると、ローカルバージョンの編集を間違えることになり、リンクされたファイルを使用するメリットがなくなります。さらに、Intellisenseで問題が発生する可能性があります。

より良い解決策:リンクされたファイルを関連するリンクと一緒に現在のプロジェクトディレクトリにコピーする代わりに、それらをそのディレクトリ内の「hiddenDebug」フォルダ(または任意のディレクトリ。同じディレクトリに保持すると管理が容易になります)にコピーします。次に、以下で説明するように、デバッグ中にパスを操作します)。

共有リポジトリから「hiddenDebug」フォルダにファイルをコピーする方法は次のとおりです(ソースプロジェクトのビルド後のイベントに追加します)。

単一のCSSファイル

xcopy / Y "$(ProjectDir)App_Themes \ Theme1 \ Shared.css" "$(SolutionDir)WebApp \ App_Themes \ Theme1 \ hiddenDebug \"

JavaScriptディレクトリ

xcopy / Y / S "$(ProjectDir)Scripts" "$(SolutionDir)WebApp \ Scripts \ Shared \ hiddenDebug \"

デバッグ中は、Global.asaxのResponse.Filterを使用して、共有ファイルのソースパスを動的に変更できます。次に例を示します。

応答フィルタークラス(共有プロジェクト内)

Imports System.IO

Namespace Code
    Public Class LinkedReferencesFilter
    Inherits MemoryStream

        Private ReadOnly outputStream As Stream = Nothing
        Private ReadOnly _IsDevEnvironment As Boolean = False

        Public Sub New(ByVal output As Stream, IsDevEnvironment As Boolean)
            Me.outputStream = output
            Me._IsDevEnvironment = IsDevEnvironment
        End Sub

        Public Overrides Sub Write(ByVal buffer As Byte(), ByVal offset As Integer, ByVal count As Integer)
            ' Convert the content in buffer to a string
            Dim contentInBuffer As String = UTF8Encoding.UTF8.GetString(buffer)

            If Me._IsDevEnvironment Then
                contentInBuffer = contentInBuffer.Replace("<script src=""Scripts/Shared/", "<script src=""Scripts/Shared/hiddenDebug/")
                contentInBuffer = contentInBuffer.Replace("/Scripts/Shared/", "/Scripts/Shared/hiddenDebug/")
                contentInBuffer = contentInBuffer.Replace("/App_Themes/Theme1/Shared.css", "/App_Themes/Theme1/hiddenDebug/Shared.css")
            End If

            Me.outputStream.Write(UTF8Encoding.UTF8.GetBytes(contentInBuffer), offset, UTF8Encoding.UTF8.GetByteCount(contentInBuffer))
        End Sub
    End Class
End Namespace

Global.asax

Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
    ' Simulate internet latency on local browsing
    If Request.IsLocal Then
        System.Threading.Thread.Sleep(50)
    End If

    Dim currentRelativePath As String = Request.AppRelativeCurrentExecutionFilePath

    If request__1.HttpMethod = "GET" Then
        If currentRelativePath.EndsWith(".aspx") Then
            Dim IsDevEnvironment As Boolean = False
            //Use whatever method you want to determine whether your current environment is a development environment:
            #If CONFIG = "Develop" Then
                IsDevEnvironment = True
            #End If

            Response.Filter =
                New Shared.Code.LinkedReferencesFilter(
                    output:=Response.Filter,
                    IsDevEnvironment:=IsDevEnvironment)
        End If
    End If
End Sub

トラブルシューティング:リンクされたアイテムを使用してプロジェクトをアンロードおよびリロードしてみてください。それでも問題が解決しない場合は、hiddenDebugディレクトリをプロジェクトに追加します。私はそれをしなければなりませんでした、しかしそれから私は後でそれを取り除くことができました。それは気難しいです...マイクロソフトがこの機能を磨いたらいいのですが、私は今のところ準備ができています。

知らなかった場合:Webアプリケーションを公開すると、ソース(リンクされた)ファイルが公開ターゲットに自動的にコピーされます。これを設定すると、忘れることができます。最良の部分は、Intellisenseまたはクイックナビゲーションを失うことはないということです。

TypeScriptに移行すると、ほとんどのJavaScriptファイル参照の課題が単純化または排除されます(他のマネージド.NET言語で利用できるような、プロジェクト間の簡単な参照を望んでいますが、そのような機能を有効にするための回避策がすでにいくつかある可能性があります)。

それがあなたのために働くかどうか、またはあなたがより良い方法を持っているかどうか私に知らせてください。

于 2014-06-03T13:18:53.473 に答える