2013-02-23 9 views
26

Sto cercando di rendere la mia azione restituire un JsonResult in cui tutte le sue proprietà sono in camelCase.MVC JsonResult camelCase serialization

Ho un modello semplice:

public class MyModel 
{ 
    public int SomeInteger { get; set; } 

    public string SomeString { get; set; } 
} 

E una semplice azione di controllo:

public JsonResult Index() 
    { 
     MyModel model = new MyModel(); 
     model.SomeInteger = 1; 
     model.SomeString = "SomeString"; 

     return Json(model, JsonRequestBehavior.AllowGet); 
    } 

chiamata a questo metodo di azione ora restituisce un JsonResult contenente i seguenti dati:

{"SomeInteger":1,"SomeString":"SomeString"} 

Per i miei usi ho bisogno che l'azione restituisca i dati in camelCase, in qualche modo come questo:

{"someInteger":1,"someString":"SomeString"} 

C'è un modo elegante per farlo?

Stavo cercando le soluzioni possibili da queste parti e ho trovato MVC3 JSON Serialization: How to control the property names? dove hanno impostato le definizioni DataMember su ogni proprietà del modello, ma in realtà non voglio farlo.

Inoltre ho trovato un collegamento dove si dice che è possibile risolvere esattamente questo tipo di problema: http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization#json_camelcasing. Dice:

Per scrivere nomi di proprietà JSON con involucro cammello, senza cambiare il modello di dati, impostare il CamelCasePropertyNamesContractResolver sulla serializzatore:

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter; 
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

Una voce su questo blog http://frankapi.wordpress.com/2012/09/09/going-camelcase-in-asp-net-mvc-web-api/ mentiones anche questa soluzione e gli stati puoi semplicemente aggiungerlo al numero RouteConfig.RegisterRoutes per risolvere questo problema. L'ho provato, ma non riuscivo a farlo funzionare.

Ragazzi, avete idea di dove stavo facendo qualcosa di sbagliato?

+0

Cosa significa "l'ho provato, ma non riuscivo a farlo funzionare".? – nemesv

+0

Ho aggiunto questo snippet di codice al metodo RouteConfig.RegisterRoutes ma sembrava non avere alcun effetto perché JsonResult conteneva ancora gli stessi dati. –

+2

FYI, il 'CamelCasePropertyNamesContractResolver' funziona solo con i controller WebAPI (controller che estendono' ApiController'). – danludwig

risposta

11

Le funzioni JSON del controller sono solo wrapper per JsonResults creando:

protected internal JsonResult Json(object data) 
{ 
    return Json(data, null /* contentType */, null /* contentEncoding */, JsonRequestBehavior.DenyGet); 
} 

protected internal JsonResult Json(object data, string contentType) 
{ 
    return Json(data, contentType, null /* contentEncoding */, JsonRequestBehavior.DenyGet); 
} 

protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding) 
{ 
    return Json(data, contentType, contentEncoding, JsonRequestBehavior.DenyGet); 
} 

protected internal JsonResult Json(object data, JsonRequestBehavior behavior) 
{ 
    return Json(data, null /* contentType */, null /* contentEncoding */, behavior); 
} 

protected internal JsonResult Json(object data, string contentType, JsonRequestBehavior behavior) 
{ 
    return Json(data, contentType, null /* contentEncoding */, behavior); 
} 

protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) 
{ 
    return new JsonResult 
    { 
     Data = data, 
     ContentType = contentType, 
     ContentEncoding = contentEncoding, 
     JsonRequestBehavior = behavior 
    }; 
} 

JsonResult utilizza internamente JavaScriptSerializer, in modo da non avere il controllo sul processo di serializzazione:

public class JsonResult : ActionResult 
{ 
    public JsonResult() 
    { 
     JsonRequestBehavior = JsonRequestBehavior.DenyGet; 
    } 

    public Encoding ContentEncoding { get; set; } 

    public string ContentType { get; set; } 

    public object Data { get; set; } 

    public JsonRequestBehavior JsonRequestBehavior { get; set; } 

    /// <summary> 
    /// When set MaxJsonLength passed to the JavaScriptSerializer. 
    /// </summary> 
    public int? MaxJsonLength { get; set; } 

    /// <summary> 
    /// When set RecursionLimit passed to the JavaScriptSerializer. 
    /// </summary> 
    public int? RecursionLimit { get; set; } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     if (context == null) 
     { 
      throw new ArgumentNullException("context"); 
     } 
     if (JsonRequestBehavior == JsonRequestBehavior.DenyGet && 
      String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) 
     { 
      throw new InvalidOperationException(MvcResources.JsonRequest_GetNotAllowed); 
     } 

     HttpResponseBase response = context.HttpContext.Response; 

     if (!String.IsNullOrEmpty(ContentType)) 
     { 
      response.ContentType = ContentType; 
     } 
     else 
     { 
      response.ContentType = "application/json"; 
     } 
     if (ContentEncoding != null) 
     { 
      response.ContentEncoding = ContentEncoding; 
     } 
     if (Data != null) 
     { 
      JavaScriptSerializer serializer = new JavaScriptSerializer(); 
      if (MaxJsonLength.HasValue) 
      { 
       serializer.MaxJsonLength = MaxJsonLength.Value; 
      } 
      if (RecursionLimit.HasValue) 
      { 
       serializer.RecursionLimit = RecursionLimit.Value; 
      } 
      response.Write(serializer.Serialize(Data)); 
     } 
    } 
} 

Hai per creare il proprio JsonResult e scrivere le proprie funzioni di Json Controller (se è necessario/desiderato). Puoi crearne di nuovi o sovrascrivere quelli esistenti, dipende da te. Questo link potrebbe interessarti anche.

13

Se si desidera restituire una stringa json dall'azione che aderisce alla notazione Camelcase, è necessario creare un'istanza JsonSerializerSettings e passarla come secondo parametro del metodo JsonConvert.SerializeObject (a, b).

public string GetSerializedCourseVms() 
    { 
     var courses = new[] 
     { 
      new CourseVm{Number = "CREA101", Name = "Care of Magical Creatures", Instructor ="Rubeus Hagrid"}, 
      new CourseVm{Number = "DARK502", Name = "Defence against dark arts", Instructor ="Severus Snape"}, 
      new CourseVm{Number = "TRAN201", Name = "Transfiguration", Instructor ="Minerva McGonal"} 
     }; 
     var camelCaseFormatter = new JsonSerializerSettings(); 
     camelCaseFormatter.ContractResolver = new CamelCasePropertyNamesContractResolver(); 
     return JsonConvert.SerializeObject(courses, camelCaseFormatter); 
    }