J'essaie de créer des actions de contrôleur qui renverront soit du JSON, soit du code HTML partiel en fonction d'un paramètre. Quel est le meilleur moyen de renvoyer le résultat à une page MVC de manière asynchrone?
Dans votre méthode d'action, renvoyez Json (objet) pour renvoyer JSON à votre page.
public ActionResult SomeActionMethod() {
return Json(new {foo="bar", baz="Blech"});
}
Ensuite, appelez simplement la méthode d'action en utilisant Ajax. Vous pouvez utiliser l’une des méthodes d’aide de ViewPage telles que
<%= Ajax.ActionLink("SomeActionMethod", new AjaxOptions {OnSuccess="somemethod"}) %>
SomeMethod serait une méthode javascript qui évalue ensuite l'objet Json renvoyé.
Si vous voulez renvoyer une chaîne simple, vous pouvez simplement utiliser le ContentResult:
public ActionResult SomeActionMethod() {
return Content("hello world!");
}
ContentResult renvoie par défaut un text/plain en tant que contentType.
C’est surchargeable alors vous pouvez aussi faire:
return Content("<xml>This is poorly formatted xml.</xml>", "text/xml");
Je pense que vous devriez considérer les types AcceptTypes de la demande. Je l'utilise dans mon projet actuel pour renvoyer le type de contenu correct comme suit.
Votre action sur le contrôleur peut le tester comme sur l'objet de requête
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"))
{
//
}
Vous pouvez ensuite implémenter l'aspx de la vue pour gérer le cas de réponse partiel xhtml.
Ensuite, dans jQuery, vous pouvez le récupérer en passant le paramètre type en tant que 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
J'espère que cela aide James
Une autre façon de gérer les données JSON consiste à utiliser la fonction getJSON de JQuery. Vous pouvez appeler le
public ActionResult SomeActionMethod(int id)
{
return Json(new {foo="bar", baz="Blech"});
}
Méthode de la méthode getJSON jquery par simple ...
$.getJSON("../SomeActionMethod", { id: someId },
function(data) {
alert(data.foo);
alert(data.baz);
}
);
J'ai trouvé quelques problèmes lors de la mise en œuvre d'appels MVC ajax GET avec JQuery qui me causaient des maux de tête, alors je ne partage pas les solutions.
JsonRequestBehavior.AllowGet
; sans cela, MVC renvoyait une erreur HTTP 500 (avec dataType: json
spécifié sur le client).cache: false
à l'appel $ .ajax, sinon vous obtiendrez des réponses HTTP 304 (au lieu des réponses HTTP 200) et le serveur ne traitera pas votre demande.Exemple de JQuery:
$.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);
}
});
Exemple de code MVC:
[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);
}
Pour répondre à l’autre moitié de la question, vous pouvez appeler:
return PartialView("viewname");
lorsque vous souhaitez renvoyer un code HTML partiel. Vous devrez juste trouver un moyen de décider si la demande utilise JSON ou HTML, éventuellement sur la base d'un élément/paramètre d'URL.
Solution alternative avec framework incoding
Retour action json
Manette
[HttpGet]
public ActionResult SomeActionMethod()
{
return IncJson(new SomeVm(){Id = 1,Name ="Inc"});
}
Page de rasoir
@using (var template = Html.Incoding().ScriptTemplate<SomeVm>("tmplId"))
{
using (var each = template.ForEach())
{
<span> Id: @each.For(r=>r.Id) Name: @each.For(r=>r.Name)</span>
}
}
@(Html.When(JqueryBind.InitIncoding)
.Do()
.AjaxGet(Url.Action("SomeActionMethod","SomeContoller"))
.OnSuccess(dsl => dsl.Self().Core()
.Insert
.WithTemplate(Selector.Jquery.Id("tmplId"))
.Html())
.AsHtmlAttributes()
.ToDiv())
Retour d'action html
Manette
[HttpGet]
public ActionResult SomeActionMethod()
{
return IncView();
}
Page de rasoir
@(Html.When(JqueryBind.InitIncoding)
.Do()
.AjaxGet(Url.Action("SomeActionMethod","SomeContoller"))
.OnSuccess(dsl => dsl.Self().Core().Insert.Html())
.AsHtmlAttributes()
.ToDiv())
Vous voudrez peut-être jeter un coup d'œil à cet article très utile qui couvre très bien ce sujet!
J'ai pensé que cela pourrait aider les personnes à la recherche d'une solution satisfaisante à ce problème.
http://weblogs.asp.net/rashid/archive/2009/04/15/adaptive-rendering-in-asp-net-mvc.aspx
Pour les personnes qui ont migré vers MVC 3, la procédure est simple Utiliser MVC3 et Json
PartialViewResult et JSONReuslt héritent de la classe de base ActionResult. Ainsi, si le type de retour est décidé de manière dynamique, déclarez la sortie de la méthode sous forme ActionResult.
public ActionResult DynamicReturnType(string parameter)
{
if (parameter == "JSON")
return Json("<JSON>", JsonRequestBehavior.AllowGet);
else if (parameter == "PartialView")
return PartialView("<ViewName>");
else
return null;
}
public ActionResult GetExcelColumn()
{
List<string> lstAppendColumn = new List<string>();
lstAppendColumn.Add("First");
lstAppendColumn.Add("Second");
lstAppendColumn.Add("Third");
return Json(new { lstAppendColumn = lstAppendColumn, Status = "Success" }, JsonRequestBehavior.AllowGet);
}
}
Approche flexible pour produire différentes sorties en fonction de la demande
public class AuctionsController : Controller
{
public ActionResult Auction(long id)
{
var db = new DataContext();
var auction = db.Auctions.Find(id);
// Respond to AJAX requests
if (Request.IsAjaxRequest())
return PartialView("Auction", auction);
// Respond to JSON requests
if (Request.IsJsonRequest())
return Json(auction);
// Default to a "normal" view with layout
return View("Auction", auction);
}
}
La méthode Request.IsAjaxRequest()
est assez simple: elle vérifie simplement si la requête entrante est dans les en-têtes HTTP pour voir si la valeur de l'en-tête X-Requested-With est XMLHttpRequest
, qui est automatiquement ajoutée par la plupart des navigateurs et des frameworks AJAX.
Méthode d'extension personnalisée pour vérifier si la demande concerne json ou non, de sorte que nous puissions l'appeler de n'importe où, tout comme la méthode d'extension Request.IsAjaxRequest ():
using System;
using System.Web;
public static class JsonRequestExtensions
{
public static bool IsJsonRequest(this HttpRequestBase request)
{
return string.Equals(request["format"], "json");
}
}