MVC4将ViewModel发送到Controller

时间:2016-01-21 14:29:10

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

我正在尝试将包含两个List的ViewModel传递给Controller,但我在控制器Action中得到null结果。我一直在网上搜索答案,但我似乎无法找到可以使用的东西。

我已经尝试按照this post让它工作但我被卡住了。

这是我的ViewModel:

public class ItemsConciliacionManualViewModel
{
    public string TituloOrigen1 { get; set; }
    public string TituloOrigen2 { get; set; }
    public List<ConciliacionItem> noConciliadasOrigen1 { get; set; }
    public List<ConciliacionItem> noConciliadasOrigen2 { get; set; }
}

这是我的观点:

@model RECON.DAL.ViewModels.ItemsConciliacionManualViewModel
@using RECON.Resources

@using (Html.BeginForm("GrabarConciliacionManual", "ConciliacionItem", FormMethod.Post, new { ListaAConciliarManual = Model }))
{
    @Html.HiddenFor(x => x.noConciliadasOrigen1)
    @Html.HiddenFor(x => x.noConciliadasOrigen2)

    <div class="col-md-10 col-md-offset-1">
        <h3>
            @Html.DisplayFor(model => model.TituloOrigen1)
        </h3>
        @{
    Html.RenderPartial("_ListaItemsAConciliarManual", Model.noConciliadasOrigen1);
        }
    </div>

    <div class="col-md-10 col-md-offset-1">
        <h3>
            @Html.DisplayFor(model => model.TituloOrigen2)
        </h3>
        @{
    Html.RenderPartial("_ListaItemsAConciliarManual", Model.noConciliadasOrigen2);
        }
    </div>

    <div class="col-md-3 col-md-offset-9">
        <br />
        <button type="submit" id="btnConciliarManual" class="btn btn-primary botonera">
            <span class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></span>
        </button>

    </div>

}

这是我的控制者:

    public ActionResult GrabarConciliacionManual(ItemsConciliacionManualViewModel ListaAConciliarManual, string motivo)
    {
    }

我要处理的是同一种模型的两个列表,如果我只将一个List传递给动作(之前我已经完成了),它实际上有效,但由于可用性的目的,我必须同时显示两个列表分开。

我不需要ViewModel的字符串,只需要列表。其他参数“string motivo”工作正常。

提前致谢。

编辑:添加了部分视图代码:

@model List<RECON.DAL.Models.ConciliacionItem>
@using RECON.Resources
@using GridMvc.Html
@using RECON.DAL.Models

@{
    IEnumerable<ConciliacionItemDiseno> conciliacionItemDiseno = new List<ConciliacionItemDiseno>();
    var itemDiseno = (IEnumerable<ConciliacionItemDiseno>)ViewBag.ConciliacionItemDisenos;
}

@Html.Grid(Model).Columns(columns =>
                              {
                                  columns.Add(foo => foo.ClaveConciliacion, true).Titled("ClaveConciliacion");

                              columns.Add(foo => foo.Id).Titled("Id");

                              columns.Add(foo => foo.OrigenDescripcion).Titled("Origen");

                              // VARCHARS

                              conciliacionItemDiseno = itemDiseno.Where(x => x.Campo == "Varchar1");
                              if (conciliacionItemDiseno.Any())
                              {
                                  columns.Add(foo => foo.Varchar1)
                                                  .Titled((conciliacionItemDiseno.FirstOrDefault(x => x.Diseno.Codigo == "Titulo") != null ? conciliacionItemDiseno.FirstOrDefault(x => x.Diseno.Codigo == "Titulo").Valor : string.Empty))
                                                  .Css((conciliacionItemDiseno.FirstOrDefault(x => x.Diseno.Codigo == "Align") != null) ? ((conciliacionItemDiseno.FirstOrDefault(x => x.Diseno.Codigo == "Align").Valor == "C") ? "text-center" : (conciliacionItemDiseno.FirstOrDefault(x => x.Diseno.Codigo == "Align").Valor == "R") ? "text-right" : "text-left") : string.Empty)
                                                  .SetWidth((conciliacionItemDiseno.FirstOrDefault(x => x.Diseno.Codigo == "Width") != null) ? conciliacionItemDiseno.FirstOrDefault(x => x.Diseno.Codigo == "Width").Valor : string.Empty);
                              })

4 个答案:

答案 0 :(得分:1)

您无法将隐藏的输入(或任何表单控件)绑定到复杂对象的集合。如果你检查

生成的html
@Html.HiddenFor(x => x.noConciliadasOrigen1)

它会像

<input type="hidden" name="noConciliadasOrigen1" value="System.Collection.Generic.List[ConciliacionItem]" />

DefaultModelBinder无法设置

model.noConciliadasOrigen1 = "System.Collection.Generic.List[ConciliacionItem]";

因此模型绑定失败,属性为null

如果您确实要发布集合中所有属性的所有值,则需要使用for循环或EditorTemplate来表示ConciliacionItem类型。但你似乎没有编辑你的集合的任何属性(实际上你似乎没有从你所显示的代码编辑任何东西)所以它不清楚为什么你会想要通过生成大量的额外HTML来降低性能并将其全部保持不变。假设您正在编辑某些内容,如果由于ModelState无效而需要返回视图,则只需重新填充这些集合。

您还需要从new { ListaAConciliarManual = Model }方法中删除BeginForm()。再次,如果您检查生成的html,您将理解为什么它永远不会起作用。

答案 1 :(得分:0)

改变这个:

@using (Html.BeginForm("GrabarConciliacionManual", "ConciliacionItem", FormMethod.Post, new { ListaAConciliarManual = Model }))

到此:

@using (Html.BeginForm("GrabarConciliacionManual", "ConciliacionItem", FormMethod.Post))

答案 2 :(得分:0)

是否可以向ItemsConciliacionManualViewModel添加构造函数,并在该构造函数中初始化两个列表。

这样的事情:

public class ItemsConciliacionManualViewModel
{
    public ItemsConciliacionManualViewModel()
    {
        this.noConciliadasOrigen1 = new List<ConciliacionItem>();
        this.noConciliadasOrigen2 = new List<ConciliacionItem>();
    }

    public string TituloOrigen1 { get; set; }
    public string TituloOrigen2 { get; set; }
    public List<ConciliacionItem> noConciliadasOrigen1 { get; set; }
    public List<ConciliacionItem> noConciliadasOrigen2 { get; set; }
}

答案 3 :(得分:-1)

我最终解决了我的问题,将其分成几部分:由于我需要发布一个包含每个可用对象的List,我所做的就是:

1)我创建了3个列表,1个发送到视图,2个用于演示。一旦我填写了我需要发送到视图的集合,我填充了另外2个,然后将它们传递给2个ViewBags视图。

2)在视图中,我用部分ViewBag的内容填充部分视图进行显示,但只保留&#34; working&#34;列表考虑。

3)控制器只接收&#34;工作&#34;列表,它的工作就像它应该的那样。