web-dev-qa-db-fra.com

Comment puis-je renvoyer camelCase JSON sérialisé par JSON.NET à partir des méthodes de contrôleur ASP.NET MVC?

Mon problème est que je souhaite renvoyer les données JSON de camelCased (par opposition au PascalCase standard) via ActionResult s à partir de méthodes de contrôleur ASP.NET MVC, sérialisées par JSON.NET .

A titre d'exemple, considérons la classe C # suivante:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Par défaut, lors du renvoi d'une instance de cette classe à partir d'un contrôleur MVC en tant que JSON, celle-ci sera sérialisée de la manière suivante:

{
  "FirstName": "Joe",
  "LastName": "Public"
}

Je voudrais qu'il soit sérialisé (par JSON.NET) comme:

{
  "firstName": "Joe",
  "lastName": "Public"
}

Comment puis-je faire cela?

192
aknuds1

J'ai trouvé une excellente solution à ce problème sur le blog de Mats Karlsson. La solution consiste à écrire une sous-classe d'ActionResult qui sérialise les données via JSON.NET, en configurant ce dernier pour qu'il respecte la convention camelCase:

public class JsonCamelCaseResult : ActionResult
{
    public JsonCamelCaseResult(object data, JsonRequestBehavior jsonRequestBehavior)
    {
        Data = data;
        JsonRequestBehavior = jsonRequestBehavior;
    }

    public Encoding ContentEncoding { get; set; }

    public string ContentType { get; set; }

    public object Data { get; set; }

    public JsonRequestBehavior JsonRequestBehavior { 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("This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.");
        }

        var response = context.HttpContext.Response;

        response.ContentType = !String.IsNullOrEmpty(ContentType) ? ContentType : "application/json";
        if (ContentEncoding != null)
        {
            response.ContentEncoding = ContentEncoding;
        }
        if (Data == null)
            return;

        var jsonSerializerSettings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
        response.Write(JsonConvert.SerializeObject(Data, jsonSerializerSettings));
    }
}

Puis utilisez cette classe comme suit dans votre méthode de contrôleur MVC:

public ActionResult GetPerson()
{
    return new JsonCamelCaseResult(new Person { FirstName = "Joe", LastName = "Public" }, JsonRequestBehavior.AllowGet)};
}
85
aknuds1

ou simplement:

JsonConvert.SerializeObject(
    <YOUR OBJECT>, 
    new JsonSerializerSettings 
    { 
        ContractResolver = new CamelCasePropertyNamesContractResolver() 
    });

Par exemple:

return new ContentResult
{
    ContentType = "application/json",
    Content = JsonConvert.SerializeObject(new { content = result, rows = dto }, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }),
    ContentEncoding = Encoding.UTF8
};
313
WebDever

Je pense que c'est la réponse simple que vous recherchez. C'est tiré du blog de Shawn Wildermuth :

// Add MVC services to the services container.
services.AddMvc()
  .AddJsonOptions(opts =>
  {
    opts.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
  });
31
Quantium

Une alternative au filtre personnalisé consiste à créer une méthode d'extension pour sérialiser tout objet en JSON.

public static class ObjectExtensions
{
    /// <summary>Serializes the object to a JSON string.</summary>
    /// <returns>A JSON string representation of the object.</returns>
    public static string ToJson(this object value)
    {
        var settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Converters = new List<JsonConverter> { new StringEnumConverter() }
        };

        return JsonConvert.SerializeObject(value, settings);
    }
}

Puis appelez-le quand vous revenez de l'action du contrôleur.

return Content(person.ToJson(), "application/json");
9
Stuart Hallows

Dans ASP.NET Core MVC.

    public IActionResult Foo()
    {
        var data = GetData();

        var settings = new JsonSerializerSettings 
        { 
            ContractResolver = new CamelCasePropertyNamesContractResolver() 
        });

        return Json(data, settings);
    }
7
Fred

Vous trouverez ci-dessous une méthode d'action qui renvoie une chaîne JSON (cameCase) en sérialisant un tableau d'objets.

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

Notez l'instance JsonSerializerSettings passée en tant que deuxième paramètre. C'est ce qui rend le camelCase arriver.

6
DanKodi

Plus simple, c'est mieux IMO!

Pourquoi ne fais-tu pas ça?

public class CourseController : JsonController
{
    public ActionResult ManageCoursesModel()
    {
        return JsonContent(<somedata>);
    }
}

Le contrôleur de classe de base simple

public class JsonController : BaseController
{
    protected ContentResult JsonContent(Object data)
    {
        return new ContentResult
        {
            ContentType = "application/json",
             Content = JsonConvert.SerializeObject(data, new JsonSerializerSettings { 
              ContractResolver = new CamelCasePropertyNamesContractResolver() }),
            ContentEncoding = Encoding.UTF8
        };
    }
}
0
jwize

Vous devez définir les paramètres dans le fichier 'Startup.cs'

Vous devez également le définir dans les valeurs par défaut de JsonConvert, si vous souhaitez utiliser ultérieurement la bibliothèque directement pour sérialiser un objet.

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(options => {
                options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });
        JsonConvert.DefaultSettings = () => new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore,
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        };
    }
0
Daniel Sánchez

J'ai fait comme ça:

public static class JsonExtension
{
    public static string ToJson(this object value)
    {
        var settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            NullValueHandling = NullValueHandling.Ignore,
            ReferenceLoopHandling = ReferenceLoopHandling.Serialize
        };
        return JsonConvert.SerializeObject(value, settings);
    }
}

c’est une méthode d’extension simple dans le noyau MVC, cela va donner la capacité ToJson () à chaque objet de votre projet. À mon avis, dans un projet MVC, la plupart des objets devraient pouvoir devenir json, bien sûr cela dépend :) 

0
Ali Alp