以编程方式为未明确使用的模型属性创建hiddenfor字段

时间:2015-01-27 21:41:40

标签: c# asp.net-mvc razor

所以这有点'我怎么能变得懒散?'或者“我能超级过度保护吗?”问题的类型。我试图解释的情况是......

使用新字段更新模型,但无论出于何种原因,在db访问控制器中实现其显式设置时,将忘记在模型的更新用户界面中添加属性。当用户单击“提交”时,此属性的值使其成为“null”,并简要地将数据库值“更新”为null。

有没有办法在模型上获取未明确放入表单的属性,并为这些属性添加hiddenfors? (最糟糕的情况是,此值不会更新而不是丢失数据)。

编辑:潜在情景

初始对象(用作表单上的模型)

public MyObject 
{
   public string Value1 { get; set; }
   public string Value2 { get; set; }
}

表格有

@Html.TextboxFor(model => model.Value1)
@Html.TextboxFor(model => model.Value2)

稍后,有人出现并添加

public string Value3 { get; set; }

到MyObject,但忘记添加

@Html.TextboxFor(model => model.Value3)

这导致在提交表单时将Value3提交为null。我想弄清楚的是,是否可以在表格中添加类似于以下内容的内容:

foreach (var nonExplicitlyUsedProperty in Model.Properties) 
{
   @Html.HiddenFor(model => model.nonExplicitlyUsedProperty)
}

在上面的场景中,这相当于添加

@Html.HiddenFor(model => model.Value3)

在表格的底部。

2 个答案:

答案 0 :(得分:1)

您有几个选择:

  • 客户端验证
  • 服务器端验证
  • 服务器端清理

听起来您正在使用表单操作,它会自动将数据提交到 Controller 。您需要在将数据传递到服务器之前验证来自客户端的数据。

另一种方法是简单地验证参数,以避免传递 Null 或修改 SQL 以忽略传递的 Null 值在它进行更新之前。

另一种方法是以更好地代表 Model Controller 的方式耦合UI的功能。这样它就更容易理解。


重要的: 您可以使用隐藏字段在初始化模型时存储数据,但是在您继续操作之前,您需要引入额外的数据并需要提供/管理。虽然黑客可以解决你的问题,但它并不是理想的,因为它会绕过你的问题,而不是真正地解决它。


@if(Model != null)
{
     foreach(var content in Model)
     {
         <div>
              <input type="hidden" id="hdName" name="name" value="@content.Name" />
         <div>
     }
}

通过使用此隐藏字段,您必须确保用户何时更改字段,隐藏字段将更新如下:

$('#txtName').blur(function () {
     $('#hdName').val($(this).val());
});

正如您所看到的,使用 Hidden Fields 如何真正成为一场噩梦,所以我建议您重新考虑您的解决方案。

答案 1 :(得分:1)

所以这是我一直试图做的最终答案......

首先构建表单(正常)。

然后为模型上的所有属性生成隐藏的输入字段,如此...使用字符串格式为明确定义的输入字段的name / id提供略微不同的name / id属性。 (因为ASP.Net通过名称而不是通过id将值从视图传递到控制器,但是jQuery标准似乎是使用id而不是name,帐户适用于这两种情况)

@foreach (var property in Model.GetType().GetProperties())
{
    <input type="hidden" name="@(String.Format("{0}_2", property.Name))" id="@(String.Format("{0}_2", property.Name))" value="@property.GetValue(Model, null)" />
}

然后,使用jQuery迭代隐藏的输入,删除添加到“name”属性的鉴别器以获取实际的属性名称,然后检查id为该值的输入(原始属性名称)是否具有一个值。如果它有一个值,则不需要隐藏的输入,可以将其删除,否则,将隐藏的输入名称属性(因为这是ASP.Net将值传递给控制器​​的方式)重命名为原始属性名称。

<script>
    $(document).ready(function() {
        $("input[type='hidden']").each(function() {
            var actualPropertyName = $(this).attr("id").substr(0, ($(this).attr("id").length - 2));
            var value = $("#" + actualPropertyName).val();
            if (value != null) {
                $(this).remove();
            } else {
                $(this).attr("name", actualPropertyName);
            }
        });
    });
</script>