Acciones del controlador ASP.NET MVC que devuelven JSON o html parcial
Estoy intentando crear acciones de controlador que devolverán JSON o html parcial según un parámetro. ¿Cuál es la mejor manera de devolver el resultado a una página MVC de forma asincrónica?
En su método de acción, devuelva Json(objeto) para devolver JSON a su página.
public ActionResult SomeActionMethod() {
return Json(new {foo="bar", baz="Blech"});
}
Luego simplemente llame al método de acción usando Ajax. Puede utilizar uno de los métodos auxiliares de ViewPage, como
<%= Ajax.ActionLink("SomeActionMethod", new AjaxOptions {OnSuccess="somemethod"}) %>
SomeMethod sería un método de JavaScript que luego evalúa el objeto Json devuelto.
Si desea devolver una cadena simple, puede usar ContentResult:
public ActionResult SomeActionMethod() {
return Content("hello world!");
}
ContentResult devuelve de forma predeterminada un texto/sin formato como su tipo de contenido.
Esto es sobrecargable por lo que también puedes hacer:
return Content("<xml>This is poorly formatted xml.</xml>", "text/xml");
Creo que deberías considerar los AcceptTypes de la solicitud. Lo estoy usando en mi proyecto actual para devolver el tipo de contenido correcto de la siguiente manera.
Su acción en el controlador puede probarlo como en el objeto de solicitud
if (Request.AcceptTypes.Contains("text/html")) {
return View();
}
else if (Request.AcceptTypes.Contains("application/json"))
{
return Json( new { id=1, value="new" } );
}
else if (Request.AcceptTypes.Contains("application/xml") ||
Request.AcceptTypes.Contains("text/xml"))
{
//
}
Luego puede implementar el aspx de la vista para atender el caso de respuesta xhtml parcial.
Luego, en jQuery puedes recuperarlo pasando el parámetro de tipo como json:
$.get(url, null, function(data, textStatus) {
console.log('got %o with status %s', data, textStatus);
}, "json"); // or xml, html, script, json, jsonp or text
Otra buena forma de manejar datos JSON es utilizar la función JQuery getJSON. Puedes llamar al
public ActionResult SomeActionMethod(int id)
{
return Json(new {foo="bar", baz="Blech"});
}
Método del método jquery getJSON simplemente...
$.getJSON("../SomeActionMethod", { id: someId },
function(data) {
alert(data.foo);
alert(data.baz);
}
);
Encontré un par de problemas al implementar llamadas GET MVC ajax con JQuery que me causaron dolores de cabeza, así que comparto soluciones aquí.
- Asegúrese de incluir el tipo de datos "json" en la llamada ajax. Esto analizará automáticamente el objeto JSON devuelto (dado que el servidor devuelve un json válido).
- Incluir la
JsonRequestBehavior.AllowGet
; sin esto, MVC devolvía un error HTTP 500 (dataType: json
especificado en el cliente). - Agregue
cache: false
a la llamada $.ajax; de lo contrario, finalmente obtendrá respuestas HTTP 304 (en lugar de respuestas HTTP 200) y el servidor no procesará su solicitud. - Finalmente, el json distingue entre mayúsculas y minúsculas, por lo que la carcasa de los elementos debe coincidir en el lado del servidor y en el lado del cliente.
JQuery de muestra:
$.ajax({
type: 'get',
dataType: 'json',
cache: false,
url: '/MyController/MyMethod',
data: { keyid: 1, newval: 10 },
success: function (response, textStatus, jqXHR) {
alert(parseInt(response.oldval) + ' changed to ' + newval);
},
error: function(jqXHR, textStatus, errorThrown) {
alert('Error - ' + errorThrown);
}
});
Código MVC de muestra:
[HttpGet]
public ActionResult MyMethod(int keyid, int newval)
{
var oldval = 0;
using (var db = new MyContext())
{
var dbRecord = db.MyTable.Where(t => t.keyid == keyid).FirstOrDefault();
if (dbRecord != null)
{
oldval = dbRecord.TheValue;
dbRecord.TheValue = newval;
db.SaveChanges();
}
}
return Json(new { success = true, oldval = oldval},
JsonRequestBehavior.AllowGet);
}