问题:
无论我多么确定我的事务已提交且应用程序可以从数据库中读取绝对最新信息,有时当我刷新应用程序时,更改未显示最新数据,我怀疑数据正在被缓存在浏览器中!这种怀疑来自于在进行更改并查看更改后在其他浏览器中加载Web应用程序。我需要这样做,以便每次刷新页面时,这些数据都不会在浏览器中缓存。
设置:
一个Web应用程序只是从数据库中读取,而AJAX调用是客户端的一个REST API,用于添加,删除和更新数据。
我一直在做很多研究,我在这里找到的最有价值的资源是: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;
}
}
现在如上所示,带有contextTransaction.Commit()的context.SaveChanges()我确保数据被写入数据库并且不会在任何级别进行缓存。我通过使用服务器资源管理器并观察内容实时更新来确认这一点。
我还认为我已经确认我的阅读将通过在更改完成后将Web应用程序加载到另一个浏览器中来从数据库中提取最新信息,但我承认这也可能是我的缓存问题不知道。
我的最后一步是绕过浏览器中发生的缓存。我知道chrome允许您清除应用程序托管数据,但我不知道如何使某些数据不被缓存,以便每次请求发生时此代码都会执行。
有关REST API的更多详细信息: 上面示例的Controller看起来几乎与此相同:
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应用程序的更多详细信息: 视图模型在其构造函数中创建一个IntegrationManager作为临时变量,以便按如下方式调用getLinks:
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 :(得分: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);
}
}
我还在查看是否需要包含所有内容的详细信息,因为它确实会增加页面显着加载的时间。