Подтвердить что ты не робот

MVC5: UserManager.AddToRole(): "Ошибка добавления пользователя в роль: UserId not found"?

Я экспериментировал с MVC5/EF6 и тестировал новую идентификационную аутентификацию с первыми переходами кода. Все в решении в настоящее время строится, и я могу добавить Migration, но когда я выполняю update-database через package manager console в VS2013, мой файл Configuration.cs не может полностью обработать мои тестовые данные в мои таблицы и выходы Error Adding User to Role: UserId not found.

Я попытался явно установить идентификатор пользователя и оставить его сгенерированным Менеджером (как видно из некоторых примеров), но каждый раз, когда я получаю то же сообщение об ошибке. Я знаю, что ошибка не работает в моем #region User & User Roles файла Configuration.cs, но я не уверен, почему:

using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using PersonalPortfolio2.Helper;
using PersonalPortfolio2.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Diagnostics;
using System.Linq;

namespace PersonalPortfolio2.Models
{
    public sealed class Configuration : DbMigrationsConfiguration<PersonalPortfolio2.Models.ApplicationDbContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;
        }

        protected override void Seed(PersonalPortfolio2.Models.ApplicationDbContext context)
        {
            BlobHelper bh = new BlobHelper();
            //LocationHelper lh = new LocationHelper();
            ApplicationDbContext db = new ApplicationDbContext();

            #region Roles
            try
            {
                List<string> myRoles = new List<string>(new string[] { "Root", "Admin", "Outsider", "Client", "Primary" });
                var RoleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));

                foreach (string r in myRoles)
                {
                    RoleManager.Create(new IdentityRole(r));
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Error Create Roles: " + ex.Message);
            }
            #endregion

            #region User & User Roles
            var store = new UserStore<ApplicationUser>(context);
            var manager = new UserManager<ApplicationUser>(store);

            List<ApplicationUser> myUsers = GetTestUsers();
            var passwordHasher = new PasswordHasher();

            foreach (var u in myUsers)
            {
                var userExists = db.Users.Where(a => a.Email == u.Email).FirstOrDefault();
                if (userExists == null)
                {
                    var user = new ApplicationUser
                    {
                        Email = u.Email,
                        PasswordHash = passwordHasher.HashPassword("[email protected]"),
                        LockoutEnabled = false,
                        Name = u.Name,
                        Position = u.Position,
                        RegisteredDate = DateTime.Now,
                        LastVisitDate = DateTime.Now,
                        OrganizationId = u.OrganizationId,
                        ProfilePictureSrc = u.ProfilePictureSrc,
                    };

                    try
                    {
                        var userCreateResult = manager.Create(user);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Error Add User: " + ex.Message + "\n" + ex.InnerException);
                    }

                    // Add User to Roles
                    List<string> usersRoles = GetUserRoles(u.Email);
                    bool codeHit = false;
                    foreach (string role in usersRoles)
                    {
                        try
                        {
                            codeHit = true;
                            manager.AddToRole(user.Id, role);
                        }
                        catch (Exception ex)
                        {
                            // ERROR!
                            throw new Exception("Error Adding User to Role: " + ex.Message + "\n" + ex.Data + "\n" + ex.InnerException + "\nName: " + user.Name + "\nEmail: " + user.Email + "\nuser.ID: " + user.Id + "\nu.Id: " + u.Id + "\nRole: " + role + "\nCodeHit: " + codeHit);
                        }
                    }
                }

            }
            #endregion

}

            #region Helpers
            private List<ApplicationUser> GetTestUsers()
            {
                List<ApplicationUser> testUsers = new List<ApplicationUser>
                {
                    new ApplicationUser
                    {
                        Id = "1",
                        Email = "[email protected]",
                        Name = "Admin User",
                        RegisteredDate = System.DateTime.Now,
                        LastVisitDate = System.DateTime.Now,
                        Position = "Site Administrator",
                        PhoneNumber = "1234564321",
                    },
                    new ApplicationUser
                    {
                        Id = "2",
                        Email = "[email protected]",
                        Name = "James Woods",
                        RegisteredDate = System.DateTime.Now,
                        LastVisitDate = System.DateTime.Now,
                        Position = "Software Developer / Web Designer",
                        PhoneNumber = "1234567890",
                    },
                    new ApplicationUser
                    {
                        Id = "3",
                        Email = "[email protected]",
                        Name = "Tyler Perry",
                        RegisteredDate = System.DateTime.Now,
                        LastVisitDate = System.DateTime.Now,
                        Position = "Company Contact",
                        PhoneNumber = "1234567890",
                    }
                };
                return testUsers;
            }


            public List<string> GetUserRoles(string user)
            {
                List<string> myRoles = new List<string>();
                switch (user)
                {
                        //"Root", "Admin", "Outsider", "Client", "Primary"
                    case "[email protected]":
                        myRoles = new List<string>(new string[] { "Root", "Admin" });
                        break;
                    case "[email protected]":
                        myRoles = new List<string>(new string[] { "Admin" });
                        break;
                    case "[email protected]":
                        myRoles = new List<string>(new string[] { "Client", "Outsider" });
                        break;
                    default:
                        myRoles = new List<string>(new string[] {"[user] not found."});
                        break;
                }
                return myRoles;
            }
            #endregion

    }
}

