Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Entity framework 4 ASP.NET MVC保存新记录和更新现有记录约定_Entity Framework 4_Asp.net Mvc 3 - Fatal编程技术网

Entity framework 4 ASP.NET MVC保存新记录和更新现有记录约定

Entity framework 4 ASP.NET MVC保存新记录和更新现有记录约定,entity-framework-4,asp.net-mvc-3,Entity Framework 4,Asp.net Mvc 3,我正在开发我的第一个ASP.NET MVC(版本3的beta版)应用程序(使用EF4),我正在努力解决一些关于保存新记录和更新现有记录的约定。我使用的是标准路线图 当用户转到页面/会话/评估时,他们可以输入新记录并保存它。我有一个定义如下的动作: [ActionName("Evaluate")] [AcceptVerbs(HttpVerbs.Post)] public ActionResult EvaluateSave(EvaluteSessionViewModel evaluatedSessi

我正在开发我的第一个ASP.NET MVC(版本3的beta版)应用程序(使用EF4),我正在努力解决一些关于保存新记录和更新现有记录的约定。我使用的是标准路线图

当用户转到页面/会话/评估时,他们可以输入新记录并保存它。我有一个定义如下的动作:

[ActionName("Evaluate")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EvaluateSave(EvaluteSessionViewModel evaluatedSession)
{
}
if (evaluatedSession.MyEntity.myField <> savedSession.myField)
   savedSession.myField = evaluatedSession.MyEntity.myField;
当他们保存时,我从视图模型中抓取一个实体,将其附加到我的上下文并保存。到目前为止,一切顺利。现在,我希望用户能够通过url/session/Evaluate/1编辑此记录,其中“1”是记录ID

编辑:我将EF图元作为属性附着到视图模型

如果我添加一个重载的方法,就像这样(这样我可以自动检索'1'部分)

我得到一个“控制器类型“SessionController”的当前操作请求“Evaluate”在以下操作之间不明确”错误。我不知道为什么它们是模棱两可的,因为它们在我看来是独一无二的

我决定现在跳过这个问题,看看是否可以让它更新现有记录,所以我注释掉了没有ID参数的EvaluateSave

我想做的是:

// Load the original entity from EF
// Rebind the postback so that the values posted update the entity
// Save the result
由于实体作为参数(evaluatedSession)填充,因此重新绑定发生得太快。但是当我看到我想采用的方法时,我意识到它会打开我的代码进行黑客攻击(因为用户可以在发布的主页中添加字段,这些字段可以覆盖我在实体中设置的值)

因此,我似乎不得不手动检查每个字段,看看它是否已更改,如果已更改,则更新它。大概是这样的:

[ActionName("Evaluate")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult EvaluateSave(EvaluteSessionViewModel evaluatedSession)
{
}
if (evaluatedSession.MyEntity.myField <> savedSession.myField)
   savedSession.myField = evaluatedSession.MyEntity.myField;
从EF方面来看,您应该能够使用上下文中的ApplyCurrentValues()方法,例如

context.ApplyCurrentValues(savedEval.EntityKey.EntitySetName, evaluatedSession);
当然,这似乎对我不起作用。我不断得到“在ObjectStateManager中找不到具有与所提供对象的键匹配的键的对象。请验证所提供对象的键值是否与必须应用更改的对象的键值匹配。”

我尝试附加刚刚加载的原始实体,以防由于某种原因(在ApplyCurrentValues之前)它没有附加到上下文:


它仍然失败。我猜这与MVC创建的EF实体对象的类型有关(可能它的填充量不够,EF4无法处理它?)。我曾希望能够让.NETFramework逐步了解它试图做什么,但似乎EF4并不是交易的一部分。我用Reflector查看了它,但对我来说,有点难以想象正在发生的事情。

好吧,它的工作方式是每个httpverb只能有一个方法名。因此,最简单的方法是创建一个新的操作名称。类似于“创建”新记录和“编辑”现有记录

您可以使用AntiForgeryToken()来验证数据。它并不能阻止所有的黑客行为,但它是一个额外的好处

附加的
每个httpverb只能有一个操作名的原因是,模型绑定只尝试进行模型绑定,实际上并不特定于类型。如果有两个方法具有相同的操作名称和两种不同类型的参数,它就不能尝试找到最佳匹配,因为您的意图很明显是一回事,而程序只能看到某种类型的最佳匹配。例如,您可能有一个参数Id和一个包含属性Id的模型,但它可能不知道要使用哪个属性Id。

好的,它的工作方式是每个httpverb只能有一个方法名。因此,最简单的方法是创建一个新的操作名称。类似于“创建”新记录和“编辑”现有记录

您可以使用AntiForgeryToken()来验证数据。它并不能阻止所有的黑客行为,但它是一个额外的好处

附加的
每个httpverb只能有一个操作名的原因是,模型绑定只尝试进行模型绑定,实际上并不特定于类型。如果有两个方法具有相同的操作名称和两种不同类型的参数,它就不能尝试找到最佳匹配,因为您的意图很明显是一回事,而程序只能看到某种类型的最佳匹配。例如,您可能有一个参数Id和一个包含属性Id的模型,但它可能不知道要使用哪个属性Id。

好的,看起来解决重载方法(在我的例子中)的一个简单方法是只创建一个允许空int的方法,如下所示:public ActionResult EvaluateSave(int?ID,EvaluateSessionViewModel evaluatedSession)是的,您可以这样做。我不建议这样做,因为这种假设类型可能会根据模型的不同而变化。例如,如果您的EvaluateSessionViewModel包含同名属性,或者您有一个名为ID的cookie,或者有许多不同的东西仍然会尝试填充ID值。好的,这看起来很简单重载方法的解决方法(在我的例子中)是只创建一个允许如下所示的可为null的int的方法:public ActionResult EvaluateSave(int?ID,EvaluateSessionViewModel evaluatedSession)是的,您可以这样做。我不建议这样做,因为这种假设类型可能会根据模型而改变。例如,如果您的EvaluateSessionViewModel包含具有相同名称的属性,或者您有一个名为ID的cookie,或者有许多不同的东西仍然会尝试填充ID值。
context.AttachTo(savedEval.EntityKey.EntitySetName, savedEval);