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

本文关键字:SaveChanges 修改 Model 对象 创建 何创建 实体 | 更新日期: 2023-09-27 18:04:30

这个问题我已经考虑了好几个小时了,还是没能找到问题所在。我用的是ASP。NET MVC 3与实体框架4.1。我正在从零开始编写帐户管理控制器和模型。我的问题是,每当控制器从视图接收到填充的实体对象并将其发送到模型时,如果我尝试事先修改任何字段,则模型不会保存它。

这是我的模型的相关部分,名为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实体对象,其相关部分如下:

    [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,但如果我改变这一行,只是改变成员。密码为字符串"1",它也不会工作。

那么,我做错了什么?我对编程完全陌生,所以如果这个问题很明显,请原谅我。是不是有可能在创建帐户时从视图创建实体对象,将其发送给控制器,然后将其传递给模型,该模型在保存之前修改密码以散列它?

BTW,引发的异常错误是:

System.Data.Entity.Validation。DbEntityValidationException:一个或多个实体验证失败。查看'EntityValidationErrors'属性了解更多细节。at System.Data.Entity.Internal.LazyInternalContext.SaveChanges() at System.Data.Entity.DbContext.SaveChanges() at Politiq.Models.ObjectManager.MemberManager。在c:' users ' c中添加(Member Member)Yehia'Documents'Visual Studio 2010'Projects'Politiq2'Models'ObjectManager'MemberManager.cs:在Politiq.Controllers.AccountController. cs第21行。注册(Member Member)在c:' users ' cYehia'Documents'Visual Studio 2010'Projects'Politiq2'Controllers'AccountController.cs:line 39

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

我看到你的成员实例是由一个模型绑定器(即不在你的代码)创建的,但我没有看到它实际上被添加到表中。你错过db.Members.Add()的电话了吗?

无论如何,我建议为"注册数据"创建一个单独的模型类,这样你就不会让MVC模型绑定器创建Member实例,而是自己创建它。原因是这种方法是不安全的,因为默认情况下绑定器会尝试将每个HTML输入字段分配给一个匹配的属性,所以黑客可以在你的对象中注入Id值,这将导致异常(可能还有一些其他讨厌的事情)。

当然,你可以使用[Bind(Exclude="ID")],这样它就不会尝试填充ID,但我仍然会将数据库实体和用户输入分开:

MemberController

public ActionResult Register(RegistrationForm form)

MemberManager

public Member RegisterMember(RegistrationForm form)