MVC EditorFor删除索引名称

时间:2014-03-05 15:36:24

标签: c# asp.net-mvc asp.net-mvc-4 razor

我的模型是另一个模型的列表,例如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的简化示例。

1 个答案:

答案 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 += '}';