【问题标题】:ObjectContext disposal in EF + Repository ASP.NET MVC 3 applicationEF + Repository ASP.NET MVC 3 应用程序中的 ObjectContext 处理
【发布时间】:2011-04-29 17:40:23
【问题描述】:

所以,当我尝试通过OnActionExecutingActionFilterAttribute 中的存储库访问ObjectContext 时,我收到了The ObjectContext instance has been disposed and can no longer be used for operations that require a connection. 错误。

我的ActionFilterAttribute 检查是否存在 HTTP cookie。如果它存在,它会用数据库验证它,刷新它的过期时间,然后将它添加到ControllerViewData 集合中,以便ActionResult 可以访问它。如果不存在,则将用户重定向到登录页面。

过滤器的一半起作用,因为当 HTTP cookie确实存在并且它试图从数据库中抓取具体对象时,它会崩溃并显示上述错误消息。

由于存在的层数,我将继续将代码发布到所有层,VerifyCookieAttribute.csCookieRepository.csRepository_1.cs。最后,虽然它可能没有任何区别,但错误发生在Repository_1.csSelectSingle方法中。

依赖注入是由 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.ObjectQuery1.GetResults(Nullable1 forMergeOption) +46 System.Data.Objects.ObjectQuery1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() +44 System.Linq.Enumerable.Single(IEnumerable1 source) +184 System.Data.Objects.ELinq.ObjectQueryProvider.b_3(IEnumerable1 sequence) +41 System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle(IEnumerable1 query, Expression queryRoot) +59 System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute(Expression expression) +150 System.Linq.Queryable.Single(IQueryable1 source, Expression1 predicate) +300 {WITHHELD}.Repositories.Repository1.SelectSingle(Expression1 Selector) in C:\Projects{WITHHELD}{WITHHELD}\Repositories\Repository1.cs:98 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, Func1 continuation) +47 System.Web.Mvc.<>c_DisplayClass17.b_14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) +263 System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) +263 System.Web.Mvc.<>c_DisplayClass17.b_14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func1 continuation) +263 System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList1 filters, ActionDescriptor actionDescriptor, IDictionary2 parameters) +191 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__DisplayClass81.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(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

【问题讨论】:

  • 你能贴出抛出异常的堆栈跟踪吗?听起来像是延迟加载问题,但需要堆栈才能看到。
  • @jfar,我用堆栈跟踪更新了帖子。我不知道如何为 SO 正确格式化它,所以我尽我所能......

标签: c# asp.net-mvc entity-framework repository


【解决方案1】:

我假设您使用的是 mvc 3。

在以前版本的 ASP.NET MVC 中, 根据请求创建操作过滤器 除了少数情况。这种行为 从来都不是有保证的行为,但 只是一个实现细节和 过滤器的合同是 认为他们是无国籍的。在 ASP.NET 中 MVC 3,过滤器缓存更多 积极地。因此,任何习俗 不正确存储的动作过滤器 实例状态可能被破坏。

这意味着不是为每个请求创建属性,因此任何InRequestScope 注入都不起作用。您将需要注入 IServiceProvider 并在每次请求时获取您的存储库,或者手动创建新上下文。

【讨论】:

  • 谢谢@Lukas!实际上我记得不久前读过它,但我从来没有费心去吸收它,因为当时我没有使用 DI...
猜你喜欢
  • 2013-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-25
  • 1970-01-01
  • 2012-06-05
  • 2011-11-09
相关资源
最近更新 更多