所以这有点'我怎么能变得懒散?'或者“我能超级过度保护吗?”问题的类型。我试图解释的情况是......
使用新字段更新模型,但无论出于何种原因,在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)
在表格的底部。
答案 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>