Frage Web-API 2: Wie Sie JSON mit camelCased-Eigenschaftsnamen für Objekte und deren Unterobjekte zurückgeben


AKTUALISIEREN

Danke für alle Antworten. Ich bin auf einem neuen Projekt und es sieht so aus, als ob ich dem letzten Punkt auf den Grund gegangen bin: Es sieht so aus, als ob der folgende Code schuld war:

public static HttpResponseMessage GetHttpSuccessResponse(object response, HttpStatusCode code = HttpStatusCode.OK)
{
    return new HttpResponseMessage()
    {
        StatusCode = code,
        Content = response != null ? new JsonContent(response) : null
    };
}

anderswo...

public JsonContent(object obj)
{
    var encoded = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore } );
    _value = JObject.Parse(encoded);

    Headers.ContentType = new MediaTypeHeaderValue("application/json");
}

Ich hatte den harmlos aussehenden JsonContent übersehen, vorausgesetzt, es war WebAPI, aber nein.

Dies wird verwendet überallKann ich nur der Erste sein, der sagt, wtf? Oder vielleicht sollte das sein "Warum machen sie das?"


ursprüngliche Frage folgt

Man hätte gedacht, das wäre eine einfache Konfigurationseinstellung, aber es ist mir jetzt zu lange entgangen.

Ich habe mir verschiedene Lösungen und Antworten angeschaut:

https://gist.github.com/rdingwall/2012642

scheint nicht für die neueste WebAPI-Version zu gelten ...

Folgendes scheint nicht zu funktionieren - Eigenschaftsnamen sind immer noch PascalCased.

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;

json.UseDataContractJsonSerializer = true;
json.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;

json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

Mayanks Antwort hier: CamelCase JSON WebAPI-Unterobjekte (verschachtelte Objekte, untergeordnete Objekte) schien eine unbefriedigende, aber praktikable Antwort, bis ich erkannte, dass diese Attribute zu generierten Code hinzugefügt werden müssen, wie wir linq2sql verwenden ...

Kann ich das automatisch machen? Dieses "Böse" hat mich schon lange geplagt.


75
2018-02-17 00:10


Ursprung


Antworten:


Wenn Sie alles zusammenfügen, bekommen Sie ...

protected void Application_Start()
{
    HttpConfiguration config = GlobalConfiguration.Configuration;
    config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false;
}

141
2018-02-17 01:55



Das hat bei mir funktioniert:

internal static class ViewHelpers
{
    public static JsonSerializerSettings CamelCase
    {
        get
        {
            return new JsonSerializerSettings {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            };
        }
    }
}

Und dann:

[HttpGet]
[Route("api/campaign/list")]
public IHttpActionResult ListExistingCampaigns()
{
    var domainResults = _campaignService.ListExistingCampaigns();
    return Json(domainResults, ViewHelpers.CamelCase);
}

Die Klasse CamelCasePropertyNamesContractResolver kommt von Newtonsoft.Json.dll im Json.NET Bibliothek.


22
2018-02-17 07:27



Alle obigen Antworten funktionierten bei mir nicht mit Owin Hosting und Ninject. Folgendes hat für mich funktioniert:

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        // Get the ninject kernel from our IoC.
        var kernel = IoC.GetKernel();

        var config = new HttpConfiguration();

        // More config settings and OWIN middleware goes here.

        // Configure camel case json results.
        ConfigureCamelCase(config);

        // Use ninject middleware.
        app.UseNinjectMiddleware(() => kernel);

        // Use ninject web api.
        app.UseNinjectWebApi(config);
    }

    /// <summary>
    /// Configure all JSON responses to have camel case property names.
    /// </summary>
    private void ConfigureCamelCase(HttpConfiguration config)
    {
        var jsonFormatter = config.Formatters.JsonFormatter;
        // This next line is not required for it to work, but here for completeness - ignore data contracts.
        jsonFormatter.UseDataContractJsonSerializer = false;
        var settings = jsonFormatter.SerializerSettings;
#if DEBUG
        // Pretty json for developers.
        settings.Formatting = Formatting.Indented;
#else
        settings.Formatting = Formatting.None;
#endif
        settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    }
}

Der Hauptunterschied ist: new HttpConfiguration () statt GlobalConfiguration.Configuration.


12
2017-08-11 20:24



Es stellt sich heraus, dass

return Json(result);

war der Übeltäter, was dazu führte, dass der Serialisierungsprozess die Camelcase-Einstellung ignorierte. Und das

return Request.CreateResponse(HttpStatusCode.OK, result, Request.GetConfiguration());

war der Droide, den ich suchte.

Ebenfalls

json.UseDataContractJsonSerializer = true;

Hat einen Strich durch die Rechnung gemacht und sich als NICHT der Droide erwiesen, nach dem ich gesucht habe.


11
2018-02-17 01:33



Code der WebApiConfig:

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            //This line sets json serializer's ContractResolver to CamelCasePropertyNamesContractResolver, 
            //  so API will return json using camel case
            config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

        }
    }


Stellen Sie sicher, dass Ihre API-Aktionsmethode die folgenden Daten zurückgibt und dass Sie die neueste Version von Json.Net/Newtonsoft.Json installiert haben:

    [HttpGet]
    public HttpResponseMessage List()
    {
        try
        {
            var result = /*write code to fetch your result*/;
            return Request.CreateResponse(HttpStatusCode.OK, cruises);
        }
        catch (Exception ex)
        {
            return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
        }
    }

6
2017-12-20 11:16



In deinem Owin Startup füge diese Zeile hinzu ...

 public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        var webApiConfiguration = ConfigureWebApi();            
        app.UseWebApi(webApiConfiguration);
    }

    private HttpConfiguration ConfigureWebApi()
    {
        var config = new HttpConfiguration();

        // ADD THIS LINE HERE AND DONE
        config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

        config.MapHttpAttributeRoutes();
        return config;
    }
}

4
2017-11-05 13:27



Hier ist eine obskure, wenn das Routenattribut nicht mit der GET-URL übereinstimmt, aber die GET-URL mit dem Methodennamen übereinstimmt, würde die jselserializer camel case-Anweisung ignoriert werden, z.

http: // website / api / geo / geodaten

//uppercase fail cakes
[HttpGet]
[Route("countries")]
public async Task<GeoData> GeoData()
{
    return await geoService.GetGeoData();
}

//lowercase nomnomnom cakes
[HttpGet]
[Route("geodata")]
public async Task<GeoData> GeoData()
{
    return await geoService.GetGeoData();
}

3
2018-02-11 12:44



Ich habe es folgendermaßen gelöst.

[AllowAnonymous]
[HttpGet()]
public HttpResponseMessage GetAllItems(int moduleId)
{
    HttpConfiguration config = new HttpConfiguration();
            config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false;

            try
            {
                List<ItemInfo> itemList = GetItemsFromDatabase(moduleId);
                return Request.CreateResponse(HttpStatusCode.OK, itemList, config);
            }
            catch (System.Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
}

1
2018-04-04 08:18