2011-03-15 26 views
4

情景
路线:/模板/定制凡/ 10 :10 =模板()ASP.NET MVC 3机型ID

在控制器的ID模型被创建基于该模板使得View的模型实际上是一个Customization()对象,因为它是新的,它实际上具有Id 0。

在我渲染@ Html.HiddenFor视图(M => m.Id),并将所得该隐藏的输入的值是,虽然它应该是因为m是类型定制的。我之前用MVC 2遇到过这个问题,并且没有使用helper方法来解决它。

问题

  1. 有注释或东西我 可以添加到HTML辅助方法 实际呈现正确的价值?

  2. 这是一个bug(MVC似乎是 渲染m.Id作为路由值 不管什么实际的模型 在控制器设置的)?

澄清附加代码

查看

@model Project.Core.Domain.Customization 
@using(Html.BeginForm("save", "customization")) 
{ 
    @Html.HiddenFor(m => m.Id) 
    @Html.HiddenFor(m => m.Template.Id) 
    <button type="submit" id="save" name="save">Save</button> 
} 

控制器

 public ActionResult Customize(int id) 
    { 
     var template = Persistence.Data.RetrieveObject<Template>(id); 
     var model = new Customization(); 

     ViewBag.Template = template; 
     return (View(model)); 
    } 

解决方案

行动更改签名:

public ActionResult Customize(int TemplateId){ ... } 

更改链接到行动,例如:

@Html.ActionLink("customize", "customize", new { TemplateId = template.Id }) 

我结束了一个URL,看起来像

/template/customize?TemplateId=10 

这是丑陋的,但我可以保持我的观点清洁与模型。所以这是一个胜利 我。

+0

请问你能展示一些代码吗?控制器和视图会很有帮助。这听起来像你的视图可能会继承错误的模型类型。 –

+0

增加了一些代码。该视图为模型使用了正确的类型。正如查尔诺认为这可能不是一个错误,而是一个后果。问题是这个结果打破了自动化。 –

回答

2

我认为这是因为当你使用类似@Html.HiddenFor(m => m.Id)的东西时,html助手会在不同的地方查找填充输入的值,而路由中的值就是其中一个地方。

所以,你可以改变你的路线,这样它就像template/customize/{TemplateId},然后让你的行动方法反映这一点,例如, public ActionResult Customize(int templateId)

或者您可以更改您的视图模型(或创建自定义视图模型),该视图模型具有CustomizationId属性,而不仅仅是Id

不,这不是一个错误...它更多的是一个功能,可能会有无法预料的后果。但是一旦你意识到这一点,它就像一种享受。

+0

我意识到我可能会违反规则并破坏其中的一些规则。肯定会感觉到那种痛苦,但我仍然觉得m.Id应该始终是Model.Id而不是Route.Id,除非模型在上下文中不存在。 –

+0

你让我接受一个可以接受的解决方案,所以我正在标记你的答案。跟进包含我做过的事情的编辑。 –

+1

只是想澄清一下,你的任何其他解决方案都可以起作用(并且路线本来会更加优雅)。我只是不想在我的路由表中创建一个新的路由。 –

5

您随时可以选择不使用HTML助手在这种情况下,用而不是纯HTML:

<input name="Id" id="Id" type="hidden" value="@Model.Id"/>

+0

非常好,谢谢! –

0

为了防止覆盖模型的相应属性路由值,调用ModelState.Clear()在你的控制器行动。使用/读取模型状态后,请小心地调用此方法

public ActionResult Customize(int id) 
{ 
    var template = Persistence.Data.RetrieveObject<Template>(id); 
    var model = new Customization(); 

    ViewBag.Template = template; 

    this.ViewData.ModelState.Clear(); // add that after you consume the ModelState 
    return (View(model)); 
} 

就我而言,隐藏输入获取模型的值而不是路径值。