ASP.NET Identity 2.0 Roles.IsUserInRole 给出 "Invalid object name 'dbo.aspnet_SchemaVersions'.&qu
Posted
技术标签:
【中文标题】ASP.NET Identity 2.0 Roles.IsUserInRole 给出 "Invalid object name \'dbo.aspnet_SchemaVersions\'." 异常【英文标题】:ASP.NET Identity 2.0 Roles.IsUserInRole gives "Invalid object name 'dbo.aspnet_SchemaVersions'." exceptionASP.NET Identity 2.0 Roles.IsUserInRole 给出 "Invalid object name 'dbo.aspnet_SchemaVersions'." 异常 【发布时间】:2014-12-24 22:22:11 【问题描述】:我使用 ASP.NET Identity 2.0,我想知道登录的用户是否具有“管理员”角色。在我的种子方法中,我创建了 3 个不同的角色,如下所示:
var store = new UserStore<ApplicationUser>(context);
var userManager = new ApplicationUserManager(store);
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
string roleName = "admin";
if (!roleManager.RoleExists(roleName))
roleManager.Create(new IdentityRole(roleName));
roleName = "superuser";
if (!roleManager.RoleExists(roleName))
roleManager.Create(new IdentityRole(roleName));
roleName = "user";
if (!roleManager.RoleExists(roleName))
roleManager.Create(new IdentityRole(roleName));
var user = new ApplicationUser() Email = "nsg@gmail.com", UserName = "Niclas" ;
userManager.Create(user, "123456");
userManager.AddToRole(user.Id, "Admin");
取决于用户是否是管理员,他需要在导航栏中看到不同的链接,所以我做了这个代码:
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@html.ActionLink("Lenio", "Index", "Home", new area = "" , new @class = "navbar-brand" )
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
@if (Roles.IsUserInRole(User.Identity.Name,"admin"))
<li>@Html.ActionLink("Admins", "Index", "Admins")</li>
<li>@Html.ActionLink("SuperUsers", "Index", "SuperUsers")</li>
<li>@Html.ActionLink("Users", "Index", "Users")</li>
<li>@Html.ActionLink("Areas", "Index", "Areas")</li>
<li>@Html.ActionLink("CDs", "Index", "CommunicationDevices")</li>
<li>@Html.ActionLink("Houses", "Index", "Houses")</li>
<li>@Html.ActionLink("Lendings", "Index", "Lendings")</li>
<li>@Html.ActionLink("Logs", "Index", "Logs")</li>
<li>@Html.ActionLink("Sensors", "Index", "Sensors")</li>
@if (User.IsInRole("user"))
<li>@Html.ActionLink("User", "Index", "Din bruger")</li>
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
@Html.Partial("_LoginPartial")
</div>
</div>
</div>
问题是当代码到达@if (Roles.IsUserInRole(User.Identity.Name,"admin"))
部分时,我得到一个"Invalid object name 'dbo.aspnet_SchemaVersions'."
异常。我的数据库中没有 aspnet_SchemaVersions 表,我不想要它。
这是与我拥有的身份相关的表格的图片:
数据库托管在 azure 上。
更新
DavidG 发布了一个解决初始问题的答案,但它没有解决我无法使用的问题:
[Authorize(Roles = "admin")]
我需要能够使用这个属性,但我不能,因为我得到了这个异常:
> [SqlException (0x80131904): Invalid object name 'dbo.aspnet_SchemaVersions'.]
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +1789294
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) +5340642
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) +244
System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) +1691
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +275
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds) +1421
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite) +177
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite) +208
System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +163
System.Web.Util.SecUtility.CheckSchemaVersion(ProviderBase provider, SqlConnection connection, String[] features, String version, Int32& schemaVersionCheck) +392
System.Web.Security.SqlRoleProvider.CheckSchemaVersion(SqlConnection connection) +64
System.Web.Security.SqlRoleProvider.GetRolesForUser(String username) +753
System.Web.Security.RolePrincipal.IsInRole(String role) +9625099
System.Linq.Enumerable.Any(IEnumerable`1 source, Func`2 predicate) +146
System.Web.Mvc.AuthorizeAttribute.AuthorizeCore(HttpContextBase httpContext) +333
System.Web.Mvc.AuthorizeAttribute.OnAuthorization(AuthorizationContext filterContext) +379
System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor) +143
System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__19(AsyncCallback asyncCallback, Object asyncState) +1680
System.Web.Mvc.Async.WrappedAsyncResult`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +59
System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +94
System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +559
System.Web.Mvc.Controller.<BeginExecuteCore>b__1c(AsyncCallback asyncCallback, Object asyncState, ExecuteCoreState innerState) +82
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73
System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +105
System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +588
System.Web.Mvc.Controller.<BeginExecute>b__14(AsyncCallback asyncCallback, Object callbackState, Controller controller) +47
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +65
System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +139
System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +484
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +50
System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__4(AsyncCallback asyncCallback, Object asyncState, ProcessRequestState innerState) +98
System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73
System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +106
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +446
System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +88
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +50
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
【问题讨论】:
【参考方案1】:出现此错误的原因是您的应用程序尝试首先使用旧版本的 Identity 进行连接。您不应使用对象的“旧”版本来管理角色。使用新的 UserManager
和 RoleManager
类。
例如:
var store = new UserStore<ApplicationUser>(context);
var userManager = new ApplicationUserManager(store);
if(userManager.IsInRole(userId, "NameOfRole")
//do stuff
要在您的视图中使用它,您可以创建自己的助手:
namespace MyProject.MyNamespace.MyExtensions
public static class IdentityExtensions
public static bool IsInIdentityRole(this IPrincipal user, string role)
var userManager = GetUserManager(); //implement this!
return userManager.IsInRole(user.Identity.GetUserId(), role);
确保您的视图知道此命名空间,将此行添加到您的 Views 文件夹中的 web.config
文件中(不是主要的 web.config
!):
<add namespace="MyProject.MyNamespace.MyExtensions"/>
并像这样在您的视图中使用:
@if (User.IsInIdentityRole("admin"))
<li>@Html.ActionLink("Admins", "Index", "Admins")</li>
【讨论】:
我在其中使用它的视图是 _Layout.cshtml 我应该将辅助方法放在哪里才能在该视图中访问它们?GetUserManager()
除了return new ApplicationUserManager(store)
还应该做什么?
更新了答案以包含它。
我实现的 GetManager() 方法与您的第一个示例一样,并且您所说的其他方法都有效。
-1 很抱歉,您不需要在创建UserManager
对象的地方创建带有静态扩展的hack。 IPrinciple
实现了 IsInRole()
方法,并且与 Identity 配合得非常好。在 Razor 视图中,您会得到 IPrincipal
类型的 User
,如果您调用 @User.IsInRole("admin")
- 它会告诉您用户是否处于管理员角色。无需去数据库。
@Niclassg 在您的web.config
中,在<system.web>
中确保此行存在:<roleManager enabled="false" />
【参考方案2】:
而不是调用
@if (Roles.IsUserInRole(User.Identity.Name,"admin"))
对旧 MembershipProvider 的调用使用此调用:
@if (User.IsInRole("admin"))
这使用了新身份框架的功能。无需实现任何东西。这也不会调用数据库来检查角色 - 它使用存储用户角色的 cookie 信息。
更新
如果您收到关于 System.Web.Security.RolePrincipal
的异常,这意味着您的会员服务提供商并未完全关闭,您看到它正在与最后的机会作斗争。
确保在您的web.config
中有:
<system.WebServer>
<modules>
<remove name="FormsAuthentication" />
在
<appSettings>
<add key="enableSimpleMembership" value="false" />
确保您的 cookie 已被删除,并且您可以再次登录。之后,当您在调试器的 Razor 视图中检查 @User
时,您应该看到 ClaimsPrincipal
对象,而不是 RolePrincipal
。当用户登录时,ClaimsPrincipal
应该在整个系统中使用——这就是 Identity 使用的。如果您没有收到IdentityPrincipal
,则表示您的登录过程无法正常工作。
【讨论】:
当我尝试使用@if (User.IsInRole("admin"))
时出现System.Data.SqlClient.SqlException' occurred in System.Web.dll but was not handled in user code
错误,详细信息为:Invalid object name 'dbo.aspnet_SchemaVersions'.
用户类型为:User = System.Web.Security.RolePrincipal
我确保我在 web.config 文件中有这些设置,并删除了所有 cookie,但它没有帮助。
您的登录代码是什么样的?这个错误是 MembershipProvider 遗留下来的,所以它在某个地方仍然存在,会打乱你的进程。
我通过将 <roleManager enabled="false"
添加到 web.config 来修复它
您的web.config
中似乎还有关于 MembershipProvider 的部分。您需要杀死所有启用 <MembershipProvider>
和 <ProfileProvider>
等的东西。以上是关于ASP.NET Identity 2.0 Roles.IsUserInRole 给出 "Invalid object name 'dbo.aspnet_SchemaVersions'.&qu的主要内容,如果未能解决你的问题,请参考以下文章
在 ASP.NET Identity 2.0 中获取当前用户 ID
如何在现有数据库中实现 ASP.NET Identity 2.0?
ASP.NET Identity 2.0 解密 Owin cookie