2010-06-25 53 views
3

我正在通过示例MVC Nerdinner教程并在AdventureWorks数据库上使用它。我在CategoryController中创建了一个Edit动作来编辑AdventureWorks中的产品类别。该表中唯一可更新的字段是Name(其他字段 - ID,RowGUID和UpdateDate是自动生成的)。所以我的编辑窗体View只有1个字段用于名称(产品类别)。对于编辑我的“保存”操作是下面: -在MVC中编辑动作{HTTP POST}使用UpdateModel与Request.Form集合

[AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult Edit(int id, FormCollection collection){ 
     ProductCategory p = awRepository.GetProductCategory(id); 
     try 
     { 
      //UpdateModel(p); 
      p.Name = Request.Form["Name"]; 
      awRepository.Save(); 
      return RedirectToAction("Details", new { id = p.ProductCategoryID }); 
     } 
     catch 
     { 
      foreach (var err in p.GetRuleViolations()) 
      { 
       ModelState.AddModelError(err.PropertyName, err.ErrorMessage); 
      } 
      return View(p); 
     } 
    } 

如果我使用的代码如上,一切工作只要我输入的名称是有效的(因而不存在例外)。如果我引入一个错误(如果名称为空,或者出于测试目的,这是由GetRuleViolations引发的)是一个特定的“Te​​st”字符串),我在该视图的这一行中得到NullReferenceException(对象引用未设置为对象的实例) (类别/ Edit.aspx)当编辑视图重绘(向用户显示的错误,让他改正)

 <%= Html.TextBox("Name") %> 

如果我更新使用的UpdateModel(p)我的产品分类,而不是使用的Request.Form变量,一切工作正常;有效数据被保存,无效数据重新绘制显示错误消息的视图。

我的问题是:通过读取Request.Form集合中的值,UpdateModel和手动更新我的变量有什么区别? Nerdinner教程似乎暗示两者都是相同的。所以我很惊讶,一个工作顺利,另一个引发一个例外。

回答

1

听起来是这样的:

http://forums.asp.net/p/1396019/3006051.aspx

所以,对于每一个错误,你有 ModelState.AddModelError(添加),并调用 查看一遍,MVC框架将尝试 找到一个AttemptedValue每找到一个 错误。因为你没有添加 他们,MVC会抛出一个异常。

通常情况下,你不需要添加这些 值: 公众的ActionResult:AttemptedValues是当你使用 DefaultBinding(通过调用 的UpdateModel()或通过将对象 绑定为一个操作方法放慢参数 automaticaly填充 创建(的FormCollection形式, YourObjectType yourObject)。

看起来像下面通过的UpdateModel自动完成的,而不是由你自己手动完成?

if (Form["Name"].Trim().Length == 0) 
{  
    ModelState.AddModelError("Name", "Name is required");  

    //You missed off SetModelValue? 
    ModelState.SetModelValue("Name", Form.ToValueProvider()["Name"]); 
} 
+0

是的,当我这样做时,我必须设置Model值。后来我转向使用DataAnnotations来提供自定义视图模型的大部分逻辑。 – 2010-06-25 12:31:16