如何创建新的实体对象,在SaveChanges()之前在Model中修改它

时间:2011-08-03 19:30:02

标签: c# asp.net entity-framework asp.net-mvc-3

我一直在讨论这个问题几个小时,无法弄清楚问题。所以我使用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行

1 个答案:

答案 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)