ViewModel的输入数组

时间:2014-03-21 16:58:20

标签: forms asp.net-mvc-4

我有一个ViewModel,其中一个元素是整数列表

public class Recurso
{
    [...]

    [Display(Name = "Clientes")]
    public List<int> Clientes { get; set; }
}

我希望从发布到此操作的表单中的隐藏输入数组中获取此值

[Authorize]
[HttpPost]
public ActionResult AdicionarRecurso(Recurso model)
{
    if (ModelState.IsValid)
    {
        ViewData["sucesso"] = Recursos.NovoRecurso(model);
    }

    return View(model);
}

在我的表格中,以及与我的模型的其他部分相对应的字段,我有类似的东西

[..]
<input type="hidden" name="Clientes[]" value="1"/>
<input type="hidden" name="Clientes[]" value="15"/>
<input type="hidden" name="Clientes[]" value="17"/>
[...]

我知道这是应该发布的(至少我是这样),因为如果记录表格,我会得到这个...&Clientes%5B%5D=1&Clientes%5B%5D=15&Clientes%5B%5D=17

但是,当模型中的Clientes进行调试时仍然是NULL

我如何实现这一目标?

修改 这里要求的是我的视图中生成表单的部分,隐藏的数组字段是动态创建的,所以我也有这个javascript:

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "recursoform", enctype = "multipart/form-data" }))
                        {
                            <div class="form-errors">
                                @Html.ValidationSummary(true)
                                <div>@Html.ValidationMessageFor(model => model.Titulo)</div>
                                <div>@Html.ValidationMessageFor(model => model.Descricao)</div>
                                <div>@Html.ValidationMessageFor(model => model.Ficheiro)</div>
                            </div>

                            <div class="clear"></div>

                            <div class="input-prepend">
                                <label for="IDTipoRecurso" class="span3">Tipo de Recurso</label>
                                <select class="span5" id="IDTipoRecurso">
                                    @foreach (var tipoRecurso in (List<SMOnline.Models.TiposRecursos>)ViewBag.tiposRecursos)
                                    {
                                        <option value="@tipoRecurso.IDTipoRecurso">@tipoRecurso.Descricao</option>
                                    }
                                </select>
                            </div>

                            <div class="input-prepend">
                                @Html.LabelFor(model => model.Titulo, new { @class = "span3" })
                                @Html.TextBoxFor(model => model.Titulo, new { @class = "span12", placeholder = "Titulo" })
                            </div>
                            <div class="input-prepend">
                                @Html.LabelFor(model => model.Descricao, new { @class = "span3" })
                                @Html.TextAreaFor(model => model.Descricao, new { @class = "span12", placeholder = "Descrição" })
                            </div>

                            <div class="input-prepend">
                                @Html.LabelFor(model => model.Ficheiro, new { @class = "span3" })
                                <a href="javascrip:;" class="btn btn-large btn-alert span3" style="margin-left: 0;" onclick="getFile()">
                                    Carregar Ficheiro!
                                    <i class="icon-upload icon-large"></i>
                                </a>
                                <label style="padding: 10px 0 0 0;">&nbsp;<i class="icon-ok icon-large" id="fileselected" style="font-size: 30px; color: #090; display: none;"></i></label>
                                <div style='height: 0px;width:0px; overflow:hidden;'>@Html.TextBoxFor(model => model.Ficheiro, null, new { type = "file", @class = "upfile" })</div>
                            </div>

                            <div class="clear">&nbsp;</div>

                            <div class="input-prepend">
                                <label for="Associacao" class="span3">Disponível para</label>
                                <select class="span5" id="Associacao">
                                    <option value="1">Todos os clientes</option>
                                    <option value="2">Tipos de clientes especificos</option>
                                    <option value="3">Clientes especificos</option>
                                </select>

                                <div class="clear"></div>
                            </div>

                            <div class="span3"></div>
                            <div id="clientesEspecificos" class="clientes">
                                <div class="span5" style="margin-left: 0;">
                                    <input type="text" value="" placeholder="Filtrar" id="box" class="span5" style="margin-left: 0;" />
                                    <ul class="navList span5" style="margin-left: 0;">
                                    @foreach (var cliente in (List<SMOnline.Models.Entidades>)ViewBag.clientes)
                                    {
                                        <li><a href="javascript:void(0);" id="cliente-@cliente.IDEntidade-@cliente.UserName" class="addCliente" title="adicionar cliente à listagem">@Html.Raw(cliente.UserName)</a></li>
                                        <!--<input type="checkbox" name="Clientes[]" id="cliente-@cliente.IDEntidade" value="@cliente.IDEntidade" class="pull-left" />
                                        <label for="cliente-@cliente.IDEntidade">&nbsp;@Html.Raw(cliente.UserName)</label>-->
                                    }
                                    </ul>
                                </div>
                                <div class="span5">
                                    <div><strong>Clientes Selecionados</strong></div>
                                    <div id="clientesSelect">

                                    </div>
                                </div>
                            </div>
                            <div id="tiposClientes" class="clientes span5">
                                @foreach (var tipo in (List<SMOnline.Models.TiposClientes>)ViewBag.tiposClientes)
                                {
                                    <input type="checkbox" name="TiposClientes[]" id="tipoCliente-@tipo.IDTipoCliente" value="@tipo.IDTipoCliente" class="pull-left" />
                                    <label for="cliente-@tipo.IDTipoCliente">&nbsp;@Html.Raw(tipo.Descricao)</label>
                                }
                            </div>
                            <div class="clear"></div>

                            <div class="box-footer">
                                <a href="@Url.Action("Index", "Admin")" class="btn btn-danger">
                                    <i class="icon-remove"></i>
                                    Cancelar
                                </a>

                                <button type="submit" class="btn btn-primary">
                                    <i class="icon-ok"></i>
                                    Gravar
                                </button>
                            </div>
                        }

