【问题标题】:MVC3 Not Posting entire ModelMVC3 不发布整个模型
【发布时间】:2012-02-18 00:13:31
【问题描述】:

我对 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
}

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

【问题讨论】:

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


    【解决方案1】:

    将发布到您的应用程序的唯一数据是正在提交的表单上可用的数据(当然,除非表单字段被禁用)。您可以通过实现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?

    【讨论】:

    • 如果一个答案有用,您应该点击向上的箭头来表示。
    【解决方案2】:

    当然你不能让它这样工作

    首先,您应该知道模型绑定基本上是使用从客户端输入发送的数据发生的。 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>
        }
    

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

    【讨论】:

    • 很高兴知道 HiddenFor 呈现为 标签。
    【解决方案3】:

    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();
        }
    

    【讨论】:

      猜你喜欢
      • 2023-03-19
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-24
      相关资源
      最近更新 更多