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
首先,我建议您“真正”熟悉 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] 属性添加到您的操作中。
| 归档时间: |
|
| 查看次数: |
764 次 |
| 最近记录: |