EF 中的 ObjectContext 处置存储库 ASP.NET MVC 3 应用程序

发布于 2024-11-04 07:15:10 字数 11171 浏览 2 评论 0原文

因此,当我尝试通过对象访问 ObjectContext 时,出现 The ObjectContext 实例已被释放,无法再用于需要连接的操作。 错误OnActionExecuting ActionFilterAttribute 中的存储库。

我的 ActionFilterAttribute 检查 HTTP cookie 是否存在。如果存在,它会使用数据库验证它,刷新其过期时间,然后将其添加到 Controller ViewData 集合中,以便可以通过 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.GetEnumerator() +44 System.Linq.Enumerable.Single(IEnumerable1 源)+184 System.Data.Objects.ELinq.ObjectQueryProvider.b_3(IEnumerable1 序列)+41 System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle(IEnumerable1 查询,表达式 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.Repository1.SelectSingle(Expression1 选择器) 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延续)+47 System.Web.Mvc.<>c_DisplayClass17.b_14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter 过滤器,ActionExecutingContext preContext,Func1 延续)+263 System.Web.Mvc。<>c__DisplayClass17。b__14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter过滤器,ActionExecutingContext preContext,Func1延续)+263 System.Web.Mvc.<>c_DisplayClass17.b_14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter 过滤器,ActionExecutingContext preContext,Func1 延续)+263 System.Web.Mvc。<>c__DisplayClass17。b__14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContextcontrollerContext,IList1个过滤器,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.b__5() +37 System.Web.Mvc.Async.<>c__DisplayClass1.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(操作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(Nullable1 forMergeOption) +46
System.Data.Objects.ObjectQuery1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() +44
System.Linq.Enumerable.Single(IEnumerable
1 source) +184
System.Data.Objects.ELinq.ObjectQueryProvider.b_3(IEnumerable1 sequence) +41
System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle(IEnumerable
1 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, Func
1 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, Func
1 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, IList
1 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__DisplayClass8
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(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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心头的小情儿 2024-11-11 07:15:10

我假设你使用的是 mvc 3。

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

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

I assume you are using mvc 3.

In previous versions of ASP.NET MVC,
action filters are create per request
except in a few cases. This behavior
was never a guaranteed behavior but
merely an implementation detail and
the contract for filters was to
consider them stateless. In ASP.NET
MVC 3, filters are cached more
aggressively. Therefore, any custom
action filters which improperly store
instance state might be broken.

This means that attributes are not created for every request, therefor any InRequestScope injection won't work. You will need to either inject IServiceProvider and get your repository with that on each request or create new context manually.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文