ti-enxame.com

MVC JsonResult camelCase serialização

Estou tentando fazer minha ação retornar um JsonResult onde todas as suas propriedades estão no camelCase.

Eu tenho um modelo simplesmente:

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

    public string SomeString { get; set; }
}

E uma ação simples do controlador:

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

        return Json(model, JsonRequestBehavior.AllowGet);
    }

Chamar esse método de ação agora retorna um JsonResult contendo os seguintes dados:

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

Para meus usos, preciso que a ação retorne os dados no camelCase, de alguma forma assim:

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

Existe alguma maneira elegante de fazer isso?

Eu estava procurando possíveis soluções por aqui e encontrei Serialização JSC do MVC3: como controlar os nomes das propriedades? onde eles definem as definições do DataMember para todas as propriedades do modelo, mas eu realmente não quero fazer isso.

Também encontrei um link onde eles dizem que é possível resolver exatamente esse tipo de problema: http://www.asp.net/web-api/overview/formats-and-model-binding/json- e-xml-serialization # json_camelcasing . Diz:

Para escrever nomes de propriedades JSON com revestimento de camelo, sem alterar seu modelo de dados, configure CamelCasePropertyNamesContractResolver no serializador:

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

Uma entrada neste blog http://frankapi.wordpress.com/2012/09/09/going-camelcase-in-asp-net-mvc-web-api/ também menciona esta solução e estados você pode simplesmente adicioná-lo ao RouteConfig.RegisterRoutes para corrigir esse problema. Eu tentei, mas não consegui fazê-lo funcionar.

Vocês têm alguma ideia de onde eu estava fazendo algo errado?

31
Thomas Mondel

As funções Json do Controller são apenas invólucros para criar JsonResults:

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

O JsonResult usa internamente o JavaScriptSerializer, para que você não tenha controle sobre o processo de serialização:

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

Você precisa criar seu próprio JsonResult e escrever suas próprias funções do Json Controller (se você precisar/desejar). Você pode criar novos ou substituir os existentes, é com você. Este link também pode lhe interessar.

13
Dresel

Se você deseja retornar uma sequência json de sua ação, que adere à notação camelcase, o que você deve fazer é criar uma instância JsonSerializerSettings e passá-la como o segundo parâmetro do método 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