2014-02-06 46 views
0

我有三个级联下拉使用Ajax填充自己的视图。同样在视图中,我调用一个迭代模型中的容器的局部视图,并且为每个项目调用另一个局部视图,根据下拉列表中选定的项目显示适当的编辑模型属性。我构建了一个复杂的模型,其中包含下拉选项以及要编辑的属性,并将模型的部分传递到显示要编辑的属性所需的最低级别部分。MVC 4模型没有返回到控制器

我想在用户通过正常的Html.BeginForm而不是通过使用Ajax单击提交按钮时更新数据库。因此,我必须只包装显示表单中属性的部分,以便现有的Ajax功能不会发布到控制器。问题是,尽管我可以构建这一切,并且提交按钮按预期连接到控制器,但模型返回到控制器null。

模型不是通过建立它们的路径从部分回来的吗?或者更准确地说,即使使用partials构建模型,模型是否仍然保留在页面上?

我相信有人会建议我使用Ajax回发,但这不是我的最佳选择。或者有人可能会问网页上的html是什么样子。奇怪的是,我只能使用浏览器开发工具看到完整的html,它并没有显示在查看源代码中。

任何想法?

把它移到它所属的地方:
我不确定我的理解。我知道返回的模型需要匹配预期的模型,但我没有得到上面的解释。你说:“所以,如果你的控制器看起来像这样:”,当然是这样,那么是什么?那是错的? 我要看看在开发工具Chrome浏览器,看看实际的HTML输出,我看到这在一个案件:
<input class="text-box single-line" id="status_Comments" name="status.Comments" type="text" value="Last Install to be completed this weekend">

因此,如果“名”标签需要寻找合适的,我认为它。我错了吗?

我的日期字段是这样的:
<input type="text" value="8/19/2014" class="datepicker hasDatepicker" id="dp1391795955619">

所以没有“名”的标签,但确实有一个ID。我需要添加一个名字吗?

下面的代码生成上述:
@foreach (Status status in Model) {
string date = status.Date.HasValue ? status.Date.Value.ToShortDateString() : string.Empty;
<tr>
<td style="width: 175px;">@Html.DisplayFor(model => status.Name)</td>
<td style="width: 75px;">@Html.DisplayDropdownColorFor(model => status.StatusValue)</td>
<td style="width: 80px;"><input type="text" value="@date" class="datepicker" /></td>
<td style="width: 80px;"><input type="text" value="" class="datepicker" /></td>
<td style="width: 375px;">@Html.EditorFor(model => status.Comments)</td>
</tr> }`
吉兹,我听起来像一个绝望的白痴。 感谢您的帮助。

+4

这是很多的描述和...没有代码。你能提供这个问题的一个有效的例子吗?模型绑定不是一个真正的黑盒子。您发布的表单中有哪些表单元素?什么键/值对发布到服务器?他们是你期望的吗?它们是否与你期望的模型结构相匹配? – David

+0

我希望避免发布代码,它相当复杂。表单元素都是文本框,没有更复杂的字符串和日期。该模型是基于上一次选择的每个下拉列表的选项列表,最后一个选项触发一个db查询,该查询使用字符串填充模型的其余部分。 – leemid

+2

我认为你错过了这一点。这不是概念上的形式代表的问题。这是POST请求中发送的实际键/值对的问题。那些需要映射到模型类的物理(而非概念)结构。没有一个可以分享的例子,你是唯一可以证实这种情况的人。 – David

回答

0

比方说,你有这样几个类:

public class SomeClass1 
{ 
    public string Name { get; set; } 
    public SomeClass2 class2Value { get; set; } 
} 

public class SomeClass2 
{ 
    public string Description { get; set; } 
} 

而且你在Razor视图形式:

@model SomeClass1 

@using (Html.BeginForm()) { 
    <fieldset> 
     <div class="editor-label"> 
      @Html.LabelFor(model => model.Name) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Name) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.class2Value.Description) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.class2Value.Description) 
     </div> 

     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
} 

实际的HTML代码将是这个样子:

<form id="form1" action="/pageurl" method="POST"> 
    <fieldset> 
     <div class="editor-label"> 
      Name 
     </div> 
     <div class="editor-field"> 
      <input type="text" name="Name" id="Name" value="Name val 1" /> 
     </div> 

     <div class="editor-label"> 
      Description 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.class2Value.Description) 
      <input type="text" name="class2Value.Description" id="class2Value_Description" value="Desc val 2" /> 
     </div> 

     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 
</form> 

如果您注意到,表单字段的name属性由M VC遵循模型。在嵌套对象的情况下,它使用ID中的下划线和名称中的句号来跟踪后置模型中值的位置。

所以,如果您的控制器是这样的:

[HttpPost] 
protected ActionResult Save(SomeClass1 model) 
{ 
    //Then 
    // SomeClass1.Name == "Name val 1" 
    // and 
    // SomeClass1.class2Value.Description == "Desc val 2" 
} 

这就是@大卫在评论越来越善于......无论多么复杂的页面,当<form>回发到服务器时,name您要返回的字段的属性必须与控制器操作期望的模型对齐......否则您将获得null值。

甚至可以为后期模型创建自定义类,只要name属性与模型保持一致,即使它与剃刀视图顶部的@model不相同,MVC也会使用键/值对并填充后期模型中的数据。

UPDATE

我更新上述以反映的校正。下划线是ID属性中的分隔符,该句点用于NAME属性中。

@leemid:一个HTML form只会发布带有name属性的字段。当提交form时,只有name'ed输入,选择,textareas等将被传回服务器。这些名称必须与控制器预期的模型内联。探空冗余的缘故,该日期input场你表现出的例子中,没有一个name attibute,如果name是一样的id,就必须像

模型中的一个属性public string dp1391795955619 { get; set; }

它会显示在您的控制器操作中。您可以手动设置name,只要它以MVC的预期方式命名,以便在发布时将其传递到模型中。

在我的例子,我是想突出的部分是类和属性名之间的关系,与名称属性MVC写入HTML文档,并将其如何保持所有的东西直。在简单的例子中,你不必考虑它。但是在你复杂的情况下,你将不得不手动管理一些命名约定,以便MVC能够理解你想要做什么。

+0

我不确定我的理解。我知道返回的模型需要匹配预期的模型,但我没有得到上面的解释。你说:“所以,如果你的控制器看起来像这样:”,当然是这样,那么是什么?那是错的? 我必须查看开发工具的Chrome浏览器才能看到实际的html输出,我在一个案例中看到: 所以如果'name'标签需要看起来合适,我认为它确实如此。我错了吗? 我的日期字段如下所示: – leemid

+0

我更新了答案。另外,请将答案文中的文字移动到您的问题中,并删除“答案”:) – jwatts1980

+0

好吧,现在我明白了。让我说,你的帮助确实有帮助,但并非总是如此。为此,我深深感谢你。我花了很多时间在一个简单的框架中嘲笑这一切,以便更容易理解并发现一些有趣的事情。您的意见填补了空白。 – leemid