web-dev-qa-db-fra.com

MVC JsonResult sérialisation camelCase

J'essaye de faire mon action retourner un JsonResult où toutes ses propriétés sont dans camelCase.

J'ai un modèle simple:

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

    public string SomeString { get; set; }
}

Et une simple action du contrôleur:

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

        return Json(model, JsonRequestBehavior.AllowGet);
    }

L'appel de cette méthode d'action renvoie désormais un JsonResult contenant les données suivantes:

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

Pour mes utilisations, j'ai besoin que l'action renvoie les données dans camelCase, en quelque sorte comme ceci:

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

Existe-t-il une manière élégante de procéder?

Je cherchais des solutions possibles ici et j'ai trouvé Sérialisation JSON MVC3: Comment contrôler les noms de propriété? où ils définissent les définitions DataMember pour chaque propriété du modèle, mais je ne veux pas vraiment le faire.

J'ai également trouvé un lien où ils disent qu'il est possible de résoudre exactement ce type de problème: http://www.asp.net/web-api/overview/formats-and-model-binding/json- et-xml-serialization # json_camelcasing . Ça dit:

Pour écrire des noms de propriété JSON avec un boîtier camel, sans changer votre modèle de données, définissez CamelCasePropertyNamesContractResolver sur le sérialiseur:

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

Une entrée sur ce blog http://frankapi.wordpress.com/2012/09/09/going-camelcase-in-asp-net-mvc-web-api/ mentionne également cette solution et déclare vous pouvez simplement l'ajouter à RouteConfig.RegisterRoutes pour résoudre ce problème. Je l'ai essayé, mais je n'ai pas pu le faire fonctionner.

Avez-vous une idée où je faisais quelque chose de mal?

31
Thomas Mondel

Les fonctions Json du contrôleur ne sont que des wrappers pour créer des résultats Json:

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 utilise en interne JavaScriptSerializer, vous n'avez donc aucun contrôle sur le processus de sérialisation:

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

Vous devez créer votre propre JsonResult et écrire vos propres fonctions de contrôleur Json (si vous en avez besoin/le souhaitez). Vous pouvez en créer de nouveaux ou écraser ceux qui existent, c'est à vous. Ce lien pourrait également vous intéresser.

13
Dresel

Si vous souhaitez renvoyer une chaîne json de votre action qui respecte la notation camelcase, vous devez créer une instance JsonSerializerSettings et la passer en tant que deuxième paramètre de la méthode 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);
    }
15
DanKodi