ASP.NET Identity 2.0 Roles.IsUserInRole给出{“无效的对象名称'dbo.aspnet_SchemaVersions'。”}异常

时间:2014-10-29 09:19:44

标签: c# asp.net sql-server asp.net-identity

我使用ASP.NET Identity 2.0,我想知道登录的用户是否具有角色" admin"。在我的种子方法中,我创建了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表,我不想要它。 以下是与我拥有的身份相关的表格的图片: Identity Tables

db托管在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

2 个答案:

答案 0 :(得分:2)

此错误的原因是您的应用程序尝试首先使用旧版本的Identity进行连接。你不应该使用&#39;遗产&#39;用于管理角色的对象的版本。使用新的UserManagerRoleManager类。

例如:

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>
}

答案 1 :(得分:0)

而不是打电话

@if (Roles.IsUserInRole(User.Identity.Name,"admin"))

调用旧的MembershipProvider使用此调用:

@if (User.IsInRole("admin"))

这使用了新Identity框架的功能。无需实施任何东西。此外,这不会调用数据库来检查角色 - 它使用存储用户角色的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,则表示您的登录过程无法正常运行。