El formulario MVC3 serializado con la colección JSon está vacío con Ajax Post

Estoy intentando devolver un objeto con una propiedad que es una colección de objetos, pero cuando uso el formulario serializado como atributo de datos en mi publicación de Ajax, la colección está vacía (nula). ¿Es esta la forma incorrecta de devolver un objeto que contiene una lista como propiedad o hay algo simple que estoy pasando por alto? Cuando entro en la acción del controlador, puedo ver que tengo el atributo Holder.Id poblado pero MyList está vacío.

He intentado hacer contentType: 'application/json' sin ayuda. Me gustaría tener el objeto completo como carga útil para la publicación de Ajax en lugar de cada elemento individual de la colección. Al llamar a Ajax con cada elemento individual, funciona y es posible que tenga que usar ese método.

Objetos POCO simples:

public class Holder
{
    public int Id { get; set; }
    public List<Contained> MyList { get; set; }
}

public class Contained
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Métodos del controlador:

    [HttpGet]
    public ActionResult Edit()
    {
        List<Contained> contained = new List<Contained>();
        contained.Add(new Contained{Id=123, Name="123Name"});
        contained.Add(new Contained{Id=456, Name="456Name"});
        return View(new Holder { Id = 1001, MyList = contained });

    }

    [HttpPost]
    public JsonResult Edit(Holder holder)
    {
        return Json("Succeeded");
    }

Marcado HTML:

@model Compeat.MyMvcApp.Controllers.Holder
@{
     ViewBag.Title = "Edit";
}
<script type="text/javascript">
$(document).ready(function () {
    $("#btnAdd").click(function () {
        var coll = [];
        var newName = $("#txtAddNameToList").val();
        coll.push(newContainedJson(999, newName));
        $("#MyList").val(coll);
        var frmElems = $("form").serialize();
        console.log(coll);
        $.ajax({
            type: "POST",
            data: coll,
            url: "Edit",
            dataType: "json",
            success: function (data) { alert('worked!'); },
            error: function (data) {
                alert('error: ' + data.responseText);
            }
        });
    });

    function newContainedJson(id, name) {
        return { "Id": id , "Name": name };
    }
});
</script>
<ul>
@foreach (var o in Model.MyList)
{
    <li>@o.Name</li>
}
</ul>
@{ using (Html.BeginForm())
   {
@Html.HiddenFor(e => e.Id)
<input type="hidden" name="MyList" id="MyList" value="" />
<input type="text" id="txtAddNameToList" name="txtAddNameToList" />
<input type="button" id="btnAdd" value="Add Name" />
}}

preguntado el 22 de mayo de 12 a las 15:05

1 Respuestas

Use el JQuery a continuación y establezca un punto de interrupción en su controlador.

 $("#btnAdd").click(function () {



        var data = {}
        data.Id = 9;
        data.MyList = [];
        data.MyList.push({ 'Id': 99, 'Name': 'Dude' });
        data.MyList.push({ 'Id': 990, 'Name': 'Dude2' });

        $.ajax({
            type: "POST",
            data: JSON.stringify(data),
            url: "Home/Index",
            dataType: "json",
            contentType: 'application/json',
            success: function (data) { alert('worked!'); },
            error: function (data) {

            }
        });
    });

contestado el 22 de mayo de 12 a las 18:05

Esto definitivamente es útil. Lo que esperaba averiguar es si es una buena o mala práctica insertar un valor como este en un campo oculto y serializar el formulario. Sin embargo, parece que la ruta puede estar llena de peligros. ¿Alguna idea sobre esa técnica? Me gustaría evitar tener que mantener JS que conozca la estructura del objeto en el back-end. - likestoski

Creo que me estoy perdiendo algo, ¿por qué estás insertando datos en el elemento de entrada oculto? Si está publicando de nuevo en el controlador con una llamada AJAX, no necesita usar un formulario. Entonces no habría necesidad de serializar nada. - ryand.johnson

Marcando como respuesta ya que por ahora esto me lleva en la dirección correcta, gracias @Ryand.Johnson - likestoski

Principalmente para el caso en que JS está deshabilitado. - likestoski

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.