16

それで、CSS/JS ファイルの ASP.NET MVC での「自動バージョン管理」に関するこのスタックオーバーフローの投稿を読んでいて、これを行うための「最善の」戦略は何か疑問に思っていました。

提供されているソリューションは、アセンブリ番号を挿入します。つまり、公開するたびに、すべてのファイルが変更されます。これは、*.css または *.js を 1 つだけ変更すると、すべてのファイルが変更されるため、理想的ではありません。

1)IIS7で変更日などを使用してサイト全体のアセンブリを使用する代わりに、「単一ファイル」に対してのみ行うにはどうすればよいですか?

2)また、 http://static.domain.com/js/123.jsのような「静的」アセットがある場合、誰かがこの静的を統合した場合、リクエストの最新ファイルを送信するために書き換えを使用するにはどうすればよいですか彼らのサイトにリンクしますか?

つまり、 http://static.domain.com/js/123.jsがリンクで、リクエストが来たときに最新のファイルを確認して送信しますか?

4

6 に答える 6

22

ASP.NET 4.5+ には、 この問題を解決するように設計された組み込みのバンドルおよび縮小フレームワークが付属しています。

シンプルな独自のソリューションが絶対に必要な場合は、以下の回答を使用できますが、正しい方法はバンドルと縮小フレームワークを使用することです.


次のようにAssemblyInfo.csファイルを変更できます。

Change
[assembly: AssemblyVersion("1.0.0.0")]
to    
[assembly: AssemblyVersion("1.0.*")]

これは、プロジェクトがビルドされるたびに、以前のバージョンよりも新しいアセンブリ バージョンが作成されることを意味します。これで、固有のバージョン番号を取得できました。

ビューで必要なときにこの情報を取得するのに役立つ UrlHelperExtension クラスを作成します。

public static class UrlHelperExtensions
{
    public static string ContentVersioned(this UrlHelper self, string contentPath)
    {
        string versionedContentPath = contentPath + "?v=" + Assembly.GetAssembly(typeof(UrlHelperExtensions)).GetName().Version.ToString();
        return self.Content(versionedContentPath);
    }
}

次の方法で、ビューにバージョン番号を簡単に追加できるようになりました。

<link href="@Url.ContentVersioned("style.css")" rel="stylesheet" type="text/css" />

ページのソースを表示すると、次のようになります。

<link href="style.css?v=1.0.4809.30029" rel="stylesheet" type="text/css" />
于 2013-03-02T17:08:49.877 に答える
9

更新:以前のバージョンは Azure で動作しませんでした。簡略化して以下に修正しました。(これを IIS Express の開発モードで動作させるには、Microsoft http://www.iis.net/downloads/microsoft/url-rewriteから URL Rewrite 2.0 をインストールする必要があります。これは WebPi インストーラーを使用します。最初に Visual Studio を閉じます)

クエリ文字列を追加するのではなく、ファイルの実際の名前を変更したい場合 (静的ファイルの一部のプロキシ/ブラウザーでは無視されます)、次の手順に従います。ソリューションを開発しながら、それを横切って:

方法: プロジェクトがビルドされるたびにアセンブリ バージョンを自動インクリメントし、更新を維持したい特定のリソースのルーティングされた静的ファイルにその番号を使用します。(そのため、something.js は something.v1234.js として含まれ、プロジェクトがビルドされるたびに 1234 が自動的に変更されます) - .min.js ファイルが本番環境で使用され、regular.js ファイルが使用されるようにするための追加機能もいくつか追加しました。デバッグ時 (縮小プロセスを自動化するために WebGrease を使用しています) このソリューションの優れた点の 1 つは、ローカル/開発モードと本番環境で機能することです。(私は Visual Studio 2015 / Net 4.6 を使用していますが、これは以前のバージョンでも機能すると思います。

手順 1:ビルド時にアセンブリで自動インクリメントを有効にする AssemblyInfo.cs ファイル (プロジェクトの "プロパティ" セクションの下にあります) で、次の行を変更します。

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

[assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyFileVersion("1.0.0.0")]

手順 2:バージョン スラッグが埋め込まれたファイルに対して、web.config で URL 書き換えを設定します (手順 3 を参照) 。

web.config (プロジェクトのメインのもの) で 、終了タグ <system.webServer>の直後に置くセクションに次のルールを追加します。</httpProtocol>

<rewrite>
  <rules>
    <rule name="static-autoversion">
      <match url="^(.*)([.]v[0-9]+)([.](js|css))$" />
      <action type="Rewrite" url="{R:1}{R:3}" />
    </rule>
    <rule name="static-autoversion-min">
      <match url="^(.*)([.]v[0-9]+)([.]min[.](js|css))$" />
      <action type="Rewrite" url="{R:1}{R:3}" />
    </rule>
  </rules>
</rewrite>

手順 3:アプリケーション変数をセットアップして、現在のアセンブリ バージョンを読み取り、js および css ファイルにバージョン スラッグを作成します。

Global.asax.cs (プロジェクトのルートにあります) で、次のコードを protected void Application_Start() (Register 行の後) に追加します。

            // setup application variables to write versions in razor (including .min extension when not debugging)
            string addMin = ".min";
            if (System.Diagnostics.Debugger.IsAttached) { addMin = ""; }  // don't use minified files when executing locally
            Application["JSVer"] = "v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString().Replace('.','0') + addMin + ".js";
            Application["CSSVer"] = "v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString().Replace('.', '0') + addMin + ".css";

手順 4: Global.asax.cs で設定したアプリケーション変数を使用して、Razor ビューの src リンクを変更する

@HttpContext.Current.Application["CSSVer"]
@HttpContext.Current.Application["JSVer"]

たとえば、_Layout.cshtml の head セクションには、スタイルシート用に次のコード ブロックがあります。

<!-- Load all stylesheets -->
<link rel='stylesheet' href='https://fontastic.s3.amazonaws.com/8NNKTYdfdJLQS3D4kHqhLT/icons.css' />
<link rel='stylesheet' href='/Content/css/main-small.@HttpContext.Current.Application["CSSVer"]' />
<link rel='stylesheet' media='(min-width: 700px)' href='/Content/css/medium.@HttpContext.Current.Application["CSSVer"]' />
<link rel='stylesheet' media='(min-width: 700px)' href='/Content/css/large.@HttpContext.Current.Application["CSSVer"]' />
@RenderSection("PageCSS", required: false)

ここで注意すべき点がいくつかあります。1)ファイルに拡張子がありません。2) .min もありません。これらは両方とも、Global.asax.cs のコードによって処理されます。

