EF 中的 ObjectContext 处置存储库 ASP.NET MVC 3 应用程序
因此,当我尝试通过对象访问 ObjectContext
时,出现 The ObjectContext 实例已被释放,无法再用于需要连接的操作。
错误OnActionExecuting
ActionFilterAttribute
中的存储库。
我的 ActionFilterAttribute
检查 HTTP cookie 是否存在。如果存在,它会使用数据库验证它,刷新其过期时间,然后将其添加到 Controller
ViewData
集合中,以便可以通过 ActionResult
的。如果不存在,则会将用户重定向到登录页面。
过滤器一半起作用是因为当 HTTP cookie 确实存在并且它尝试从数据库中获取具体对象时,它会崩溃并显示上述错误消息。
由于已设置的层数较多,我将继续将代码发布到所有层,VerifyCookieAttribute.cs
、CookieRepository.cs
和 Repository_1.cs
。最后,虽然可能没有任何区别,但错误发生在 Repository_1.cs
的 SelectSingle
方法中。
依赖注入是由 Ninject 2.2.1.0 实现的。延迟加载当前已启用,但任一设置都会产生相同的错误。
不管怎样,我希望能得到一些指导来说明我在这一切方面出错的地方。预先感谢您的任何帮助!
// VerifyCookieAttribute.cs
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
internal class VerifyCookieAttribute : ActionFilterAttribute {
[Inject]
public CookieRepository Repository { private get; set; }
private HttpRequestBase Request = null;
private HttpResponseBase Response = null;
private readonly bool Administration = false;
private readonly bool Customers = false;
private readonly string[] ExcludedPaths = new string[2] {
"/Administration",
"/Customers"
};
public VerifyCookieAttribute(
bool Administration,
bool Customers) {
this.Administration = Administration;
this.Customers = Customers;
}
public override void OnActionExecuting(
ActionExecutingContext ActionExecutingContext) {
this.Request = ActionExecutingContext.HttpContext.Request;
if (!this.ExcludedPaths.Contains(this.Request.Url.AbsolutePath)) {
this.Response = ActionExecutingContext.HttpContext.Response;
if (this.Exists()) {
Cookie Cookie = this.Get();
this.Refresh(Cookie);
ActionExecutingContext.Controller.ViewData.Add("Cookie", Cookie);
if (this.Administration) {
ActionExecutingContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {
area = "Administration",
controller = "Administration",
action = "Dashboard"
}));
} else if (this.Customers) {
// Do Nothing
};
} else if (!this.Exists() && !this.Response.IsRequestBeingRedirected) {
if (this.Administration) {
ActionExecutingContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {
area = "Administration",
controller = "Administration",
action = "Default"
}));
} else if (this.Customers) {
ActionExecutingContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {
area = "Customers",
controller = "Customers",
action = "Default"
}));
};
};
};
}
private bool Exists() {
string Token = this.GetHttpCookieToken();
return (!String.IsNullOrEmpty(Token) && (Token.Length == 256));
}
private Cookie Get() {
string Token = this.GetHttpCookieToken();
Cookie Cookie = this.Repository.SelectSingle(
c =>
(c.Token == Token));
return (Cookie);
}
private string GetHttpCookieToken() {
if (this.Request.Cookies["NWP"] != null) {
return this.Request.Cookies["NWP"]["Token"];
};
return (string.Empty);
}
private void Refresh(
Cookie Cookie) {
if (Cookie.RefreshStamp <= DateTime.Now.AddHours(1)) {
this.Repository.RefreshCookie(Cookie.CookieId);
this.SetHttpCookie(Cookie);
};
}
private void SetHttpCookie(
Cookie Cookie) {
this.Response.Cookies["NWP"]["Token"] = Cookie.Token;
this.Response.Cookies["NWP"].Expires = Cookie.RefreshStamp.AddHours(1);
}
}
// CookieRepository.cs
public sealed class CookieRepository : Repository<Cookie> {
[Inject]
public CookieRepository(
Entities Entities)
: base(Entities, true) {
}
public void RefreshCookie(
int CookieId) {
this.Entities.ExecuteFunction("RefreshCookie", new ObjectParameter("CookieId", CookieId));
}
}
// Repository`1.cs
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class {
protected readonly Entities Entities = null;
private readonly IObjectSet<TEntity> EntitySet = null;
[Inject]
public Repository(
Entities Entities)
: this(Entities, true) {
}
[Inject]
public Repository(
Entities Entities,
bool CreateEntitySet) {
this.Entities = Entities;
if (CreateEntitySet) {
this.EntitySet = this.Entities.CreateObjectSet<TEntity>();
};
}
public virtual void Delete(
TEntity TEntity) {
this.EntitySet.DeleteObject(TEntity);
}
public virtual void Insert(
TEntity TEntity) {
this.EntitySet.AddObject(TEntity);
}
public virtual IQueryable<TEntity> Select() {
return this.EntitySet;
}
public virtual IQueryable<TEntity> Select(
Expression<Func<TEntity, bool>> Selector) {
return this.EntitySet.Where(Selector);
}
public virtual bool SelectAny(
Expression<Func<TEntity, bool>> Selector) {
return this.EntitySet.Any(Selector);
}
public virtual IList<TEntity> SelectList() {
return this.EntitySet.ToList();
}
public virtual IList<TEntity> SelectList(
Expression<Func<TEntity, bool>> Selector) {
return this.EntitySet.Where(Selector).ToList();
}
private IList<TEntity> SelectOrderedList(
bool Ascending,
params Expression<Func<TEntity, IComparable>>[] Orderers) {
IOrderedQueryable<TEntity> Queryable = null;
foreach (Expression<Func<TEntity, IComparable>> Orderer in Orderers) {
if (Queryable == null) {
Queryable = (Ascending ? this.EntitySet.OrderBy(Orderer) : this.EntitySet.OrderByDescending(Orderer));
} else {
Queryable = (Ascending ? Queryable.ThenBy(Orderer) : Queryable.ThenByDescending(Orderer));
};
};
return (Queryable.ToList());
}
public virtual IList<TEntity> SelectOrderedList(
params Expression<Func<TEntity, IComparable>>[] Orderers) {
return this.SelectOrderedList(true, Orderers);
}
public virtual IList<TEntity> SelectOrderedDescendingList(
params Expression<Func<TEntity, IComparable>>[] Orderers) {
return this.SelectOrderedList(false, Orderers);
}
public virtual TEntity SelectSingle(
Expression<Func<TEntity, bool>> Selector) {
return this.EntitySet.Single(Selector);
}
public virtual void Update() {
this.Entities.SaveChanges();
}
public virtual IEnumerable<TEntity> Where(
Expression<Func<TEntity, bool>> Selector) {
return this.EntitySet.Where(Selector);
}
}
更新
这是每个@jfar请求的堆栈跟踪:
System.Data.Objects.ObjectContext.EnsureConnection() +8550458 System.Data.Objects.ObjectQuery
1.GetResults(Nullable
1 forMergeOption) +46 System.Data.Objects.ObjectQuery1.System.Collections.Generic.IEnumerable
1 源)+184 System.Data.Objects.ELinq.ObjectQueryProvider.b_3(IEnumerable1 序列)+41 System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle(IEnumerable
1 查询,表达式 queryRoot)+59 System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute(表达式表达式)+150 System.Linq.Queryable.Single(IQueryable1 源,表达式
1 谓词) +300 C:\Projects{WITHHELD}{WITHHELD}\Repositories\Repository1.cs:98 中的 {WITHHELD}.Repositories.Repository
1延续)+47 System.Web.Mvc.<>c_DisplayClass17.b_14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter 过滤器,ActionExecutingContext preContext,Func1.SelectSingle(Expression
1 选择器) C:\Projects\{WITHHELD}\{WITHHELD}\Attributes\VerifyCookieAttribute.cs 中的VerifyCookieAttribute.Get():100 C:\Projects\{WITHHELD}\{WITHHELD}\Attributes\VerifyCookieAttribute.cs:55 中的VerifyCookieAttribute.OnActionExecuting(ActionExecutingContext ActionExecutingContext) System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter过滤器,ActionExecutingContext preContext,Func1 延续)+263 System.Web.Mvc。<>c__DisplayClass17。
1延续)+263 System.Web.Mvc.<>c_DisplayClass17.b_14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter 过滤器,ActionExecutingContext preContext,Func1 延续)+263 System.Web.Mvc。<>c__DisplayClass17。
1个过滤器,ActionDescriptoractionDescriptor,IDictionary2个参数)+191 System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContextcontrollerContext,字符串actionName)+343 System.Web.Mvc.Controller.ExecuteCore() +116 System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97 System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10 System.Web.Mvc.<>c__DisplayClassb.
1.b_7(IAsyncResult ) +12 System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62 System.Web.Mvc.<>c_DisplayClasse.b_d() +50 System.Web.Mvc.SecurityUtil.b_0(操作f)+7 System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(操作操作)+22 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult 结果) +9 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8862381 System.Web.HttpApplication.ExecuteStep(IExecutionStep 步骤,Boolean&completedSynchronously) +184
so, I'm getting a The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
error when I try to access the ObjectContext
through a repository in an OnActionExecuting
ActionFilterAttribute
.
My ActionFilterAttribute
checks for the existence of an HTTP cookie. If it exists it verifies it with the database, refreshes it's expiration, and then adds it to the Controller
ViewData
collection so it can be accessed by ActionResult
's. If it doesn't exist, then it redirects the user to the login page.
The filter half works because when an HTTP cookie does exist and it attempts to grab the concrete object out of the database, it crashes with the above error message.
Because of the number of layers that are in place, I'm gonna go ahead and post the code to all of them, VerifyCookieAttribute.cs
, CookieRepository.cs
and Repository_1.cs
. Lastly, although it probably does not make any difference, the error occurs in the SelectSingle
method of Repository_1.cs
.
Dependency Injection is by Ninject 2.2.1.0. Lazy loading is currently enabled, but either setting produces the same error.
Anyway, I'd appreciate some guidance in where I'm going wrong with all of this. Thanks in advance for any help!
// VerifyCookieAttribute.cs
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
internal class VerifyCookieAttribute : ActionFilterAttribute {
[Inject]
public CookieRepository Repository { private get; set; }
private HttpRequestBase Request = null;
private HttpResponseBase Response = null;
private readonly bool Administration = false;
private readonly bool Customers = false;
private readonly string[] ExcludedPaths = new string[2] {
"/Administration",
"/Customers"
};
public VerifyCookieAttribute(
bool Administration,
bool Customers) {
this.Administration = Administration;
this.Customers = Customers;
}
public override void OnActionExecuting(
ActionExecutingContext ActionExecutingContext) {
this.Request = ActionExecutingContext.HttpContext.Request;
if (!this.ExcludedPaths.Contains(this.Request.Url.AbsolutePath)) {
this.Response = ActionExecutingContext.HttpContext.Response;
if (this.Exists()) {
Cookie Cookie = this.Get();
this.Refresh(Cookie);
ActionExecutingContext.Controller.ViewData.Add("Cookie", Cookie);
if (this.Administration) {
ActionExecutingContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {
area = "Administration",
controller = "Administration",
action = "Dashboard"
}));
} else if (this.Customers) {
// Do Nothing
};
} else if (!this.Exists() && !this.Response.IsRequestBeingRedirected) {
if (this.Administration) {
ActionExecutingContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {
area = "Administration",
controller = "Administration",
action = "Default"
}));
} else if (this.Customers) {
ActionExecutingContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {
area = "Customers",
controller = "Customers",
action = "Default"
}));
};
};
};
}
private bool Exists() {
string Token = this.GetHttpCookieToken();
return (!String.IsNullOrEmpty(Token) && (Token.Length == 256));
}
private Cookie Get() {
string Token = this.GetHttpCookieToken();
Cookie Cookie = this.Repository.SelectSingle(
c =>
(c.Token == Token));
return (Cookie);
}
private string GetHttpCookieToken() {
if (this.Request.Cookies["NWP"] != null) {
return this.Request.Cookies["NWP"]["Token"];
};
return (string.Empty);
}
private void Refresh(
Cookie Cookie) {
if (Cookie.RefreshStamp <= DateTime.Now.AddHours(1)) {
this.Repository.RefreshCookie(Cookie.CookieId);
this.SetHttpCookie(Cookie);
};
}
private void SetHttpCookie(
Cookie Cookie) {
this.Response.Cookies["NWP"]["Token"] = Cookie.Token;
this.Response.Cookies["NWP"].Expires = Cookie.RefreshStamp.AddHours(1);
}
}
// CookieRepository.cs
public sealed class CookieRepository : Repository<Cookie> {
[Inject]
public CookieRepository(
Entities Entities)
: base(Entities, true) {
}
public void RefreshCookie(
int CookieId) {
this.Entities.ExecuteFunction("RefreshCookie", new ObjectParameter("CookieId", CookieId));
}
}
// Repository`1.cs
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class {
protected readonly Entities Entities = null;
private readonly IObjectSet<TEntity> EntitySet = null;
[Inject]
public Repository(
Entities Entities)
: this(Entities, true) {
}
[Inject]
public Repository(
Entities Entities,
bool CreateEntitySet) {
this.Entities = Entities;
if (CreateEntitySet) {
this.EntitySet = this.Entities.CreateObjectSet<TEntity>();
};
}
public virtual void Delete(
TEntity TEntity) {
this.EntitySet.DeleteObject(TEntity);
}
public virtual void Insert(
TEntity TEntity) {
this.EntitySet.AddObject(TEntity);
}
public virtual IQueryable<TEntity> Select() {
return this.EntitySet;
}
public virtual IQueryable<TEntity> Select(
Expression<Func<TEntity, bool>> Selector) {
return this.EntitySet.Where(Selector);
}
public virtual bool SelectAny(
Expression<Func<TEntity, bool>> Selector) {
return this.EntitySet.Any(Selector);
}
public virtual IList<TEntity> SelectList() {
return this.EntitySet.ToList();
}
public virtual IList<TEntity> SelectList(
Expression<Func<TEntity, bool>> Selector) {
return this.EntitySet.Where(Selector).ToList();
}
private IList<TEntity> SelectOrderedList(
bool Ascending,
params Expression<Func<TEntity, IComparable>>[] Orderers) {
IOrderedQueryable<TEntity> Queryable = null;
foreach (Expression<Func<TEntity, IComparable>> Orderer in Orderers) {
if (Queryable == null) {
Queryable = (Ascending ? this.EntitySet.OrderBy(Orderer) : this.EntitySet.OrderByDescending(Orderer));
} else {
Queryable = (Ascending ? Queryable.ThenBy(Orderer) : Queryable.ThenByDescending(Orderer));
};
};
return (Queryable.ToList());
}
public virtual IList<TEntity> SelectOrderedList(
params Expression<Func<TEntity, IComparable>>[] Orderers) {
return this.SelectOrderedList(true, Orderers);
}
public virtual IList<TEntity> SelectOrderedDescendingList(
params Expression<Func<TEntity, IComparable>>[] Orderers) {
return this.SelectOrderedList(false, Orderers);
}
public virtual TEntity SelectSingle(
Expression<Func<TEntity, bool>> Selector) {
return this.EntitySet.Single(Selector);
}
public virtual void Update() {
this.Entities.SaveChanges();
}
public virtual IEnumerable<TEntity> Where(
Expression<Func<TEntity, bool>> Selector) {
return this.EntitySet.Where(Selector);
}
}
UPDATE
Here's the stack trace per @jfar's request:
System.Data.Objects.ObjectContext.EnsureConnection() +8550458
System.Data.Objects.ObjectQuery1.GetResults(Nullable
1 forMergeOption) +46
System.Data.Objects.ObjectQuery1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() +44
1 source) +184
System.Linq.Enumerable.Single(IEnumerable
System.Data.Objects.ELinq.ObjectQueryProvider.b_3(IEnumerable1 sequence) +41
1 query, Expression queryRoot) +59
System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle(IEnumerable
System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute(Expression expression) +150
System.Linq.Queryable.Single(IQueryable1 source, Expression
1 predicate) +300
{WITHHELD}.Repositories.Repository1.SelectSingle(Expression
1 Selector) in C:\Projects{WITHHELD}{WITHHELD}\Repositories\Repository1.cs:98
1 continuation) +47
VerifyCookieAttribute.Get() in C:\Projects\{WITHHELD}\{WITHHELD}\Attributes\VerifyCookieAttribute.cs:100
VerifyCookieAttribute.OnActionExecuting(ActionExecutingContext ActionExecutingContext) in C:\Projects\{WITHHELD}\{WITHHELD}\Attributes\VerifyCookieAttribute.cs:55
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func
System.Web.Mvc.<>c_DisplayClass17.b_14() +19
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) +263
1 continuation) +263
System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func
System.Web.Mvc.<>c_DisplayClass17.b_14() +19
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) +263
1 filters, ActionDescriptor actionDescriptor, IDictionary
System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList2 parameters) +191
1.b_7(IAsyncResult ) +12
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
System.Web.Mvc.Controller.ExecuteCore() +116
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
System.Web.Mvc.Async.<>c__DisplayClass8
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
System.Web.Mvc.<>c_DisplayClasse.b_d() +50
System.Web.Mvc.SecurityUtil.b_0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8862381
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我假设你使用的是 mvc 3。
这意味着不会为每个请求创建属性,因此任何
InRequestScope
注入都不起作用。您需要注入IServiceProvider
并在每个请求上获取存储库,或者手动创建新上下文。I assume you are using mvc 3.
This means that attributes are not created for every request, therefor any
InRequestScope
injection won't work. You will need to either injectIServiceProvider
and get your repository with that on each request or create new context manually.