Может ли кто-нибудь дать представление о том, что я могу игнорировать? Для получения полной информации мой текущий catch статус выводит следующее:

Error Adding User to Role: UserId not found.
System.Collections.ListDictionaryInternal

Name: Admin User
Email: [email protected]
user.ID: 1
u.Id: 1
Role: Root
CodeHit: True

Когда я комментирую явный Id = "1", для моего пользователя Admin, user.ID и u.Id становится: ab753316-3d7b-4f98-a13a-d19f7c926976. Я думал, что это могут быть мои вспомогательные методы GetTestUsers() или GetUserRoles(u.Email), которые были проблемой, но между моей try/catch и codeHit логической переменной, которую я использую, я подтвердил, что проблема определенно происходит от manager.AddToRole(user.Id, role).

4b9b3361

Ответ 1

Я оставляю это здесь для всех, у кого могла быть аналогичная проблема. У меня были те же "симптомы". Оказывается, проблема, связанная с сохранением пароля, не придерживается политики настроенных паролей (по крайней мере, один заглавный char, один строчный char и т.д. И т.д.).

В соответствии с нижеприведенными комментариями и ответами, в общем случае, возникает такое же неопределенное сообщение об ошибке, когда не соблюдаются никакие ограничения или политики создания пользователя.

Это может включать следующее:

  • Политика паролей не соблюдается (это, по-видимому, самая распространенная причина)
  • Обязательные поля передаются как пустые строки /null
  • Дублировать имя пользователя или адрес электронной почты

Существует очень широкий спектр проблем, которые могут вызвать эту ошибку. Если вышеуказанное не решит вашу проблему, я предлагаю следующее:

  • Ознакомьтесь с правилами и политиками для identityprovider, которые были настроены для вашего решения.
  • В соответствии с ответом @Ted ниже, трассируйте или установите точку останова в методе UserManager.Create для просмотра результата, так как это, вероятно, покажет причину вашей проблемы.

Ответ 2

Ответ CraftBeerHipsterDude помог мне найти ответ на ту же ситуацию, что и я. Если AddToRole не работает, фокус в том, чтобы посмотреть результат, полученный от Usermanager.Create(...). Это может не вызвать исключение, но все же вернуть результаты, которые говорят, что создание не удалось. В моем случае это было "Имя пользователя уже существует".

Обобщение: проверьте результаты предыдущих операций для отслеживания реальной ошибки.

Ответ 3

Отвечайте на создателя вопроса: UserId не следует вводить, оставьте это для структуры сущности, чтобы создать его для пользователей. Вы также пытаетесь ввести его как целое число, но Id для пользователей в ролевой безопасности является GUID в форме строки, поэтому он не будет работать, чтобы попытаться добавить целочисленное значение для столбца, ожидающего строку.

Теперь это не было проблемой для меня, но у меня было еще несколько проблем с той же ошибкой:

Я попытался выяснить, чего я пропустил, но не нашел ничего плохого.

Итак, я использовал другой экземпляр VS в качестве отладчика семенного кода (нашел это в другом потоке):

    if (System.Diagnostics.Debugger.IsAttached == false)
    System.Diagnostics.Debugger.Launch();

Я заметил, что у пользователя действительно был идентификатор, когда он добавлялся к роли. В конце концов я смог сделать обходной путь, добавив пустой блок catch. Код не генерирует исключений из-за ложной ошибки, а пользователи добавляются в правильные роли:

    try
    {
        var newUser = userManager.FindByEmail(superuserToInsert.Email);
        userManager.AddToRole(newUser.Id, "Super users");
    }
    catch 
    {
    }

