我一直在讨论这个问题几个小时,无法弄清楚问题。所以我使用ASP.NET MVC 3和Entity Framework 4.1。我从头开始编写帐户管理控制器和模型。我的问题是,每当Controller从View接收填充的实体对象并将其向前发送到Model时,如果我事先尝试修改任何字段,Model将不会保存它。
以下是我的模型的相关部分,名为ModelManager.cs:
public class MemberManager
{
private DAL db = new DAL();
public void Add(Member member)
{
member.Password = Crypto.HashPassword(member.Password);
db.Members.Add(member);
db.SaveChanges();
}
该模型将Member member
实体对象作为Controller中的参数获取,相关部分如下:
[HttpPost]
public ActionResult Register(Member member)
{
try
{
if (ModelState.IsValid)
{
MemberManager memberManager = new MemberManager();
if (!memberManager.UsernameExist(member.Username))
{
memberManager.Add(member);
FormsAuthentication.SetAuthCookie(member.FirstName, false);
return RedirectToAction("Welcome", "Home");
}
else
{
ModelState.AddModelError("", "Username already taken.");
}
}
}
catch
{
ModelState.AddModelError("", "Could not complete account creation. Please try again.");
}
return View(member);
}
如果我删除模型中实体对象的任何属性的任何修改,代码就可以工作(即我删除实际对象的密码字段中Crypto.HashPassword
的行。我认为问题出在HashPassword上,但如果我改变该行只是将member.Password更改为字符串“1”,那么它也无法正常工作。
那么,我做错了什么?我对编程完全不熟悉,如果问题非常明显,请耐心等待。是否可以在创建帐户时从View创建实体对象,然后将其发送到Controller,然后将其传递给模型,模型在保存之前修改密码以对其进行散列?
BTW,引发的异常错误是:
System.Data.Entity.Validation.DbEntityValidationException:一个或多个实体的验证失败。有关详细信息,请参阅“EntityValidationErrors”属性。在System.Data.Entity.Internal.InternalContext.SaveChanges()at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()at System.Data.Entity.DbContext.SaveChanges()at Politiq.Models.ObjectManager.MemberManager.Add (成员)在C:\ Users \ C中。 Yehia \ Documents \ Visual Studio 2010 \ Projects \ Politiq2 \ Models \ ObjectManager \ MemberManager.cs:第21行,位于C:\ Users \ C中的Politiq.Controllers.AccountController.Register(成员成员)。 Yehia \ Documents \ Visual Studio 2010 \ Projects \ Politiq2 \ Controllers \ AccountController.cs:第39行
答案 0 :(得分:0)
我看到您的成员实例是由模型绑定器创建的(即不在您的代码中),但我没有看到它实际上被添加到表中。你错过了db.Members.Add()
电话吗?
无论如何,我建议为“注册数据”创建一个单独的模型类,这样你就不要让MVC模型绑定器创建Member
实例,而是自己创建它。原因是这种方法不安全,因为默认情况下,绑定器会尝试将每个HTML输入字段分配给匹配的属性,这样黑客就可以在对象中注入Id
值,这将导致异常(可能还有其他一些讨厌的东西)。
当然,您可以使用[Bind(Exclude="ID")]
,因此它不会尝试填充ID,但我仍然会将数据库实体和用户输入分开:
<强> MemberController 强>
public ActionResult Register(RegistrationForm form)
<强> MemberManager 强>
public Member RegisterMember(RegistrationForm form)