D'Appartenance personnalisé avec Microsoft.AspNet.L'identité CreateLocalUser échoue
J'ai essayé de mettre en œuvre une version personnalisée de la nouvelle Identité fonctionnalités ASP.NET 4.5 (Microsoft.AspNet.D'identité), à l'aide de Visual Studio 2013. Après de nombreuses heures à jouer avec, j'ai simplifié mon code dans un effort pour essayer de le faire fonctionner sans erreurs. J'ai énuméré mon code ci-dessous. Lorsque vous effectuez un Enregistrement Local, les tables de base de données sont créés, mais le CreateLocalUser méthode échoue. J'espère que quelqu'un peut m'aider à identifier les changements nécessaires.
Modèles/MembershipModel.cs
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace thePulse.web.Models
{
public class PulseUser : IUser
{
public PulseUser() { }
public PulseUser(string userName)
{
UserName = userName;
}
[Key]
public string Id { get; set; }
[Required]
[StringLength(20)]
public string UserName { get; set; }
[StringLength(100)]
public string Email { get; set; }
[Column(TypeName = "Date")]
public DateTime? BirthDate { get; set; }
[StringLength(1)]
public string Gender { get; set; }
}
public class PulseUserClaim : IUserClaim
{
public PulseUserClaim() { }
[Key]
public string Key { get; set; }
public string UserId { get; set; }
public string ClaimType { get; set; }
public string ClaimValue { get; set; }
}
public class PulseUserSecret : IUserSecret
{
public PulseUserSecret() { }
public PulseUserSecret(string userName, string secret)
{
UserName = userName;
Secret = secret;
}
[Key]
public string UserName { get; set; }
public string Secret { get; set; }
}
public class PulseUserLogin : IUserLogin
{
public PulseUserLogin() { }
public PulseUserLogin(string userId, string loginProvider, string providerKey)
{
LoginProvider = LoginProvider;
ProviderKey = providerKey;
UserId = userId;
}
[Key, Column(Order = 0)]
public string LoginProvider { get; set; }
[Key, Column(Order = 1)]
public string ProviderKey { get; set; }
public string UserId { get; set; }
}
public class PulseRole : IRole
{
public PulseRole() { }
public PulseRole(string roleId)
{
Id = roleId;
}
[Key]
public string Id { get; set; }
}
public class PulseUserRole : IUserRole
{
public PulseUserRole() { }
[Key, Column(Order = 0)]
public string RoleId { get; set; }
[Key, Column(Order = 1)]
public string UserId { get; set; }
}
public class PulseUserContext : IdentityStoreContext
{
public PulseUserContext(DbContext db) : base(db)
{
Users = new UserStore<PulseUser>(db);
Logins = new UserLoginStore<PulseUserLogin>(db);
Roles = new RoleStore<PulseRole, PulseUserRole>(db);
Secrets = new UserSecretStore<PulseUserSecret>(db);
UserClaims = new UserClaimStore<PulseUserClaim>(db);
}
}
public class PulseDbContext : IdentityDbContext<PulseUser, PulseUserClaim, PulseUserSecret, PulseUserLogin, PulseRole, PulseUserRole>
{
}
}
Changements aux Contrôleurs/AccountController.cs
public AccountController()
{
IdentityStore = new IdentityStoreManager(new PulseUserContext(new PulseDbContext()));
AuthenticationManager = new IdentityAuthenticationManager(IdentityStore);
}
//
//POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
try
{
//Create a profile, password, and link the local login before signing in the user
PulseUser user = new PulseUser(model.UserName);
if (await IdentityStore.CreateLocalUser(user, model.Password))
{
await AuthenticationManager.SignIn(HttpContext, user.Id, isPersistent: false);
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", "Failed to register user name: " + model.UserName);
}
}
catch (IdentityException e)
{
ModelState.AddModelError("", e.Message);
}
}
//If we got this far, something failed, redisplay form
return View(model);
}
Comme je l'ai dit ci-dessus, cette mise en oeuvre échoue lorsque le CreateLocalUser méthode échoue (Microsoft.AspNet.L'identité.EntityFramework). Je ne peux pas comprendre pourquoi.
- Voici un exemple de l'Identité de l'application qui est en train de faire quelque chose de semblable à ce que je fais (pour référence). github.com/rustd/AspnetIdentitySample/tree/master/...
- Et voici un post de la MSDN Blogs décrivant le nouveau système d'Identité pour ASP.NET. blogs.msdn.com/b/webdev/archive/2013/06/27/...
- quelle est l'erreur ?
- J'ai aussi n'ont pas été en mesure de le mettre en œuvre. Ive pas trouvé d'exemples qui fonctionnent avec un Utilisateur personnalisée tableau contenant le mot de passe, mais aussi de permettre l'authentification oAuth capacité de lier google, etc. comptes pour le même enregistrement dans la base de données.
- Phil, la ligne suivante (dans le AccountController) est de retour un faux, et pas de l'enregistrement de l'Utilisateur est créé dans la base de données. si (attendre IdentityStore.CreateLocalUser(utilisateur, modèle.Le mot de passe))
- Voici une autre page de l'examen de la nouvelle OWIN Formes Autentication: blogs.msdn.com/b/webdev/archive/2013/07/03/...
- Vous pouvez également ajouter le code pour le DbContext, il pourrait y avoir des questions.
- Hao Kung, le dbContext code est inclus au bas de la MembershipModels.cs fichier. Ai-je raté quelque chose?
- Quelle version est-ce lié. Vais-je faire face à la samme questions si j'essaie ci-dessus sur la release candidate?
Vous devez vous connecter pour publier un commentaire.
Le problème ici est que IdentityStoreManager a forte dépendance à l'égard du défaut de mise en œuvre de l'identité EF modèles. Par exemple, le CreateLocalUser méthode permet de créer UserSecret et UserLogin objets et de les enregistrer dans les magasins, ce qui ne marchera pas si le magasin n'est pas à l'aide de la valeur par défaut type de modèle. Donc, si vous personnalisez le type de modèle, il ne fonctionnera pas correctement avec IdentityStoreManager.
Puisque vous n'personnaliser la IUser modèle, j'ai simplifié le code pour hériter de l'utilisateur personnalisés à partir d'identité par défaut de l'utilisateur et de les réutiliser à d'autres modèles de l'identité EF modèles.
Le code ci-dessus devrait fonctionner avec la version preview de l'Identité de l'API.
La IdentityStoreManager l'API dans la prochaine version est déjà au courant de ce problème et changé tous les non-EF code de dépendance dans une classe de base, de sorte que vous pouvez le personnaliser en héritant de il. Il faut résoudre tous les problèmes ici. Merci.
PulseUser.Id est défini comme une chaîne de caractères, mais ne semble pas être réglé sur une valeur. Avez-vous été destiné à être l'aide d'un GUID pour la carte d'identité? Si oui, l'initialiser dans le constructeur.
Vous voudrez aussi de vérifier que le nom d'utilisateur n'existe pas déjà. Regardez primordial DbEntityValidationResult dans PulseDbContext. Faire un nouveau projet MVC dans VS2013 pour voir un exemple.
Car il y a beaucoup de changements sur cette lorsque vous allez à la RTM, j'ai mis à jour le SPA modèle qui utilise un WebApi contrôleur pour tout l'identité signin et ces. Ses vraiment un super modèle , si vous havent vu.
J'ai mis tout mon code ici:
https://github.com/s093294/aspnet-identity-rtm/tree/master
(Note, c'est uniquement pour de l'inspiration. J'ai seulement fait le travail et rien de plus. Correctement un bug ou deux aussi).