MVC3不发布整个模型

时间:2012-01-24 18:31:45

标签: c# asp.net-mvc-3 entity-framework binding model

我对MVC很新,我真的很想习惯模型绑定。我有一个我在表单中创建的简单模型。但是,当我发布该表单时,文本框值只会转移到控制器。我还需要使用DisplayTextFor完成的描述字段。这是我要为自定义模型绑定器制作的东西吗?我可以采取一个快捷方式,只是使描述成为一个没有边框的只读文本框,所以它看起来像文本,但我想以正确的方式做到这一点。这是我的代码:

public class FullOrder
{
    public List<FullOrderItem> OrderList { get; set; }
    public string account { get; set; }
    public string orderno { get; set; }
}

public class FullOrderItem
{
    public int? ID { get; set; }
    public int? OrderId { get; set; }
    public string Description { get; set; }
    public int Qty { get; set; }
    public decimal? Price { get; set; }
}

这是视图

<table class="ExceptionAltRow">
    <tr style="background-color: #DDD;">
        <td class="strong" style="width:500px;">
            Description
        </td>
        <td class="strong" style="width:100px;">
            Qty
        </td>
        <td class="strong" style="width:100px;">
            Previous Purchases
        </td>
    </tr>
    @for (int i = 0; i < Model.FullOrder.OrderList.Count(); i++)
    {
        <tr>
            <td>
                @Html.DisplayTextFor(m => m.FullOrder.OrderList[i].Description)
            </td>
            <td>
                @Html.TextBoxFor(m => m.FullOrder.OrderList[i].Qty, new { @style = "width:50px;" })
            </td>
        </tr>
    }
    </table>

这是控制器:

[HttpPost]
public ActionResult AddItem(FullOrder f)
{
    //doesn't work description is not passed but qty is
}

有没有办法可以让我的模型只是简单地传递帖子上的描述,即使它不是我模型中绑定项目的文本框?

3 个答案:

答案 0 :(得分:2)

将发布到您的应用程序的唯一数据是在提交的表单上可用的数据(当然,除非表单字段被禁用)。您可以通过实施custom model binder来覆盖控制器看到的内容。

在这种情况下,您的表单由单个文本字段的许多实例组成:

@Html.TextBoxFor(m => m.FullOrder.OrderList[i].Qty, new { @style = "width:50px;" })

如果你想填写描述和其他内容,他们需要出现在表格上。如果它们不需要可见,那么您可以使用HiddenFor帮助程序:

@Html.HiddenFor(m => m.FullOrder.OrderList[i].Description)

另见What does Html.HiddenFor do?

答案 1 :(得分:1)

当然你无法让它以那种方式运作

首先,您应该知道模型绑定基本上是使用客户端输入发送的数据进行的。 Html.DisplayTextFor帮助器不生成输入,它生成简单的文本。文本不参与提交表单时从客户端发送的数据,因此您不会使它们受到模型限制。如果您查看Request.Form属性,您应该看到证明 - 没有描述字段。

如果要显示文本并让描述参与表单值,您可以执行的操作是使用隐藏字段。 MVC得到了这个

的帮助
 @for (int i = 0; i < Model.FullOrder.OrderList.Count(); i++)
    {
        <tr>
            <td>
                @Html.DisplayTextFor(m => m.FullOrder.OrderList[i].Description)
                @Html.HiddenFor(m => m.FullOrder.OrderList[i].Description)
            </td>
            <td>
                @Html.TextBoxFor(m => m.FullOrder.OrderList[i].Qty, new { @style = "width:50px;" })
            </td>
        </tr>
    }

这样,提交的表单也将包含描述值

答案 2 :(得分:0)

DisplayTextFor函数只会将该文本输出到浏览器的DOM。 MVC框架的绑定基本上是查看POST / GET变量,并自动将这些值设置为模型。

如果要自动绑定任何数据(例如描述文本),则必须将其存储到某种类型的输入和/或隐藏字段。隐藏字段有效,但效率低下,因为您在HTML中添加了大量额外元素,甚至可以由用户使用类似Firebug的内容进行编辑。

我的建议以及我一直在做的是期望不会发回一些信息,并在控制器操作中明确设置:

 [HttpPost]
    public ActionResult AddItem(FullOrder f)
    {
         // Next line is just showing that you should get the existing order
         // from your data layer
         FullOrder existingOrder = orderRepository.GetExistingOrder();

         // Now loop through f.OrderList and update the quantities
         foreach(OrderItem item in f.OrderList) {
             // Find the existing item and update the quantity.
         }

         // Now you have the original information from the DB along with
         // updated quantities.

         // Save results or do whatever is next
         existingOrder.Save();
    }