2011-03-18 45 views
0

我正在使用MVC 3最終RTM。ASP.NET MVC ModelBinder錯誤:將請求變量「id」綁定到Model的屬性「Id」

鑑於

這條路線:

context.MapRoute(
    "Blog_Posts", 
    "Blog/Posts/{id}/{slug}", 
    new { controller = "Posts", action = "Index", slug = UrlParameter.Optional } 
); 

和後的頁面上,例如/博客/帖子/ 2 /一些段塞我綁定在Comment模型的局部視圖:

@Html.Partial("_CommentEditor", new Comment()) 

而且Comment具有public int Id {get; set;}

而在局部視圖,我有這樣的:

@Html.HiddenFor(comment => comment.Id) 

它爲什麼會顯示這個?

<input type="hidden" value="2" name="Id" id="Id" data-val-required="The Id field is required." data-val-number="The field Id must be a number." data-val="true"> 

爲什麼當我在CommentCommentId改變Id它具有正確的0值?

我認爲默認的模型綁定器綁定到路由的{id}

+0

嘗試@ Html.Partial( 「_ CommentEditor」,新評論{ID = 0}) – Paul 2011-03-19 00:08:33

回答

2

這是因爲,當您使用HTML傭工如HiddenFor他們先了解一下路線數據和模型狀態,之後在模型中。因此,他們在您的路線數據中找到參數id = 2,並在您傳遞的模型中使用此值而不是id = 0。

+0

謝謝,這將解釋這個問題。我轉而使用'CommentId'來代替。我也遇到過使用'SomeAction(SomeRequestClass request)'作爲一個Action的變量參數的問題,它試圖將它填充爲一個'HttpContext.Current.Request'對象,這是一回事嗎?我自己沒有看到它,只是有一個同事有問題。 – kamranicus 2011-03-19 15:57:39

+0

**只是一個建議:**由於我總是在我的實體類中使用'Id'作爲屬性名,我寧願將路由變量重命名爲'identifier'。似乎更容易。 'Comment.CommentId'的命名約定似乎沒有必要,也很愚蠢。這就好像我會問你關於你的名字的事情:** Darin,你叫什麼名字?** – 2011-03-19 17:39:33

+0

有趣的是,你提到Robert,我剛剛開始了一個項目,當我嘗試在我的操作方法參數中使用'id'我不斷收到錯誤。我發現我的團隊將它切換到'identifier',因此它們比我更聰明。幸運的是,我使用SubSonic,因此很容易將其更改回'Id'。 – kamranicus 2011-03-23 12:15:06

0

如果您使用的是linq to sql,則標記爲由數據庫提供的字段不能手動設置。

0

嘗試:

Try @Html.Partial("_CommentEditor", new Comment{Id = 0}) 
+0

早些時候我曾試過,沒有運氣,但謝謝你。 – kamranicus 2011-03-19 15:54:38

+0

我想嘗試的另一件事是使用Command/ViewModel。你可以在這裏閱讀更多關於它的信息:http://geekswithblogs.net/michelotti/archive/2009/10/25/asp.net-mvc-view-model-patterns.aspx我通常不會在我的視圖中使用我的實際實體。要從左到右減少,可以使用Automapper:http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/01/22/automapper-the-object-object-mapper.aspx – Paul 2011-03-19 17:05:05

+0

感謝Paul;我最終因爲其他原因最終使用了ViewModel,以使我的生活更輕鬆。現在你應該提到它,我應該使用AutoMapper。 – kamranicus 2011-03-23 12:13:41

1

這是一個錯誤,或者它可能不是因爲下面實現的邏輯;

在Asp.NET MVC中,View引擎使用ViewData(它是可變的,其類型是「ViewDataDictionary」)。而這ViewData有2個屬性「模型狀態」,保存路由值,和「模型」,持有我們的實際模型對象。

  1. 查看引擎查看屬性的「ModelState」對象檢索值。
  2. 如果在步驟1中找到,則返回值。
  3. Else查看「Model」對象以檢索屬性的值。

在上述情況下,路由具有屬性「id」和它的值保存在「ModelState中」,所以它從「ModelState中」,而不是綁定模式返回值。

對於上述情況,任何輸入控件都會呈現意外值。

分辨率爲:

<div class="postData" value='@Model.Id'/> 

//use below jquery function to retrieve data 
var postedData = $('.postData'); 
+0

感謝您的解釋! – kamranicus 2011-03-19 16:01:16