MVC-InvalidOperationException:找不到用户ID [英] MVC - InvalidOperationException: UserId not found

查看:115
本文介绍了MVC-InvalidOperationException:找不到用户ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我使用以下代码注册用户时:

When I register a user using the following code:

// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = new ApplicationUser() { UserName = model.UserName };

        IdentityResult result = await UserManager.CreateAsync(user, model.Password);

        if (result.Succeeded)
        {
            await SignInAsync(user, isPersistent: false);
            return RedirectToAction("Index", "Home");
        }
        else
        {
            AddErrors(result);
        }

        return View(model);
    }
}

我可以使用[Authorize]属性访问所有视图. 但是,如果我注销并使用同一用户重新登录,则会显示错误页面

I am able to access all of the views with the [Authorize] attribute. However, if I log out and back in with the same user I get an error page with

"InvalidOperationException:找不到用户ID"

"InvalidOperationException: UserId not found"

该错误似乎是由于我的SignInAsync函数在以下语句引起的:

The error seems to be coming from my SignInAsync function at the statement:

var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);

我没有添加UserID,并且用户类(其ID)或AspNetUsers表中没有UserId字段. 该表中存在该用户,但是同样,没有UserId.

I am not adding a UserID and there is no UserId field in the user classs (its Id) or in the AspNetUsers table. The user exists in that table, but again, there is no UserId.

我曾尝试清除Cookie等,但仍然无法重新登录. 我做错了登记吗?我不明白为什么身份验证似乎不存在时为什么要查找UserId字段

I have tried clearing the cookies etc, but still no luck in re-logging in. Am I doing the register wrong? I don't understand why the authentication is looking for the UserId field when it doesn't seem to exist

当我第一次登录...我得到错误页面.但是,当我重新打开页面并读取Cookie时,我可以访问所有内容.初始登录到底是怎么回事?

When I login the first time...i get the error page. However, when I reopen the page and it reads the cookie, I have access to everything. What the heck is going on with the initial login?

这是SignInAsync方法:

here is the SignInAsync method:

 private async Task SignInAsync(ApplicationUser user, bool isPersistent)
        {
            AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
            var _identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);

            AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, _identity);
        }

包含:

 public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }
    }

推荐答案

对于您提到Dapper的情况,我是错的,因此Dapper特定的细节无关紧要,但修复的总体思路仍然存在-您的ID和UserId列可能无法正确匹配.

I am wrong about you having mentioned Dapper, so the Dapper-specific details are not relevant, but the general idea of the fix remains - your Id and UserId columns are likely not getting matched up correctly.

昨天我遇到了这个确切的错误.我想您之前已经提到过,您正在使用Dapper作为数据访问机制.我认为这可能是相关的,因为您还提到了表具有Userid字段,但是用户类具有Id属性.我猜您可能还有些代码,如果那里没有一个,将一个新的Guid分配给Id属性.像这样:

I ran into this exact error yesterday. I think you previously had mentioned that you're using Dapper as the data access mechanism. I think that was perhaps relevant because you've also mentioned that the table has a Userid field, but your user class has an Id property. I am guessing you may also have some code to assign a new Guid to the Id property if there's not one there. Something like this:

public ApplicationUser()
{
    Id = Guid.NewGuid().ToString();
}

这与Dapper映射的工作方式结合在一起可能会使您感到困惑,因为Id字段将使用新的Guid而不是应该从表中读取的字段.

This combined with how Dapper mapping works may be messing you up since the Id field will wind up with that new Guid instead of the one it is supposed to be reading from the table.

在下面的示例中,Dapper无法分配ApplicationUser的Id字段,因为DB字段的命名与类的属性不同.但是它的构造函数中已经有一个Id值.这会导致以后对FindByIdAsync()和朋友的呼叫失败.

In the below sample, Dapper is unable to assign the Id field of the ApplicationUser because the DB field is named differently than the property of the class. But it will already have an Id value from its constructor. This causes later calls to FindByIdAsync() and friends to fail.

public async Task<ApplicationUser> FindByNameAsync(string userName)
{
    ApplicationUser result = null;

    using (var conn = await GetOpenDBConnection())
    {
        try
        {
            // this query is bugged with Dapper because UserId does not
            // exist on ApplicationUser.
            var queryResults = await conn.QueryAsync<ApplicationUser>(
                "SELECT UserId, UserName, Email FROM dbo.Users WHERE UserName = @UserName;",
                new { UserName = userName });

            result = queryResults.FirstOrDefault();
        }
        catch (Exception ex)
        {
                            //handle error appropriately.
            result = null;
        }
    }

    return result;
}

如果实际上是Dapper映射问题,则可以在查询结果中重命名字段,例如SELECT UserId as [Id], UserName, Email FROM dbo.Users WHERE UserName = @UserName,或参见

If it is in fact a Dapper mapping issue, you can either rename the field in the query results such as SELECT UserId as [Id], UserName, Email FROM dbo.Users WHERE UserName = @UserName, or see Randall Stutton's answer for how to map Dapper fields in a really clean way.

这篇关于MVC-InvalidOperationException:找不到用户ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