MVC提交具有部分视图的表单

时间:2014-02-26 16:12:34

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

如果之前已经回答道歉,我找不到与我的问题相符的任何内容。

我有一个包含部分视图的视图,在提交视图时,部分视图中的数据不会发送到控制器。我知道如果我使用编辑器模板,这应该可行,但我无法使用它,因为我需要部分内部主模型的数据。

我的创建视图(简化):

@model CreateXmlSchemaModel
@using (Html.BeginForm("Create", "XmlSchema", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <fieldset>
        <div class="editor-label">
            @Html.LabelFor(m => m.XmlSchema.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(m => m.XmlSchema.Name)
        </div>
        <div id="fieldmapping">
            @Html.Partial("_XmlFieldMapping")
        </div>
        <div>
            <input type="submit" value="Create" class="button" />
        </div>
    </fieldset>
}

我的模型结构(简化):

public abstract class XmlSchemaModelContainerBase
{
    public IEnumerable<string> BusinessObjects { get; set; }
    public IEnumerable<XmlInputFieldModel> XmlFields { get; set; }
    public IEnumerable<string> BusinessObjectFields { get; set; }
}

public class XmlSchemaModelContainer : XmlSchemaModelContainerBase
{
    public XmlSchemaModel XmlSchema { get; set; }
}

public class XmlSchemaModel
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string BusinessObject { get; set; }
    public IEnumerable<XmlSchemaField> MappedFields { get; set; }
}

public class XmlSchemaField
{
    public string XmlElement { get; set; }
    public string BusinessObjectField { get; set; }
}

public class XmlInputFieldModel
{
    public string XmlElement { get; set; }
    public string XmlValue { get; set; }
}

public class CreateXmlSchemaModel : XmlSchemaModelContainer
{
    [Required(ErrorMessage = "File upload required")]
    public HttpPostedFileBase Xml { get; set; }
}

我的控制器(我不会发布所有内容,因为我可以立即告诉我的viewModel不包含MappedFields):

[HttpPost]
public ActionResult Create(CreateXmlSchemaModel viewModel)
{
}

我的_XmlMappedFields部分视图:

@model CherwellXmlConnector.Models.XmlSchemaModelContainer
@{
    Model.XmlSchema.MappedFields = Model.XmlSchema.MappedFields.OrderBy(i => i.XmlElement);
}

<div>
    <div>
        @for(int i = 0; i < @Model.XmlFields.Count(); i ++)
        {
            List<CherwellXmlConnector.Models.XmlSchemaField> fields = Model.XmlSchema.MappedFields.ToList();
            string itemValue = Model.XmlFields.FirstOrDefault(x => x.XmlElement == fields[i].XmlElement).XmlValue;

            <div style="width: 300px; display: inline-block;">
                @Html.DisplayFor(x => fields[i].XmlElement)
            </div>
            <div style="width: 300px; display: inline-block;">
                @itemValue
            </div>
            <div class="busoblist" style="display: inline-block;">
                @Html.DropDownListFor(x => fields[i].BusinessObjectField, new SelectList(Model.BusinessObjectFields))
            </div>
            <hr />
        }
    </div>
</div>

我的目的是在partial中向用户显示所有给定的XmlField及其值的列表,并允许他们从每个XmlField的下拉列表中选择一个BusinessObjectField。然后,我希望将其提交回IEnumerable<XmlSchemaField> MappedFields对象内的Controller。这可能吗?

1 个答案:

答案 0 :(得分:4)

是的,这是可能的。

您面临的问题是由于模型绑定的工作原理。如果只是primitive type你试图绑定IEnumerable,那么它就可以正常工作。

@foreach(var item in @Model.XmlSchema.MappedFields)
    {
        string itemValue = Model.XmlFields.FirstOrDefault(x => x.XmlElement == item.XmlElement).XmlValue;
        <div style="width: 300px; display: inline-block;">
            @Html.DisplayFor(i => item.XmlElement)
        </div>
        <div style="width: 300px; display: inline-block;">
            @itemValue
        </div>
        <div class="busoblist" style="display: inline-block;">
            @Html.DropDownListFor(i => item.BusinessObjectField, new SelectList(Model.BusinessObjectFields))
        </div>
        <hr />
    }

如果您查看上面代码生成的源代码,您会看到从上面的代码生成的所有dropdownsselect标记)都具有相同的名称。因此,当您提交表单时,它不会正确绑定到您的模型。

以下是一篇很好的博客文章,我发现它非常有用,并详细解释了这一点

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/

<强>更新

对于那些来这里寻找将数据发布到列表的答案的人,我写了一篇博文。 http://amilaudayanga.wordpress.com/2014/03/05/posting-data-to-a-list-in-asp-net-mvc-part1/