我的模型是另一个模型的列表,例如ModelList:ModelSingle 在我的剃刀视图中,我正在使用
@model somenamespace.ModelList
@Html.EditorForModel()
这会迭代每个ModelSingle并返回一个强类型为ModelSingle的EditorTemplate。
@model somenamespace.ModelSingle
@using(Html.BeginForm("Action", "Controller", FormMethod.Post, new { id = "formname" + Model.ID}))
{
@Html.AntiForgeryToken()
@Html.EditorFor(p => p.SomeField)
@Html.EditorFor(p => p.AnotherField)
}
这些模板中的每一个都包含一个可用于编辑单个模型的表单。这些是使用我的控制器方法单独发布的
public ActionResult(ModelSingle model)
我遇到的问题是模型没有正确绑定。有了这样的模型
public class ModelSingle()
{
public string SomeField { get; set; }
public string AnotherField { get; set; }
}
正在告诉EditorTemplate它是列表的一部分所以我得到了
<Form>
<input name="[0].SomeField"/>
<input name="[0].AnotherField"/>
<input type="submit" value="Update"/>
</Form>
我不能简单地绑定到ModelList,因为它没有命名ModelList [0] .SomeField,即使它是我不认为除了第一项之外的任何东西都可以。
无论如何都要让EditorTemplate忽略它的模型是列表的一部分或强制DropDownListFor,EditorFor等....只使用字段名而不预先添加[i]。
我知道我可以强制更改Name =“SomeField”,但我宁愿有一个解决方案来反映Model类本身所做的任何更改。
EDIT - As Requested添加了一个使用View和EditorTemplate的简化示例。
答案 0 :(得分:2)
问题与您的页面模型(列表)生成的输入名称与您的操作所期望的模型之间不匹配有关,该操作是列表中的单个项目。
渲染列表时,默认行为是呈现您向我们显示的索引名称([#]表示法)。由于您希望能够从列表中发布任意项目,因此您不会提前知道使用了哪个索引。当模型绑定器查看单个对象的请求时,它不会尝试使用索引表示法。
从用户角度来看,我不知道您的要求是什么 - 例如是否需要页面刷新,但实现此目的的一种方法是为发布的特定项目提供jQuery帖子:
// pass jquery form object in
var postItem = function($form) {
var postBody = {
SomeField: $form.find('input selector') // get your input value for this form
AnotherField: '' // another input select for this item
}
$.ajax({
url:'<your action url>',
type: 'POST',
contentType:"application/json; charset=utf-8",
data: JSON.stringify(postBody),
dataType: 'json',
success: function(response) {
// do something with returned markup/data
}
});
}
您正在使用json对象手动序列化模型的单个实例并发布该实例。您从操作中返回的内容取决于您:刷新特定项目的新标记,简单状态的json数据等。
或者,您可以考虑手动循环集合中的项目,并使用Html.RenderPartial / Html.Partial使用View模板呈现每个项目。这将使每个项目的名称生成短路,并生成名称,就像它是ModelSingle的单个实例一样。
最后,一个快速(但有点丑陋)的修复方法是让你的action方法获取ModelSingle对象的列表。我不建议这样做。
编辑:我错过了将json发布到mvc动作的一些重要方面
Edit2:关于硬编码名称的评论之后,这样的事情会有所帮助:
var inputs = $form.find('all input selector');
var jsonString = '{';
$.each(inputs, function(index, element) {
var parsedName = element.attr('name').chopOffTrailingFieldName();
jsonString += parsedName + ":'" + element.val() + "',";
});
jsonString += '}';