2014-02-26 83 views
5

如果之前已回答此问题,我无法找到符合我的问题的任何内容。MVC以部分视图提交表格

我有一个包含部分视图的视图,并且在提交视图时,部分视图中的数据不会发送到控制器。我明白,如果我使用编辑器模板,这应该可以工作,但我无法使用它,因为我需要从部分内部的主模型中获取数据。

我创建视图(简体):

@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; } 
} 

我控制器(我不会发布这一切,我可以马上告诉我视图模型不包含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> 

我的目的是在部分显示给用户,所有给定XmlFields和它们的值的列表,并允许他们从每个XmlField一个下拉列表中选择一个BusinessObjectField。然后我想把这个提交给IEnumerable<XmlSchemaField> MappedFields对象内的控制器。这可能吗?

+0

通常,可以提交包含部分视图的表单。没有看到1.你的控制器很难回答你的问题,2.什么样的类“XmlInputFieldModel”。你可以提供这个吗? – Nilzor

+0

此外,显示为部分视图生成的HTML将会有所帮助。为了你自己的利益,使用Fiddler来调试POST数据也是有帮助的 – Nilzor

+0

@Nilzor,我已经为你添加了缺失的类 – Mark

回答

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/

UPDATE

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

+1

只需添加到:将foreach循环更改为for-loop并使用old-school索引,而你会很好去。 – Nilzor

+0

@Amila非常感谢,我也一直在关注这篇文章,但是我必须错过一些最终的约束或者其他的东西,因为它还没有被传递给控制器​​。我已经使用我所做的更改更新了我的帖子。 – Mark

+0

'@ Html.Partial(“_ XmlFieldMapping”)'你没有将模型传递给partial。你应该传递类型为'CherwellXmlConnector.Models.XmlSchemaModelContainer'的对象。 – Amila