【问题标题】:MVC4 Send ViewModel to ControllerMVC4 将 ViewModel 发送到控制器
【发布时间】:2016-03-22 06:57:10
【问题描述】:

我正在尝试将包含两个列表的 ViewModel 传递给控制器​​,但我在控制器操作中得到空结果。我一直在网上搜索答案,但似乎找不到我可以使用的东西。

我已尝试根据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)
    {
    }

我要处理的是同一种模型的两个列表,如果我只将一个列表传递给操作(我以前做过),这实际上是有效的,但出于可用性目的,我必须同时展示这两个列表列表分开。

我不需要 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);
                              })

【问题讨论】:

  • 您能否从 _ListaItemsAConciliarManual 发布有用的 sn-ps - 部分视图,谢谢
  • 是的,我就是这么做的。谢谢。
  • 嗯,你在视图中做的太多了,他们在做过滤等等。从视图模型中分离你的集合可能是......
  • 我必须在这个项目中使用 Mvc.Grid link,所以对此我别无选择。尽管如此,我发现如果我发送到控制器 2 List 而不是 viewModel 并且在部分视图中我使用标准 html 而不是说网格,我会收到列表。

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


【解决方案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 for typeof ConciliacionItem。但是您似乎没有编辑您的集合的任何属性(实际上您似乎根本没有从您显示的代码中编辑任何内容)所以不清楚为什么您要通过生成大量额外的 html 来降低性能并将其全部原封不动地发布。假设您正在编辑某些内容,如果您因为 ModelState 无效而需要返回视图,那么只需重新填充这些集合即可。

您还需要从您的 BeginForm() 方法中删除 new { ListaAConciliarManual = Model }。同样,如果您检查生成的 html,您就会明白为什么这永远行不通。

【讨论】:

  • 这真的很说明问题。非常感谢!
【解决方案2】:

改变这个:

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

到这里:

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

【讨论】:

  • 我在问之前已经完成了,仍然得到空值。感谢您的意见。
【解决方案3】:

您能否向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; }
}

【讨论】:

  • 我可以尝试,但目的是什么?对不起,我是 C# OOP 的初学者。谢谢。
  • 将您拥有的模型 ItemsConciliacionManualViewModel 替换为我建议的具有构造函数 List 初始化的模型
【解决方案4】:

我最终解决了我的问题,将其分成几部分:因为我需要发布一个包含每个可用对象的列表,所以我所做的是:

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

2) 在视图中,我用两个 ViewBag 的内容填充部分视图以进行显示,但只考虑“工作”列表。

3) 控制器只接收“工作”列表,并按预期工作。

【讨论】:

    猜你喜欢
    • 2012-12-16
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-05
    • 1970-01-01
    相关资源
    最近更新 更多