167 votos

¿Cómo puedo publicar una matriz de cadenas a ASP.NET MVC controlador sin un formulario?

Voy a crear una pequeña aplicación para enseñarme ASP.NET MVC y JQuery, y una de las páginas se muestra una lista de elementos en el que algunos pueden ser seleccionados. A continuación, me gustaría que pulsar un botón y enviar una Lista (o algo equivalente) a mi controlador que contiene los identificadores de los elementos que se han seleccionado, usando JQuery Post de la función.

Me las arreglé para obtener un array con los identificadores de los elementos que fueron seleccionados, y ahora que quiero publicar. Una manera de hacer esto es tener un muñeco formulario en mi página, con un valor oculto, y, a continuación, establezca el valor oculto con los elementos seleccionados, y después de que forma; esto se ve crufty, aunque.

Hay un limpiador de manera de lograr esto mediante el envío de la matriz directamente al controlador? Yo he probado un par de cosas diferentes, pero parece que el controlador no puede asignar los datos que se reciben. Aquí está el código:

function generateList(selectedValues) {
   var s = {
      values: selectedValues //selectedValues is an array of string
   };
   $.post("/Home/GenerateList", $.toJSON(s), function() { alert("back") }, "json");
}

Y entonces mi Controlador se parece a este

public ActionResult GenerateList(List<string> values)
{
    //do something
}

Todas me las arreglé para conseguir un "null" en el parámetro de controlador de...

¿Algún consejo?

231voto

MrDustpan Puntos 2900

Modifiqué mi respuesta para incluir el código de una aplicación de prueba que hice.

Actualización: he actualizado el jQuery para establecer la 'tradicional' en true para que esto funcione otra vez (por la respuesta de @DustinDavis).

Primero el javascript:

function test()
{
    var stringArray = new Array();
    stringArray[0] = "item1";
    stringArray[1] = "item2";
    stringArray[2] = "item3";
    var postData = { values: stringArray };

    $.ajax({
        type: "POST",
        url: "/Home/SaveList",
        data: postData,
        success: function(data){
            alert(data.Result);
        },
        dataType: "json",
        traditional: true
    });
}

Y aquí está el código en mi clase de controlador:

public JsonResult SaveList(List<String> values)
{
    return Json(new { Result = String.Format("Fist item in list: '{0}'", values[0]) });
}

Cuando llamo a la función javascript, recibo una alerta diciendo "primero el artículo en la lista: 'item1'". Espero que esto ayude!

101voto

DustinDavis Puntos 7808

FYI: JQuery cambió la forma en que serializar datos post.

http://Forum.jQuery.com/topic/nested-param-Serialization

Tienes que establecer la 'Tradicional' en true, otro sabio

{ Values : ["1", "2", "3"] }

va a salir como

Values[]=1&Values[]=2&Values[]=3

En lugar de

Values=1&Values=2&Values=3

24voto

Evgeny Puntos 2765

Gracias a todos por las respuestas. Otra solución rápida será utilizar método jQuery.param con parámetro tradicional establecido en true para convertir el objeto JSON en cadena:

$.post("/your/url", $.param(yourJsonObject,true));

8voto

Craig Stuntz Puntos 95965

No publicar los datos como una matriz. Para enlazar a una lista, los pares clave/valor deben presentarse con el mismo valor para cada tecla.

No necesita una forma de hacerlo. Sólo necesitas una lista de pares clave/valor, que puede incluir en la llamada a $.post.

1voto

Mohsen Afshin Puntos 3643

Como ya os comentamos aquí ,

si desea pasar personalizado objeto JSON para MVC acción, a continuación, puede utilizar esta solución funciona como un encanto.

    public string GetData()
    {
        // InputStream contains the JSON object you've sent
        String jsonString = new StreamReader(this.Request.InputStream).ReadToEnd();

        // Deserialize it to a dictionary
        var dic = 
          Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<String, dynamic>>(jsonString);

        string result = "";

        result += dic["firstname"] + dic["lastname"];

        // You can even cast your object to their original type because of 'dynamic' keyword
        result += ", Age: " + (int)dic["age"];

        if ((bool)dic["married"])
            result += ", Married";


        return result;
    }

El beneficio real de esta solución es que no se requieren para definir una nueva clase para cada combinación de argumentos y a su lado, usted puede convertir sus objetos, a sus tipos originales fácilmente.

y puede utilizar un método auxiliar como este para facilitar su trabajo

public static Dictionary<string, dynamic> GetDic(HttpRequestBase request)
{
    String jsonString = new StreamReader(request.InputStream).ReadToEnd();
    return Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(jsonString);
}

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X