Usando JSON.NET para devolver ActionResult

Intento escribir un método C # que serialice un modelo y devuelva un resultado JSON. Aquí está mi código:

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

Obtuve el siguiente resultado de JSON cuando voy a Words / Read en 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} 

Creo que las \ “escapadas de las comillas son un problema que ocurre cuando duplicas serializar un objeto. De otras preguntas: La salida WCF JSON recibe cotizaciones y barras invertidas no deseadas.

Definitivamente parece que estoy serializando dos veces mi objeto, ya que primero serializo usando JSON.NET y luego paso mi resultado a la función Json (). Necesito serializar manualmente para evitar los ciclos de referencia, pero creo que mi vista necesita un resultado de acción.

¿Cómo puedo devolver un ActionResult aquí? ¿Debo hacerlo, o puedo simplemente devolver una cadena?

Encontré una pregunta similar sobre stackflow : Json.Net y ActionResult

La respuesta allí sugirió usar

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

Eso parece funcionar en mi página muy simple.

En lugar de serializar utilizando JSON.NET y luego llamar a Json() , ¿por qué no reemplazar el método Json() en su controlador (o tal vez un controlador base para mejorar su reutilización)?

Esto se extrae de esta publicación de blog.

En su controlador (o controlador 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 }; } 

Y la definición de 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()); } } } 

Al hacer esto, cuando llame a Json() en su controlador, obtendrá automáticamente la serialización JSON.NET que desee.