2014-04-28 19 views
39

Sto provando a scrivere un metodo C# che serializzerà un modello e restituirà un risultato JSON. Qui è il mio codice:Utilizzo di JSON.NET per restituire ActionResult

public ActionResult Read([DataSourceRequest] DataSourceRequest request) 
    { 
     var items = db.Words.Take(1).ToList(); 
     JsonSerializerSettings jsSettings = new JsonSerializerSettings(); 
     jsSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; 
     var converted = JsonConvert.SerializeObject(items, null, jsSettings); 
     return Json(converted, JsonRequestBehavior.AllowGet); 
    } 

ho ottenuto il seguente risultato JSON quando vado a parole/Leggi in Chrome:

"[{\"WordId\":1,\"Rank\":1,\"PartOfSpeech\":\"article\",\"Image\":\"Upload/29/1/Capture1.PNG\",\"FrequencyNumber\":\"22038615\",\"Article\":null,\"ClarificationText\":null,\"WordName\":\"the | article\",\"MasterId\":0,\"SoundFileUrl\":\"/UploadSound/7fd752a6-97ef-4a99-b324-a160295b8ac4/1/sixty_vocab_click_button.mp3\",\"LangId\":1,\"CatId\":null,\"IsActive\":false} 

penso che il \" sfuggito citazioni sono un problema che si verifica quando si fa doppio serialize un oggetto da altre questioni:. WCF JSON output is getting unwanted quotes & backslashes added

sembra definitivamente come sto doppia serializzazione mio oggetto, da quando ho serializzare utilizzando JSON.NET e poi passare il mio risultato in JSON() la funzione che ho bisogno di serializzare manualmente. per avoi d referenceloops, ma penso che il mio View abbia bisogno di un ActionResult.

Come posso restituire un ActionResult qui? Devo o posso semplicemente restituire una stringa?

+0

Sul ritorno javascript, faccio solo JSON.parse (messaggio) ;. – MiniRagnarok

+0

Significa usare Javascript per analizzare solo la/"s? Sto usando Razor HTML helper per un pacchetto specifico, quindi non so come farlo funzionare .. – hubatish

risposta

60

Ho trovato un simile domanda StackOverflow: Json.Net And ActionResult

La risposta ci ha suggerito di utilizzare

return Content(converted, "application/json"); 

che sembra funzionare sulla mia pagina molto semplice.

+4

Risposta IMO migliore. Semplice e fa esattamente quello che è stato chiesto. – pimbrouwers

+2

se verificherete le intestazioni, vedrete probabilmente 'text/html' come tipo di contenuto. – Dementic

+0

Di gran lunga la soluzione più semplice. Questo fa esattamente ciò di cui ha bisogno. – user1751825

59

Invece di serializzare utilizzando JSON.NET e quindi chiamando Json(), perché non sostituire il metodo Json() nel controller (o forse un controller di base per migliorarne la riusabilità)?

Questo viene estratto da questo blog post.

Nel vostro controller (o il controller base):

protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior) 
{ 
    return new JsonNetResult 
    { 
     Data = data, 
     ContentType = contentType, 
     ContentEncoding = contentEncoding, 
     JsonRequestBehavior = behavior 
    }; 
} 

E la definizione per JsonNetResult:

public class JsonNetResult : JsonResult 
{ 
    public JsonNetResult() 
    { 
     Settings = new JsonSerializerSettings 
     { 
      ReferenceLoopHandling = ReferenceLoopHandling.Ignore, 
     }; 
    } 

    public JsonSerializerSettings Settings { get; private set; } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     if (context == null) 
      throw new ArgumentNullException("context"); 
     if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) 
      throw new InvalidOperationException("JSON GET is not allowed"); 

     HttpResponseBase response = context.HttpContext.Response; 
     response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType; 

     if (this.ContentEncoding != null) 
      response.ContentEncoding = this.ContentEncoding; 
     if (this.Data == null) 
      return; 

     var scriptSerializer = JsonSerializer.Create(this.Settings); 

     using (var sw = new StringWriter()) 
     { 
      scriptSerializer.Serialize(sw, this.Data); 
      response.Write(sw.ToString()); 
     } 
    } 
} 

In questo modo, quando si chiama Json() nel controller, verrà automaticamente ottenere il Serializzazione JSON.NET desiderata.

+0

Cool. Questo è abbastanza conveniente. , Stavo pensando che questo mi avrebbe permesso di passare ancora JSONRequestBehavior.AllowGet, ma non sembra funzionare. – hubatish

+0

Per far funzionare tutto questo, devi aggiungere le sostituzioni a 'Json()' che passa in modo predefinito valori per gli altri parametri. questo è ciò che l'implementazione di default fa. –

+0

Bene, questa linea JSON (i dati degli oggetti, contentType stringa, System.Text.Encoding contentEncoding, comportamento JsonRequestBehavior) sembra significare che posso fare JSON (convertiti , JsonRequestBehavior.AllowGet), ma ottengo "Per consentire le richieste GET, imposta JsonRequestBehavior su AllowGet." Quando vado alla pagina. – hubatish

Problemi correlati