Custom Membership with Microsoft.AspNet.Identity - CreateLocalUser fails

北城余情 提交于 2019-12-02 15:37:41

The issue here is that IdentityStoreManager has strong dependency on the default implementation of identity EF models. For example, the CreateLocalUser method will create UserSecret and UserLogin objects and save them to stores, which won't work if the store is not using the default model type. So if you customize the model type, it won't work smoothly with IdentityStoreManager.

Since you only customize the IUser model, I simplified the code to inherit custom user from default identity user and reuse other models from identity EF models.

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 WebApplication11.Models
{
    public class PulseUser : User
    {
        public PulseUser() { }
        public PulseUser(string userName) : base(userName)
        {
        }

        [StringLength(100)]
        public string Email { get; set; }
        [Column(TypeName = "Date")]
        public DateTime? BirthDate { get; set; }
        [StringLength(1)]
        public string Gender { get; set; }
    }

    public class PulseUserContext : IdentityStoreContext
    {
        public PulseUserContext(DbContext db) : base(db)
        {
            this.Users = new UserStore<PulseUser>(this.DbContext);
        }
    }

    public class PulseDbContext : IdentityDbContext<PulseUser, UserClaim, UserSecret, UserLogin, Role, UserRole>
    {
    }
}

The code above should work with preview version of Identity API.

The IdentityStoreManager API in upcoming release is already aware of this issue and changed all the non-EF dependency code into a base class so that you can customize it by inheriting from it. It should solve all the problems here. Thanks.

PulseUser.Id is defined as a string but doesn't appear to be set to a value. Were you meant to be using a GUID for the Id? If so, initialise it in the constructor.

    public PulseUser() : this(String.Empty) { }
    public PulseUser(string userName) 
    {
        UserName = userName;
        Id = Guid.NewGuid().ToString();
    }

You will also want to perform a check that the user name doesn't already exist. Look at overriding DbEntityValidationResult in PulseDbContext. Do a new MVC project in VS2013 to see an example.

Since there are alot of changes on this when going to RTM, i have updated the SPA template that uses a WebApi controller for all the identity signin and such. Its a really cool template , if you havent seen it.

I put all my code here: https://github.com/s093294/aspnet-identity-rtm/tree/master

(Do note, its only for inspiration. I only made it work and nothing more. Properly have a bug or two also).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!