0

Я использую веб-проект с asp.net Identity 2.0 на Visual Studio 2013. Я выполнил инструкции по этому page, чтобы создать настраиваемое новое поле, которое Я назвал screenName. Кажется, все работает хорошо.Как сделать индивидуальную информацию профиля UNIQUE в ASP.NET Identity

Однако я хочу сделать еще один шаг и иметь уникальное имя экрана в базе данных. Это означает, что ApplicationUserManager должен проверить, было ли имя экрана взято перед регистрацией пользователя. Как я могу потребовать уникальное имя экрана и выполнить это?

Вот мои коды:

AccountControler.cs (добавлено ScreenName = model.screenName)

public async Task<ActionResult> Register(RegisterViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      var user = new ApplicationUser { UserName = model.Email, Email = model.Email, screenName = model.screenName }; 

      var result = await UserManager.CreateAsync(user, model.Password); 
      if (result.Succeeded) 
      { 
       var 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, "bla bla bla", "Thank you for your bla bla bla registration. Please confirm your account by clicking this link: <a href=\"" + callbackUrl + "\">link</a>"); 
       ViewBag.Link = callbackUrl; 
       return View("DisplayEmail"); 
      } 
      AddErrors(result); 
     } 

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

AccountViewModel.cs

public class RegisterViewModel 
{ 
[Required] 
[StringLength(20, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 
    [Display(Name = "screenName")] 
    public string screenName { get; set; } 
} 

IdentityModel.cs (добавлена ​​публичная строка ScreenName { get; set;})

public class ApplicationUser : IdentityUser 
{ 
    public string screenName { get; set; } 
    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; 
    } 
} 

Register.cshtml

<div class="form-group"> 
@Html.LabelFor(m => m.screenName, new { @class = "col-md-2 control-label" }) 
<div class="col-md-10"> @Html.TextBoxFor(m => m.screenName, new { @class = "form-control" }) 
</div> 
</div> 

SQL SERVER

GO 
CREATE UNIQUE NONCLUSTERED INDEX [screenNameIndex] 
ON [dbo].[AspNetUsers]([screenName] ASC); 

ApplicationUserManager является, например, требует уникального Email с помощью следующего кода на identityConfig.cs. Как я могу сделать то же самое для пользовательского имени экрана?

var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>())); 
// Configure validation logic for usernames 
manager.UserValidator = new UserValidator<ApplicationUser>(manager) 
     { 
      AllowOnlyAlphanumericUserNames = false, 
      RequireUniqueEmail = true 
     }; 

ответ

0

Вам необходимо вручную проверить, есть ли запись с этим именем экрана существует в БД:

Что-то вроде этого:

public async Task<ActionResult> Register(RegisterViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     // somehow obtain your DbContext object 
     var existsDuplicate = dbContext.Users.Any(u => u.screenName == model.screenName); 
     if(existsDuplicate) 
     { 
      ModelState.AddModelError("screenName", "Screen Name is already taken, please choose another one"); 
      return View(model); 
     } 


     // the rest of controller is unchanged 
     var user = new ApplicationUser { UserName = model.Email, Email = model.Email, screenName = model.screenName }; 

     var result = await UserManager.CreateAsync(user, model.Password); 
     if (result.Succeeded) 
     { 
      var 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, "bla bla bla", "Thank you for your bla bla bla registration. Please confirm your account by clicking this link: <a href=\"" + callbackUrl + "\">link</a>"); 
      ViewBag.Link = callbackUrl; 
      return View("DisplayEmail"); 
     } 
     AddErrors(result); 
    } 

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

спасибо за ответ. Я пытаюсь реализовать свой код, но по какой-то причине dbContext не может быть найден, хотя у меня установлен EntityFramework 6.1.1. Я использую MVC5. Мне не хватает пространства имен? – Gloria

+0

OK Я решил проблему, добавив System.Data.Entity. Но теперь я получаю еще одно сообщение об ошибке; «System.Data.Entity.DbContext» не содержит определения для «Пользователи» ... – Gloria

+0

Вам нужно использовать собственный контекст базы данных, который наследуется от 'IdentityDbContext'. Код выше - образец, не воспринимайте его буквально. – trailmax