C# MVC4:回发为模型中object类型的属性返回一个数组
我有一个具有object类型属性之一的模型。此属性是动态属性,有时可能包含字符串、日期或布尔值 我有一个编辑器模板的每种类型,即布尔,字符串,日期等 我遇到的问题是,当发布页面时,回发包含一个数组,而不是实际值。数组的第一个元素包含实际值 为什么将值作为数组返回 我的模型C# MVC4:回发为模型中object类型的属性返回一个数组,c#,asp.net-mvc,asp.net-mvc-4,C#,Asp.net Mvc,Asp.net Mvc 4,我有一个具有object类型属性之一的模型。此属性是动态属性,有时可能包含字符串、日期或布尔值 我有一个编辑器模板的每种类型,即布尔,字符串,日期等 我遇到的问题是,当发布页面时,回发包含一个数组,而不是实际值。数组的第一个元素包含实际值 为什么将值作为数组返回 我的模型 public string Description; public string Name { get; set; } public Type Type{ get; set; } objec
public string Description;
public string Name { get; set; }
public Type Type{ get; set; }
object _value;
public object Value { get;set;}
视图中的语句
@Html.EditorFor( m => m.Value)
编辑:将对象名称从_值更正为值。这是一个错误的Ctrl V操作
编辑:在浏览器中呈现的HTML
当对象包含布尔值时(复选框):
视图:
@model SampleDynamicDataProject.Models.DynamicData
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>DynamicData</legend>
<div class="editor-label">
@Model.Description
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Value)
@Html.ValidationMessageFor(model => model.Value)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
如代码所示,我的问题是在编辑的post操作中,即使对于一个简单的字符串,我也会以数组的形式获取值。
这里的示例项目代码我在另一个论坛上得到了问题的答案 基本上,MVC绑定器返回数组的原因是它不了解html中使用的数据/控件类型,并且模型绑定器失败 我通过修改模型使其具有两个不同的属性a来解决我的问题
public String StringValue
public Bool BooleanValue
当类型为字符串、日期、数字等时,我使用StringValue字段。
我对类型为Boolean的字段使用BooleanValue
这不是最干净的方法,但在我编写自己的自定义模型活页夹之前,它必须这样做
感谢布鲁斯在这里回答了我的问题
我现在明白了为什么模型绑定器失败了
把他的答案贴在这里,以利他人
您需要了解浏览器回发是如何完成的。表单提交时,发送名称/值对的集合。名称是表单元素名称,值是元素值。标准url编码已完成。因此:
postdata是
foo=1&bar=true
注意,post数据只是一个没有类型数据的字符串。brwser允许重复的名称,因此
发布数据为:
foo=1&foo=true
当asp.net将post数据加载到表单集合(它只是一个字典)中时,它不能添加键“foo”两次,而是包含由“,”(“1,true”)分隔的值。绑定器只是将其视为一个名为foo的字符串数组,具有2个值。
现在我们来看另一种浏览器行为。支持选中的表单元素(单选和复选框)仅在选中时才包括post数据。这会导致带有复选框的mvc活页夹出现问题,因为它无法从回发数据中判断元素是否未选中或未包含。如果使用tryupdate仅应用模型特性的子集,这一点很重要,因为仅渲染了子集。为了避免这种情况,复选框帮助器呈现两个同名字段,一个隐藏字段的值为“false”,另一个复选框的值为“true”。
这可能是因为ASP.NET MVC模型绑定器使用数组和索引来绑定要查看的模型属性。由于它现在不是_值的类型,所以它是按原样将视图绑定到模型。
@HTML.EditorFor(m=>m.value)
提供了什么?@emrenevayeshirazi我必须在模型中使用对象类型,因为数据的最终类型是在运行时通过从数据库中获取类型信息来确定的。有没有办法让MVC正常工作?@Tobberoth:它给了我一个复选框或文本框,使用自定义编辑器模板,具体取决于对象中的实际数据(布尔值或字符串)@Pat也许你可以使用,TextBoxFor或TextBoxFor helper的自定义实现。与EditorFor不同,它不应该使用数组来跟踪模型。
public ActionResult Edit(string name ="field1" )
{
Models.DynamicData data1 = new Models.DynamicData();
//all this comes from the database table. I am putting the value directly in field just for simplicity
// this is exactly how I convert the value from the entity to the model
data1.Description = "Field1 Description";
data1.Name = "field1";
data1.Type = typeof(string);
data1.Value = Convert.ChangeType("MyStringValue", data1.Type);
//similarly add few more fields to the model collection
return View(data1);
}
[HttpPost]
public ActionResult Edit(Models.DynamicData model)
{
// break point here : model.Value shows a array of string instead of the edited value.
return View(model);
}
@model SampleDynamicDataProject.Models.DynamicData
@{
ViewBag.Title = "Edit";
}
<h2>Edit</h2>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<fieldset>
<legend>DynamicData</legend>
<div class="editor-label">
@Model.Description
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Value)
@Html.ValidationMessageFor(model => model.Value)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
data1.Description = "Field2 Description";
data1.Name = "field2";
data1.Type = typeof(bool);
data1.Value = Convert.ChangeType("true", data1.Type); // database stores "true" as string which is converted into a boolean and stored in the object.
public String StringValue
public Bool BooleanValue