C# ASP.NET MVC4实体验证错误:已使用用户名
我是ASP.NET MVC4新手,下面的代码出现验证错误 我的应用程序正在使用身份和数据库 我用一些测试数据填充了一些表。调用C# ASP.NET MVC4实体验证错误:已使用用户名,c#,asp.net,asp.net-mvc,asp.net-mvc-4,asp.net-identity,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 4,Asp.net Identity,我是ASP.NET MVC4新手,下面的代码出现验证错误 我的应用程序正在使用身份和数据库 我用一些测试数据填充了一些表。调用dc.SaveChanges()将返回验证错误 我创建了以下类:Facultyderiving from classPersonderiving from classIdentityUser 我创建了一个名为Faculty的角色,然后创建了一个名为mark的Faculty对象,并将其添加到Faculty角色中。当mark登录并且数据库开始初始化时,我得到错误“用户名Pet
dc.SaveChanges()
将返回验证错误
我创建了以下类:Faculty
deriving from classPerson
deriving from classIdentityUser
我创建了一个名为Faculty
的角色,然后创建了一个名为mark
的Faculty
对象,并将其添加到Faculty
角色中。当mark
登录并且数据库开始初始化时,我得到错误“用户名Peter已经被占用了。”
如能作出解释,将不胜感激
代码
类人
:
public class Faculty : Person {
public Faculty() {
this.Courses = new List<Course>();
SenecaId = string.Empty;
}
public Faculty(string fname, string lname, string phone, string senId)
: base(fname, lname, phone) {
this.Courses = new List<Course>();
this.Messages = new List<Message>();
SenecaId = senId;
}
[Required]
[RegularExpression("^[0][0-9]{8}$", ErrorMessage = "0 followed by 8 digits")]
public string SenecaId { get; set; }
public List<Course> Courses { get; set; }
public List<Message> Messages { get; set; }
}
角色教员
:
string roleFaculty = "Faculty";
if (!RoleManager.RoleExists(roleFaculty)) {
var roleFacultyCreateResult = RoleManager.Create(new IdentityRole(roleFaculty));
}
// 1 create faculty Mark (8)
Faculty mark = new Faculty();
// add "mark" to role "faculty"
mark.SenecaId = "034234678";
mark.FirstName = "Mark";
mark.LastName = "McTest";
mark.Phone = "555-567-6789";
mark.UserName = "Mark";
string UserMarkPw = "123456";
var UserMarkCreate = UserManager.Create(mark, UserMarkPw);
if (UserMarkCreate.Succeeded) {
var addUserMarkToRoleFacultyResult = UserManager.AddToRole(mark.Id, roleFaculty);
}
mark.HomeTown = "Markham";
var UserMarkInfo = new MyUserInfo() {
FirstName = "Mark", LastName = "McTest" };
mark.MyUserInfo = UserMarkInfo;
mark.PersonId = 8;
dc.Faculties.Add(mark);
创建教员
对象(标记)并将其添加到角色教员
:
string roleFaculty = "Faculty";
if (!RoleManager.RoleExists(roleFaculty)) {
var roleFacultyCreateResult = RoleManager.Create(new IdentityRole(roleFaculty));
}
// 1 create faculty Mark (8)
Faculty mark = new Faculty();
// add "mark" to role "faculty"
mark.SenecaId = "034234678";
mark.FirstName = "Mark";
mark.LastName = "McTest";
mark.Phone = "555-567-6789";
mark.UserName = "Mark";
string UserMarkPw = "123456";
var UserMarkCreate = UserManager.Create(mark, UserMarkPw);
if (UserMarkCreate.Succeeded) {
var addUserMarkToRoleFacultyResult = UserManager.AddToRole(mark.Id, roleFaculty);
}
mark.HomeTown = "Markham";
var UserMarkInfo = new MyUserInfo() {
FirstName = "Mark", LastName = "McTest" };
mark.MyUserInfo = UserMarkInfo;
mark.PersonId = 8;
dc.Faculties.Add(mark);
错误:
"Entity of type Faculty in state Added has the following validation errors:"
...
"User name Peter is already taken."
你已经把它们绑好了。那是你的问题
IdentityUser
是用户帐户,因为Faculty
是Person
是IdentityUser
,Faculty
是IdentityUser
。通过创建Faculty
对象,您还创建了一个用户帐户
事实上,除非您自定义了实体配置,否则entity Framework会在带有鉴别器列的AspNetUsers表中执行所有这些操作。换句话说,您没有实际的教员表或人员表,而是一个AspNetUsers表,其中有一列填写了特定类类型的名称(“教员”、“人员”等)
更新
标识仅支持一种用户类型。您可以指定在应用程序上下文中继承的IdentityDbContext
泛型的类型。在本例中,您已将其设置为Person
(即IndentityDbContext
)。这意味着,ApplicationUser
根本没有被使用。如果那是你想要的,那很好。你的“用户”可以随意命名;它不必是ApplicationUser
。然后,您只使用了STI(单表继承)来添加更具体的“类型”用户,这将是您的Faculty
类。对于基类是实体(映射到数据库表)的继承结构,实体框架默认情况下会这样做。基本上,Faculty
、Person
和IdentityUser
的所有字段都映射到同一个数据库表,并且添加了一个鉴别器列来跟踪实体框架在从数据库中提取该行时应实例化的特定类类型。STI是一种将对象层次结构映射到关系数据库的常见继承策略,在大多数情况下,它工作得很好,但您需要记住,超类上的所有字段都必须为空。换句话说,feculty
上的字段在数据库级别不能为空,否则会出现错误。但是,您可以通过应用程序将该字段设为必填字段,即使从技术上讲,在数据库级别插入新行并不需要该字段。您可能会遇到错误“用户名标记已被使用。”
因为用户名为“'Mark'的用户是通过以下语句创建并保存在数据库中的
var UserMarkCreate = UserManager.Create(mark, UserMarkPw);
您再次尝试在dc
中使用语句dc.Faculties.add(Mark)
添加'Mark'
现在,当您执行dc.SaveChanges()
时,它会再次尝试在DB中插入'Mark'。因此你会犯错误
“已使用用户名标记。”
谢谢你,克里斯!我可以请你看看我最新的问题吗?我添加了第7节。在这种情况下,我建议创建CustomMembershipProvider。这有点烦人,但最终它比开箱即用的SimpleMembership更有用,因为它可以完美地满足您的需求和现有的DB字段等。成员资格提供商与身份不兼容。亲爱的Chris,感谢您的宝贵意见。我已经更新了我的问题,你能看一下第8节吗?我相信这是由于在一个新实体中添加了相关的项目,而这些项目本身已经存在而导致的竞争条件。这有点迟钝,但本质上,当您添加新的主实体时,它会附加它,并尝试附加其相关对象,这些相关对象已经附加,并且您会得到错误。尝试先添加主实体(无需保存,只需调用
。添加(实体)
),然后再将相关属性与之关联。非常感谢!我得到了它!