2008-10-22 26 views

risposta

443

Nel metodo di azione, restituire Json (oggetto) per restituire JSON alla pagina.

public ActionResult SomeActionMethod() { 
    return Json(new {foo="bar", baz="Blech"}); 
} 

Quindi basta chiamare il metodo di azione utilizzando Ajax. È possibile utilizzare uno dei metodi helper dal ViewPage come

<%= Ajax.ActionLink("SomeActionMethod", new AjaxOptions {OnSuccess="somemethod"}) %> 

SomeMethod sarebbe un metodo JavaScript che valuta quindi l'oggetto JSON restituito.

Se si desidera restituire una stringa semplice, si può semplicemente utilizzare il ContentResult:

public ActionResult SomeActionMethod() { 
    return Content("hello world!"); 
} 

ContentResult di default restituisce un text/plain come contentType.
Questo è sovraccaricabile modo da poter fare:

return Content("<xml>This is poorly formatted xml.</xml>", "text/xml"); 
+4

dispiace phil! questo in realtà non risponde alla domanda lo fa? è sicuramente utile, ma come dice Brad devi scoprire in qualche modo cosa stanno chiedendo e restituire il risultato di conseguenza. –

+0

vedi la mia domanda in qualche modo correlata (beh quella che mi ha portato qui) su http://stackoverflow.com/questions/482363/should-my-mvc-controller-really-know-about-json –

+9

se trovi una risposta, collegalo alla domanda stessa. Inoltre non penso di controllare questo dato che la risposta è la cosa giusta. – Cherian

71

Un altro bel modo di trattare con i dati JSON utilizza la funzione di JQuery getJSON. È possibile chiamare il

public ActionResult SomeActionMethod(int id) 
{ 
    return Json(new {foo="bar", baz="Blech"}); 
} 

Metodo dal metodo jquery getJSON semplicemente ...

$.getJSON("../SomeActionMethod", { id: someId }, 
    function(data) { 
     alert(data.foo); 
     alert(data.baz); 
    } 
); 
+14

Questo non risponde affatto alla domanda. – Aaronaught

+2

@Aaronaught In realtà la prima parte 'return Json (new {foo =" bar ", baz =" Blech "});' does! – SparK

12

Per rispondere l'altra metà della domanda, è possibile chiamare:

return PartialView("viewname"); 

quando vuoi restituire un codice HTML parziale. Dovrai solo trovare un modo per decidere se la richiesta vuole JSON o HTML, magari in base a una parte/parametro URL.

+2

quindi la domanda rimane senza risposta? –

+2

Questo non risponde alla domanda. – Aaronaught

+0

sta cercando una richiesta ajax per ottenere l'html utilizzando PartialView richiede un aggiornamento della pagina a meno che non si restituisca la vista da un metodo di azione utilizzando una chiamata ajax –

103

Penso che dovresti considerare AcceptTypes della richiesta. Lo sto utilizzando nel mio progetto corrente per restituire il tipo di contenuto corretto come segue.

L'azione sul controller può testare come sull'oggetto richiesta

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")) 
{ 
    // 
} 

È quindi possibile implementare l'aspx della vista per soddisfare il caso di risposta xhtml parziale.

Poi in jQuery si può prenderlo passando il parametro tipo 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 

Spero che questo aiuti James

+3

Grazie James, che potrebbe essere molto utile per creare una sorta di sito Web e un REST API che utilizza le stesse azioni del controllore. – NathanD

+0

Se ho molti metodi come questo nel mio controller, c'è un modo per farlo in modo più generico? – Seph

+0

In quale spazio dei nomi è la classe Json? Qual è la dipendenza di project.json? Grazie in anticipo – Andrei

4

Per le persone che hanno eseguito l'aggiornamento a MVC 3: ecco un modo pulito Using MVC3 and Json

+1

puoi anche utilizzare la stessa tecnica di questo articolo in MVC 2 – longhairedsi

6

soluzione alternativa con incoding framework

ritorno Azione JSON

controller

[HttpGet] 
    public ActionResult SomeActionMethod() 
    { 
     return IncJson(new SomeVm(){Id = 1,Name ="Inc"}); 
    } 

pagina Razor

@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()) 

ritorno Azione html

controller

[HttpGet] 
    public ActionResult SomeActionMethod() 
    { 
     return IncView(); 
    } 

pagina Razor

@(Html.When(JqueryBind.InitIncoding) 
    .Do() 
    .AjaxGet(Url.Action("SomeActionMethod","SomeContoller")) 
    .OnSuccess(dsl => dsl.Self().Core().Insert.Html()) 
    .AsHtmlAttributes() 
    .ToDiv()) 
40

Ho trovato un paio di problemi nell'implementare MVC ajax. Le chiamate GET con JQuery mi hanno causato grattacapi in modo da condividere le soluzioni qui.

  1. Assicurarsi di includere il tipo di dati "json" nella chiamata ajax. Questo analizzerà automaticamente l'oggetto JSON restituito per te (dato che il server restituisce un json valido).
  2. Include JsonRequestBehavior.AllowGet; senza questo MVC restituiva un errore HTTP 500 (con dataType: json specificato sul client).
  3. Aggiungi cache: false alla chiamata $ .ajax, altrimenti alla fine otterrai risposte HTTP 304 (anziché risposte HTTP 200) e il server non elaborerà la richiesta.
  4. Infine, il json fa distinzione tra maiuscole e minuscole, quindi l'involucro degli elementi deve corrispondere sul lato server e sul lato client.

JQuery Esempio:

$.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); 
    } 
}); 

Esempio codice 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); 
} 
+0

Perfetto! Grazie mille ... –

+0

Funziona come un capo :) –

+1

Grazie per aver postato le opzioni di risoluzione dei problemi per Ajax. Questo mi ha aiutato. – vibs2006

2

PartialViewResult e JSONReuslt ereditare dalla classe base ActionResult. quindi se il tipo di ritorno è deciso dinamicamente, dichiara l'output del metodo come ActionResult.

public ActionResult DynamicReturnType(string parameter) 
     { 
      if (parameter == "JSON") 
       return Json("<JSON>", JsonRequestBehavior.AllowGet); 
      else if (parameter == "PartialView") 
       return PartialView("<ViewName>"); 
      else 
       return null; 


     } 
2
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); 
      } 
     } 
+0

potresti aggiungere un po 'di informazioni in più su ciò che fa? – RealCheeseLord

Problemi correlati