处理DbContext后出现问题

Mac*_*ack 8 dispose entity-framework-4 asp.net-mvc-3 dbcontext

我最近更改了我的MVC3应用程序,试图正确处理DbContext对象[1].这在开发中非常有用,但是一旦应用程序被推送到我的生产服务器,我就开始间歇性地获得一些有趣的例外,这些例外会一直存在,直到AppPool被回收.异常可以追溯到我的自定义中的代码AuthorizeAttribute,如下所示:

System.InvalidOperationException: The 'Username' property on 'User' could not be set to a 'Int32' value. You must set this property to a non-null value of type 'String'.

System.InvalidOperationException: The 'Code' property on 'Right' could not be set to a 'String' value. You must set this property to a non-null value of type 'Int32'. 
Run Code Online (Sandbox Code Playgroud)

(数据库模式如下所示:用户:[Guid,String,...],权利:[Guid,Int32,...])

就好像某些"电线越过",应用程序混合了数据库的Right结果:试图将结果表示为a User,反之亦然.

为了管理处理DbContext,我把代码放在每个控制器级别存储.当处理控制器时,我也将其丢弃DbContext.我知道它很hacky,但是AuthorizeAttribute使用相同的上下文filterContext.Controller.

处理DbContext这个庄园的物体生命周期有什么问题吗?关于为什么我得到上述十字交叉的例外,是否有任何合理的解释?

[1]虽然我知道没有必要处理DbContext对象,但我最近遇到了许多消息来源,说明这是最好的做法.

编辑(按@ MikeSW的评论)

当在范围内时,在方法中设置AuthorizeAttribute表示的属性.稍后在该方法中使用此属性.DbContextOnAuthorizationAuthorizationContextAuthorizeCore

Mat*_*cic 0

首先,我建议您“真正”熟悉 IIS 7.0 的 ASP.NET 应用程序生命周期概述,因为它是良好的 MVC 应用程序设计的基础。

现在尝试“模仿”您的代码库

假设您有一个类似的自定义 MembershipProvider,如此处所述/sf/answers/704691431/

那么你只需要一个自定义Authorize属性

public sealed class AuthorizeByRoles : AuthorizeAttribute
    {
        public AuthorizeByRoles(params UserRoles[] userRoles)
        {
            this.Roles = AuthorizationHelper.GetRolesForEnums(userRoles);
        }
    }

public static class AuthorizationHelper
{       
    public static string GetRolesForEnums(params UserRoles[] userRoles)
    {
        List<string> roles = new List<string>();
        foreach (UserRoles userRole in userRoles)
        {
            roles.Add(GetEnumName(userRole));
        }
        return string.Join(",", roles);
    }

    private static string GetEnumName(UserRoles userRole)
    {
        return Enum.GetName(userRole.GetType(), userRole);
    }        
}
Run Code Online (Sandbox Code Playgroud)

您可以在任何控制器或特定操作上使用它

 [AuthorizeByRoles(UserRoles.Admin, UserRoles.Developer)]
 public class MySecureController : Controller
 {
      //your code here
 }
Run Code Online (Sandbox Code Playgroud)

如果您愿意,您还可以订阅该PostAuthorizeRequest事件并根据某些条件丢弃结果。

 protected void Application_PostAuthorizeRequest(Object sender, EventArgs e)
        {

            //do what you need here
        }
Run Code Online (Sandbox Code Playgroud)

至于DbContext,我从未遇到过您的情况,是的,每个请求是正确的方法,因此您可以将其处置在控制器或存储库中。

当然,建议您使用过滤器,然后将 [AllowAnonymous] 属性添加到您的操作中。