jquery - por - ¿Cómo puedo enviar una matriz de cadenas a Controlador MVC de ASP.NET sin un formulario?
llamar actionresult desde javascript (9)
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.
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 el arreglo 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 ve así
public ActionResult GenerateList(List<string> values)
{
//do something
}
Todo lo que logré obtener es un "nulo" en el parámetro del controlador ...
¿Algun consejo?
Como discutí here ,
si desea pasar un objeto JSON personalizado a una acción MVC, puede usar 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 necesita definir una nueva clase para cada combinación de argumentos y, además de eso, puede convertir los objetos a sus tipos originales fácilmente.
y puedes usar un método de ayuda como este para facilitar tu 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);
}
En .NET4.5
, MVC 5
Javascript:
objeto en JS:
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'',
});
});
DO#
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:
Espero que esto te ahorre algo de tiempo.
FYI: JQuery cambió la forma en que serializan los datos de la publicación.
http://forum.jquery.com/topic/nested-param-serialization
Tienes que establecer la configuración ''Tradicional'' en verdadero, de otra manera
{ Values : ["1", "2", "3"] }
saldrá como
Values[]=1&Values[]=2&Values[]=3
en lugar de
Values=1&Values=2&Values=3
Gracias a todos por las respuestas. Otra solución rápida será utilizar el método jQuery.param con el parámetro tradicional establecido en true para convertir el objeto JSON en cadena:
$.post("/your/url", $.param(yourJsonObject,true));
La respuesta me ayudó mucho en mi situación, así que gracias por eso. Sin embargo, para futuras referencias las personas deberían vincularse a un modelo y luego validarlo. Esta publicación de Phil Haack describe esto para MVC 2. http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx
Espero que esto ayude a alguien.
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 de controlador:
public JsonResult SaveList(List<String> values)
{
return Json(new { Result = String.Format("Fist item in list: ''{0}''", values[0]) });
}
Cuando llamo a esa función javascript, recibo una alerta que dice "Primer elemento en la lista: ''elemento1''". ¡Espero que esto ayude!
No publique los datos como una matriz. Para enlazar a una lista, los pares de clave / valor deben enviarse con el mismo valor para cada clave.
No deberías necesitar un formulario para hacer esto. Solo necesita una lista de pares clave / valor, que puede incluir en la llamada a $ .post.
Otra implementación que también está trabajando con la lista de objetos, no solo 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 ''selectedValues'' es Array of Objects.
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)
});
}
Puede configurar el parámetro global con
jQuery.ajaxSettings.traditional = true;