同様に、(_Layout.csでも)私のjavascriptセクションで:次のコードがあります:

<script src="~/Scripts/all3bnd100.min.js" type="text/javascript"></script>
<script src="~/Scripts/ui.@HttpContext.Current.Application["JSVer"]" type="text/javascript"></script>
@RenderSection("scripts", required: false)

最初のファイルは、私が WebGrease で手動で作成したすべてのサードパーティ ライブラリのバンドルです。バンドル内のファイルのいずれかを追加または変更する場合 (これはまれです)、ファイルの名前を手動で all3bnd101.min.js、all3bnd102.min.js などに変更します... このファイルは書き換えハンドラーと一致しないため、名前を手動で再バンドル/変更するまで、クライアント ブラウザにキャッシュされたままになります。

2 番目のファイルは ui.js (デバッグ モードで実行しているかどうかに応じて ui.v12345123.js または ui.v12345123.min.js として書き込まれます) これは処理/書き換えられます。(Global.asax.cs の Application_OnBeginRequest にブレークポイントを設定して、動作を確認できます)

これに関する詳細な説明: Simplified Auto-Versioning of Javascript / CSS in ASP.NET MVC 5 to stop caching issues (Azure および Locally で動作) URL Rewrite の有無にかかわらず (URL Rewrite なしでそれを行う方法を含む)

于 2015-12-08T07:48:41.117 に答える
6

1)代わりにファイル変更時間を使用します。次に例を示します。

public static string GeneratePathWithTime(string cssFileName)
{
  var serverFilePath = server.MapPath("~/static/" + cssFileName);
  var version = File.GetLastWriteTime(serverFilePath).ToString("yyyyMMddhhmmss");
  return string.Format("/static/{0}/{1}", version, cssFileName);
}

/static/201109231100/style.cssこれにより、「 」のようなパスが生成されます(あなたがディレクトリにあるとstyle.css仮定します)。次に、IISに書き換えルールを追加して、「」を「」に書き換えます。バージョン番号は、cssファイルが変更された場合にのみ変更され、変更されたファイルにのみ適用されます。style.cssstatic/static/201109231100/style.css/static/style.css

2)HttpModuleを介して123.jsへのリクエストを処理し、その最新のコンテンツを送信することはできますが、リクエストが最新バージョンを取得することを保証できるとは思いません。これは、ブラウザがキャッシュを処理する方法によって異なります。応答ヘッダーでより早い有効期限(たとえば、1分前)を設定して、常にファイルを再ダウンロードするようにブラウザーに指示できますが、ファイルを再ダウンロードするかどうかを決定するのはブラウザー自体です。 。そのため、質問1)でファイルを更新するたびに、変更されたファイルに対して異なるパスを生成する必要があります。URLにアクセスしたことがない場合、ブラウザは常にファイルのダウンロードを試みます。

于 2011-09-23T04:14:05.440 に答える
4

CacheBusting を実行する Url Helper を作成しました。

public static string CacheBustedContent(this UrlHelper helper, string contentPath)
{
    var path = string.Empty;

    if (helper.RequestContext.HttpContext.Cache["static-resource-" + contentPath] == null)
    {
        var fullpath = helper.RequestContext.HttpContext.Server.MapPath(contentPath);
        var md5 = GetMD5HashFromFile(fullpath);
        path = helper.Content(contentPath) + "?v=" + md5;

        helper.RequestContext.HttpContext.Cache.Add("static-resource-" + contentPath, path, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(24, 0, 0), System.Web.Caching.CacheItemPriority.Default, null);
    }
    else
    {
        path = helper.RequestContext.HttpContext.Cache["static-resource-" + contentPath].ToString();
    }

    return path;
}

GetMD5HashFromFile() を、ファイルの内容または最終変更日に基づいて一意の文字列を生成する CRC またはその他の種類の呼び出しに置き換えることができます。

欠点は、キャッシュが無効化されるたびに呼び出されることです。また、何らかの方法でファイルをライブで変更しても、アプリケーション プールをリセットしない場合は、おそらく web.config を変更して正しく再読み込みする必要があります。

于 2012-08-14T18:29:29.593 に答える
3

Dean Hume の Blogpost MVC と HTML5 Application Cache を参照してください。その投稿で、彼は@ShirtlessKirkのクラス ライブラリを使用して、リクエストごとにバージョン管理を自動的に処理するエレガントな方法を指摘しています。

@Url.Content("~/Content/Site.css").AppendHash(Request)
于 2011-09-23T21:49:50.387 に答える