2016-03-31 2 views
0

問題:どんなに私は、トランザクションがコミットされ、アプリケーションがデータベースから絶対的な最新情報を読み取ることができるということだかどうかはわかりEntity Frameworkの6.1.3、2つのWebアプリケーションの1つのSQLデータベース、ブラウザのキャッシュの問題

時にはアプリケーションを更新するときに、最新のデータが表示されず、データがブラウザにキャッシュされていると思われます。この疑念は、変更が行われた後に別のブラウザにWebアプリケーションをロードし、変更を確認することによって発生します。ページを更新するたびに、このデータはブラウザにキャッシュされないようにする必要があります。


セットアップ:AJAX呼び出しは、追加、削除、およびデータを更新REST APIにクライアント側を行っている間に

一つのWebアプリケーションは、単純に、データベースから読み込みます。

私は多くの研究をやっていると私は、この上で発見した最も貴重な資源はここにあった:データベースから読み込んhttp://mehdi.me/ambient-dbcontext-in-ef6/

私のコードは、このパターンを使用しています。

public IEnumerable<Link> GetLinks(){ 
    using (var context = new MyContext()){ 
     foreach(var link in context.ChangeTracker.Entries()) 
     { 
      link.Reload(); 
     } 
     return context.Links.Where(x => x.UserId == this.UserId).ToList(); 
    } 
} 

例今

public int AddLink(string text, string url) 
    { 
     using (var context = new MyContext()) 
     { 
      Link linkresult; 
      using (var contextTransaction = context.Database.BeginTransaction()) 
      { 
       var link = new Link() 
       { 
        Text = text, 
        Url = url 
        UserId = this.UserId 
       }; 

       linkresult = context.Links.Add(link); 
       context.SaveChanges(); 
       contextTransaction.Commit(); 
      } 
      return linkresult.Id; 
     } 
    } 

、上記context.SaveChangesを(示すように)contextTransaction.Commitと()私は:読み込み私の事業の一つで、このパターンを次のデータがデータベースに書き込まれ、どのレベルでもキャッシュされないようにします。私はサーバーエクスプローラを使用してこれを確認し、コンテンツがリアルタイムで更新されるのを見ています。

変更が加えられた後に別のブラウザにWebアプリケーションを読み込むことで、私の読んだものがデータベースから最新の情報を引き出すことを確認したと思いますが、これは私が気づいていない。

私の最後のステップは、ブラウザで発生するキャッシングを回避することです。私はクロムがアプリケーションのホストされたデータをクリアできることを知っていますが、特定のデータがキャッシュされないようにする方法がわからないので、リクエストが発生するたびにこのコードが実行されます。 RESTのAPI上


詳細: 上記の例のためのコントローラは、これにほぼ同じになります:

public ActionResult AddLink(MyLink model) 
    { 
     IntegrationManager manager = new IntegrationManager(System.Web.HttpContext.Current.User); 
     model.Id = manager.AddLink(model.Text, model.Url); 
     return Json(model); 
    } 

IntegrationManagerがあるためIDisposableインターを実装していないだけで、基本的なクラスです。コンテキストは、各トランザクション中に作成され処分されます。ご覧のとおり、AddLinkはIntegrationManagerクラスのメンバーです。Webアプリケーション


詳細: ビューのモデルは以下のようにgetLinksを呼び出すようにする一時的な変数としてのコンストラクタでIntegrationManagerを作成します。

public Home(IPrincipal user, Cache cache) 
    { 
     this.HttpCache = cache; 

     IntegrationManager _IntegrationManager = new IntegrationManager(user); 
     this.Links = this.GetLinks(_IntegrationManager); 

    } 

AJAXコール

  .on("click", "#btn-add-link", function (event) { 
       var text = $("#add-link-text"), 
        url = $("#add-link-url"); 

       if (text.val().length > 0 && url.val().length > 0) { 
        var hasHttp = /^http.*$/.test(url.val()); 
        if (!hasHttp) { 
         url.val("http://" + url.val()); 
        } 

        $.ajax({ 
         url: addLinkUrl, 
         type: "POST", 
         data: { Text: text.val(), Url: url.val() } 
        }).success(function (data) { 
         var newLink = $('<li class="ui-state-default deletable" id="link-' + data.Id + '"><a href="' + data.Url + '" target="_blank">' + data.Text + '</a></li>'); 

         $("#user-links").append(newLink); 

         text.val(""); 
         url.val(""); 

        }); 
+0

ビューやコントローラコードを投稿できますか? – esmoore68

+0

@ esmoore68確かに、それは数分かかるでしょう。 –

+1

それが非同期のHttp GET呼び出しであれば、それは非常にうまくいく可能性があります。ヘッダー内のコンテンツの長さを指定することも、URLにランダムな名前/値のペアを適用することもできます。これにより、コンテンツが異なり、サーバーへのトリップが必要であることがブラウザに通知されます。 JQueryにもプロパティがあります。ブラウザがAJAX Getコールのキャッシュに依存していないことを確認できるように設定できると確信していますが、実際にその設定に従っているブラウザーとバージョンが常に十分に文書化されているわけではありません。 – Igor

答えて

0

さて、キャッシングが起こらないようにする方法を見つけました。以下はNoCacheというWebアプリケーションのコントローラの属性です。ここで

using whatever.namespace.nocache.lives.in 

[NoCache] 

属性の詳細です:

public class NoCacheAttribute : ActionFilterAttribute 
{ 
    public override void OnResultExecuting(ResultExecutingContext filterContext) 
    { 
     filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1)); 
     filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false); 
     filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); 
     filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
     filterContext.HttpContext.Response.Cache.SetNoStore(); 

     base.OnResultExecuting(filterContext); 
    } 
} 

私はまだ私はすべてを必要とするか否かの詳細を探しています、それを使用するには、コントローラは、このような属性が必要になりますこれは、ページが大幅に読み込まれる時間が長くなるために含まれています。

関連する問題