2008-11-21 22 views
164

Estoy creando una pequeña aplicación para enseñarme ASP.NET MVC y JQuery, y una de las páginas es una lista de elementos en los que se pueden seleccionar algunos. Luego me gustaría presionar un botón y enviar una Lista (o algo equivalente) a mi controlador que contenga los ID de los ítems que fueron seleccionados, usando la función Publicar de JQuery.¿Cómo puedo publicar una matriz de cadenas en el controlador MVC de ASP.NET sin un formulario?

Logré obtener una matriz con los identificadores de los elementos que se seleccionaron, y ahora quiero publicar eso. Una forma de hacerlo es tener una forma ficticia en mi página, con un valor oculto, y luego establecer el valor oculto con los elementos seleccionados, y publicar ese formulario; sin embargo, esto parece muy complicado.

¿Hay alguna manera más clara de lograr esto, enviando la matriz directamente al controlador? He intentado algunas cosas diferentes, pero parece que el controlador no puede mapear los datos que está recibiendo. Aquí está el código hasta ahora:

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 esta

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

todo lo que pude conseguir es un "nulo" en los parámetros de regulación ...

Algún consejo ?

+0

Aunque, puede acceder a los mismos datos mediante el uso de 'Solicitud [ "valores []"]' – Tocco

Respuesta

227

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

Actualización: He actualizado jQuery para establecer la configuración 'tradicional' en verdadero, así que esto funcionará nuevamente (según 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 controlador:

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

Cuando llamo a que la función del Javascript, me sale un aviso que dice "Primer elemento de la lista: 'Artículo 1'". ¡Espero que esto ayude!

+2

Es bueno que haya encontrado esta respuesta, ahora puedo enviar una matriz de Guid's y Acción los recibe a List . Gracias – Tx3

+38

Hay dos cosas importantes a tener en cuenta aquí. 1) dataType: "json" 2). Traditional: true. Sin ellos string array no se pasará a los métodos de acción – Thanigainathan

+0

Tenga en cuenta que 'dataType: 'JSON'' hace que jQuery intente analizar la respuesta como JSON, y generará un error si no es JSON válido – sennett

98

FYI: JQuery cambió la forma en que serializan los datos de la publicación.

http://forum.jquery.com/topic/nested-param-serialization

Hay que establecer la configuración de 'tradicional' de verdad, de otra forma

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

saldrá como

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

en lugar de

Values=1&Values=2&Values=3 
+8

Esto es algo que me hizo revolver la cabeza por un tiempo. establecer '$ .ajax ({..., traditional: true});' ayudará a volver a la serialización tradicional. –

+0

Necesitaba esto para que una ruta ASP.NET MVC consumiera correctamente una matriz js simple de valores de cadena. – BrandonG

+0

Tu respuesta es realmente útil. Tengo la misma situación pero está con 'ints'. Cuando uso 'traditional: true', funciona, tu respuesta y tu enlace explican el * por qué * de él. También funciona cuando uso 'type:" POST "', sin usar 'traditional: true'. ¿Porqué es eso? ¿Podrías por favor dar más detalles? FYI estoy usando Asp.Net Mvc. – barnes

22

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

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

Funciona bien y se adapta perfectamente a mí ya que estoy usando $ .post() en lugar de $ .ajax(). Gracias ! – AFract

1

Como ya os comentamos here,

si quieres pasa el objeto JSON personalizado a la acción MVC y luego puedes usar esta solución, funciona como un amuleto.

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 requiere definir una nueva clase para cada combinación de argumentos y al lado de eso, puede emitir sus objetos a sus tipos originales fácilmente.

y se puede utilizar un método de ayuda 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); 
} 
4

En .NET4.5, MVC 5

Javascript:

objeto en JS: enter image description here

mecanismo que publica.

$('.button-green-large').click(function() { 
     $.ajax({ 
      url: 'Quote', 
      type: "POST", 
      dataType: "json", 
      data: JSON.stringify(document.selectedProduct), 
      contentType: 'application/json; charset=utf-8', 
     }); 
    }); 

C#

Objetos:

public class WillsQuoteViewModel 
{ 
    public string Product { get; set; } 

    public List<ClaimedFee> ClaimedFees { get; set; } 
} 

public partial class ClaimedFee //Generated by EF6 
{ 
    public long Id { get; set; } 
    public long JourneyId { get; set; } 
    public string Title { get; set; } 
    public decimal Net { get; set; } 
    public decimal Vat { get; set; } 
    public string Type { get; set; } 

    public virtual Journey Journey { get; set; } 
} 

controlador:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Quote(WillsQuoteViewModel data) 
{ 
.... 
} 

objeto recibido:

enter image description here

Espero que esto te ahorre algo de tiempo.

3

Otra aplicación que también está trabajando con la lista de objetos, no sólo cadenas:

JS:

var postData = {}; 
postData[values] = selectedValues ; 

$.ajax({ 
    url: "/Home/SaveList", 
    type: "POST", 
    data: JSON.stringify(postData), 
    dataType: "json", 
    contentType: "application/json; charset=utf-8", 
    success: function(data){ 
     alert(data.Result); 
    } 
}); 

Suponiendo que '' es selectedValues ​​matriz de objetos.

En el controlador, el parámetro es una lista de los ViewModels correspondientes.

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

Puede configurar el parámetro global con

jQuery.ajaxSettings.traditional = true; 
Cuestiones relacionadas