Прежде чем я попытался добавить вновь созданного пользователя к роли, семя, похоже, отбросило создание пользователя, и пользователь никогда не создавался в пользовательской базе данных.

Но когда я полностью удалял добавление в часть роли, пользователь был добавлен в базу данных, а во втором запуске немного отредактированного кода конфигурации пользователь мог быть добавлен к роли, что привело меня к мысли, что это было aa ложная ошибка, возникающая. игнорирование этой ложной ошибки с пустым блоком catch также игнорирует откат создания пользователя (что должно произойти за шторами непосредственно перед добавлением в роль), что приводит к пользователю, существующему при добавлении роли часть кода.

Надеюсь, что это поможет кому-то

EDIT:

Вышеупомянутая фиксированная почти вся голова болит, но я заметил, что еще было 300 учетных записей, которые не могли быть созданы (но ошибок не было). Простая ПОЛНАЯ ВЗАИМОДЕЙСТВУЮЩАЯ РАБОТА и рассмотрение пользовательской базы данных с помощью таблицы исходных баз данных заставляют меня думать, что пользователи с тире (-) в обоих значениях столбцов "Имя пользователя" и "Электронная почта" остановили создание пользователей, и это был случай.

Это было простое исправление, просто настройте пользовательский менеджер на использование более буквенно-цифровых символов: (и хотя имя атрибута, по-видимому, указывает только на "Имена пользователей", это также повлияло на "Email" ).

    var userManager = new UserManager<ApplicationUser>(userStore);

    userManager.UserValidator = new UserValidator<ApplicationUser(userManager)
    {
        AllowOnlyAlphanumericUserNames = false,
    }; 

//Miske

Ответ 4

Я бы не использовал UserManager и RoleManager в методе Seed. Вместо этого я бы использовал только контекст. Что-то, что я использую, это следующее, которое создает пользователя и назначает его роли:

protected override void Seed(DbModelContext context)
{
    if (context == null)
    {
        throw new ArgumentNullException("context", "Context must not be null.");
    }

    const string UserName = "User";
    const string RoleName = "UserRole";

    var userRole = new IdentityRole { Name = RoleName, Id = Guid.NewGuid().ToString() };
    context.Roles.Add(userRole);

    var hasher = new PasswordHasher();

    var user = new IdentityUser
                   {
                       UserName = UserName,
                       PasswordHash = hasher.HashPassword(UserName),
                       Email = "[email protected]",
                       EmailConfirmed = true,
                       SecurityStamp = Guid.NewGuid().ToString()
                   };

    user.Roles.Add(new IdentityUserRole { RoleId = userRole.Id, UserId = user.Id });

    context.Users.Add(user);

    base.Seed(context);
}

Классы Entity являются пользовательскими реализациями (потому что я хотел использовать GUID в качестве идентификаторов), но они происходят из классов фреймворка. При этом он должен работать таким же образом, если вы измените их на соответствующие классы классов.

ИЗМЕНИТЬ

Я удалил пользовательские классы и переключил их на классы фреймворка, потому что возникла некоторая путаница.

Ответ 5

Это спасло мой второй день. Спасибо @Daffy Punk. В моем случае проблема заключалась в пароле. который был "ABC" раньше.

var studentPassword = "abcABC_9";
                        var user = new ApplicationUser { UserName = "abc", Email = [email protected] };
                        var UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
                        var result = await UserManager.CreateAsync(user, studentPassword.ToString());
                        await UserManager.AddToRoleAsync(user.Id, "Student");

Ответ 6

проблема в моем случае заключается в том, что я использую (имя пользователя) пользователя вместо Id, рабочий код ниже:

 public async Task<ActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser { UserName = model.Username, Email = model.Username, workshopId =model.workshopId};
                var rolesList = _context.Roles.ToList();
                string role = rolesList.FirstOrDefault(r => r.Id == model.SelectedRoleId).Name;
                var result = await UserManager.CreateAsync(user, model.Password);

                // Add User to the selected role from the list in .cshtml
                if (result.Succeeded)
                {
                    await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
                    result =await UserManager.AddToRoleAsync(user.Id, role);
                    // For more information on how to enable account confirmation and password reset please visit https://go.microsoft.com/fwlink/?LinkID=320771
                    // Send an email with this link
                    // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
                    // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
                    // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");

                    return RedirectToAction("Index", "Home");
                }
                AddErrors(result);
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }