如何创建新的实体对象,在SaveChanges()之前在Model中对其进行修改 [英] How to create new entity object, modify it in Model before SaveChanges()

查看:71
本文介绍了如何创建新的实体对象,在SaveChanges()之前在Model中对其进行修改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经将这个问题搁置了几个小时,无法解决问题.因此,我将ASP.NET MVC 3与Entity Framework 4.1一起使用.我正在从头开始编写帐户管理控制器和模型.我的问题是,每当Controller从View接收到已填充的实体对象并将其发送到Model时,如果我尝试事先修改任何字段,Model都不会保存它.

I've been dwelling with this issue for hours and couldn't figure out the problem. So I'm using ASP.NET MVC 3 with Entity Framework 4.1. I am writing the account management controller and models from scratch. My problem is that whenever the Controller receives the filled-up entity object from the View and sends it onwards to the Model, the Model won't save it if I try to modify any of the fields beforehand.

这是我模型的相关部分,名为ModelManager.cs:

Here is the relevant portion of my model, named 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();
    }

该模型从Controller中获取 Member成员实体对象作为参数,其相关部分如下:

That model gets the Member member entity object as a parameter from the Controller, relevant portion of-which is below:

    [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);
    }

如果我删除对模型中实体对象的任何属性的 any 修改,代码将起作用(即,删除实体对象的 Crypto.HashPassword 所在的行密码字段,起初我以为是HashPassword的问题,但是如果我更改该行以仅更改member.Password到字符串"1",那么它也不起作用.

If I remove any modification to any property of the entity object in the Model, the code works (i.e. I remove the line where I Crypto.HashPassword the entity object's Password field. At first I thought the issue was with HashPassword, but if I change that line to simply change the member.Password to string "1", it won't work either.

那么,我在做什么错?我是编程的新手,所以如果这个问题很明显,请多多包涵.创建帐户后,是否可以从View创建一个实体对象,然后将其发送到Controller,然后将其传递给Model,该Model修改密码以在保存之前对它进行哈希处理?

So, what am I doing wrong? I'm entirely new to programming so bear with me if the issue is quite flagrant. Isn't it possible to create an entity object from the View upon account creation, send it through to the Controller that then passes it on to the Model which modifies the Password to hash it before saving it?

顺便说一句,引发的异常错误是:

BTW, the exception error raised is:

System.Data.Entity.Validation.DbEntityValidationException:对一个或多个实体的验证失败.有关更多详细信息,请参见'EntityValidationErrors'属性.在System.Data.Entity.Internal.LazyInternalContext.SaveChanges()在System.Data.Entity.DbContext.SaveChanges()在Politiq.Models.ObjectManager.MemberManager.Add(成员)在C:\ Users \ C中.Yehia \ Documents \ Visual Studio 2010 \ Projects \ Politiq2 \ Models \ ObjectManager \ MemberManager.cs:C:\ Users \ C中Politiq.Controllers.AccountController.Register(Member member)的第21行.Yehia \ Documents \ Visual Studio 2010 \ Projects \ Politiq2 \ Controllers \ AccountController.cs:第39行

System.Data.Entity.Validation.DbEntityValidationException: Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. at 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(Member member) in C:\Users\C. Yehia\Documents\Visual Studio 2010\Projects\Politiq2\Models\ObjectManager\MemberManager.cs:line 21 at Politiq.Controllers.AccountController.Register(Member member) in C:\Users\C. Yehia\Documents\Visual Studio 2010\Projects\Politiq2\Controllers\AccountController.cs:line 39

推荐答案

我看到您的成员实例是由模型绑定程序创建的(即不在您的代码中),但是我看不到它实际上已添加到表中.您是否错过了 db.Members.Add()通话?

I see your member instance being created by a model binder (i.e. not in your code) but I don't see it actually being added to the table. Did you miss db.Members.Add() call?

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

Anyway, I would suggest creating a separate model class for "registration data" so you don't let MVC model binder create Member instance but instead create it yourself. The reason is this approach is insecure because by default the binder will try to assign each HTML input field to a matching property so a hacker can inject Id value in your object that will cause an exception (and probably some other nasty things).

当然,您可以使用 ,因此它不会尝试填充ID,但我仍然会分离数据库实体和用户输入:

Of course, you can use [Bind(Exclude="ID")] so it doesn't try to fill the ID but I would still separate database entities and user input:

MemberController

public ActionResult Register(RegistrationForm form)

会员经理

public Member RegisterMember(RegistrationForm form)

这篇关于如何创建新的实体对象,在SaveChanges()之前在Model中对其进行修改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