Удаление ObjectContext в приложении EF + Repository ASP.NET MVC 3 - PullRequest
1 голос
/ 29 апреля 2011

Итак, я получаю ошибку The ObjectContext instance has been disposed and can no longer be used for operations that require a connection., когда пытаюсь получить доступ к ObjectContext через репозиторий в OnActionExecuting ActionFilterAttribute.

Мой ActionFilterAttribute проверяет наличиеHTTP-cookie.Если он существует, он проверяет его с базой данных, обновляет срок его действия, а затем добавляет его в коллекцию Controller ViewData, чтобы к нему могли получить доступ ActionResult.Если он не существует, он перенаправляет пользователя на страницу входа в систему.

Половина фильтра работает, потому что, когда HTTP-cookie существует , и пытается извлечь конкретный объект изв базе данных происходит сбой с указанным выше сообщением об ошибке.

Из-за количества имеющихся слоев я собираюсь отправить код всем из них, VerifyCookieAttribute.cs, CookieRepository.csи Repository_1.cs.Наконец, хотя это, вероятно, не имеет никакого значения, ошибка возникает в методе SelectSingle Repository_1.cs.

Внедрение зависимостей от 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<code>1.GetResults(Nullable 1 forMergeOption)+46 System.Data.Objects.ObjectQuery 1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() +44 System.Linq.Enumerable.Single(IEnumerable 1 источник) +184 System.Data.Objects.ELinq.ObjectQueryProvider.b_ 3 (IEnumerable 1 sequence) +41 System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle(IEnumerable 1 запрос, выражение expressionRoot) +59 System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute (выражение-выражение) +150 System.Linq.Queryable.Single (предикат IQueryable 1 source, Expression 1) +300 {WITHHELD} .Repositories.Repository 1.SelectSingle(Expression 1 селектор) в C: \ Projects {WITHHELD} {WITHHELD} \ Репозитории \ Репозиторий 1.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 продолжение) +47 System.Web.Mvc. <> C _DisplayClass17.b_ 14 () +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter (фильтр IActionFilter, preContext ActionExecutingContext, продолжение Func 1 continuation) +263 System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func 1) +263 System.Web.Mvc. <> C _DisplayClass17.b_ 14 () +19 System.Webrol.InvokeActionMethodFilter (фильтр IActionFilter, ActionExecutingContext preContext, Func 1 continuation) +263 System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList 1 фильтры, ActionDescriptor actionDescriptor, IDictionary 2 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 Система.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 (IAsyncResultS.Web.HttpApplication.IExecutionStep.Execute () +8862381 System.Web.HttpApplication.ExecuteStep (шаг IExecutionStep, логический и завершенный синхронно) +184

1 Ответ

2 голосов
/ 30 апреля 2011

Я предполагаю, что вы используете mvc 3.

В предыдущих версиях ASP.NET MVC фильтры действий создавались по запросу, за исключением нескольких случаев.Такое поведение никогда не было гарантированным поведением, а являлось лишь деталью реализации, и контракт на фильтры заключался в том, чтобы считать их не имеющими состояния.В ASP.NET MVC 3 фильтры кэшируются более агрессивно.Следовательно, любые фильтры пользовательских действий, которые неправильно хранят состояние экземпляра, могут быть повреждены.

Это означает, что атрибуты не созданы для каждого запроса, поэтому любое внедрение InRequestScope не будетРабота.Вам нужно будет либо внедрить IServiceProvider и получить свой репозиторий с каждым запросом, либо создать новый контекст вручную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...