的javascript:

$('.addCliente').click(function () {
            var splitId = this.id.split("-");

            $(this).fadeOut('slow');

            var clienteAdicionado = '<div class="removeCliente" id="removeCliente-' + splitId[1] + '-' + splitId[2] + '">' + splitId[2] + '</div>';
            clienteAdicionado += '<input type="hidden" name="Clientes[1]" value="' + splitId[1] + '"/>';

            $('#clientesSelect').append(clienteAdicionado);

            removeCliente();
        });

function removeCliente() {
        $('.removeCliente').click(function () {
            var splitId = this.id.split("-");

            $(this).fadeOut('slow', function () { $(this).remove(); });

            $('#cliente-' + splitId[1] + '-' + splitId[2]).fadeIn();
        });
    }

和最初的行动:

[Authorize]
    public ActionResult AdicionarRecurso()
    {
        Recurso model = new Recurso();

        string email = this.GetEmailFromCookie();
        string key = Admin.GetUserKey(email);

        ViewData["clientes"] = Admin.GetAllClientes(email);
        ViewData["tiposClientes"] = Admin.GetTiposClientes(email);
        ViewData["tiposRecursos"] = Recursos.GetTiposRecursos(key);

        return View(model);
    }

3 个答案:

答案 0 :(得分:1)

您显示的视图输出错误:

<input type="hidden" name="Clientes[]" value="1"/>
<input type="hidden" name="Clientes[]" value="15"/>
<input type="hidden" name="Clientes[]" value="17"/>

它应该是这样的:

<input type="hidden" name="Clientes[0]" value="1"/>
<input type="hidden" name="Clientes[1]" value="15"/>
<input type="hidden" name="Clientes[2]" value="17"/>

这就是动作帖

中模型中列表为空的原因

在您的初步操作中,请执行以下操作:

[Authorize]
    public ActionResult AdicionarRecurso()
    {
        Recurso model = new Recurso();

        model.Clientes  = new List<int>();

        string email = this.GetEmailFromCookie();
        string key = Admin.GetUserKey(email);

        ViewData["clientes"] = Admin.GetAllClientes(email);
        ViewData["tiposClientes"] = Admin.GetTiposClientes(email);
        ViewData["tiposRecursos"] = Recursos.GetTiposRecursos(key);

        return View(model);
    }

答案 1 :(得分:1)

因此,在将模型发送到视图之前,我需要在初始操作上定义model.Clientes = new List<int>();

对于视图中的表单,结果是如果我不在name="Clientes[]"name="Clientes[1]"添加括号,而只是用name="Clientes"

如:

<input type="hidden" name="Clientes" value="1"/>
<input type="hidden" name="Clientes" value="15"/>
<input type="hidden" name="Clientes" value="17"/>

默认模型绑定器会看到具有相同名称的所有这些名称/值对,并将其转换为具有键int的集合,然后与操作方法的ints参数进行匹配。

这是引导我朝正确方向前进的article

答案 2 :(得分:0)

首先我认为你没有在你的Action上传递模型对象,你传递的是你的模型,你的模型将为null。我想可能会在操作中通过Request检索你的int,然后在正确验证之后你可以用这个字段(来自请求)创建你的模型并将它传递给视图。

HttpContext.Current.Request.QueryString["somekey"]