[c#] Web API 2 : 객체 및 해당 하위 객체에서 camelCased 속성 이름과 함께 JSON을 반환하는 방법

최신 정보

모든 답변에 감사드립니다. 저는 새 프로젝트를 진행 중이며 마침내이 문제를 해결 한 것 같습니다. 실제로 다음 코드가 원인이 된 것 같습니다.

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

다른 곳에 …

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

WebAPI가 아니라고 가정하고 무해한 JsonContent를 간과했습니다.

이것은 어디에서나 사용됩니다 … 내가 처음으로 말할 수 있습니까, wtf? 아니면 “왜 이러는거야?”


원래 질문이 이어진다

하나는 이것이 간단한 구성 설정이라고 생각했을 것이지만 지금은 너무 오래되었습니다.

다양한 솔루션과 답변을 살펴 보았습니다.

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

최신 WebAPI 버전에 적용되지 않는 것 같습니다 …

다음은 작동하지 않는 것 같습니다. 속성 이름은 여전히 ​​PascalCased입니다.

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;

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

json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

Mayank의 답변 : CamelCase JSON WebAPI 하위 개체 (중첩 된 개체, 하위 개체) 는 만족스럽지 않지만 linq2sql을 사용하면서 이러한 속성을 생성 된 코드에 추가해야한다는 것을 깨달을 때까지 실행 가능한 대답처럼 보였습니다.

이 작업을 자동으로 수행하는 방법이 있습니까? 이 ‘더러운’은 오랫동안 나를 괴롭 혔습니다.



답변

모두 합치면 얻을 수 있습니다 …

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


답변

이것은 나를 위해 일한 것입니다.

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

그리고:

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

클래스 CamelCasePropertyNamesContractResolverJson.NET 라이브러리 Newtonsoft.Json.dll에서 제공됩니다 .


답변

그것은 밝혀졌다

return Json(result);

범인이어서 직렬화 프로세스가 camelcase 설정을 무시하도록했습니다. 그리고

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

제가 찾고 있던 드로이드였습니다.

또한

json.UseDataContractJsonSerializer = true;

스패너를 작업에 넣었고 내가 찾고 있던 드로이드가 아닌 것으로 판명되었습니다.


답변

위의 모든 답변은 Owin Hosting 및 Ninject에서 작동하지 않았습니다. 나를 위해 일한 것은 다음과 같습니다.

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

주요 차이점은 GlobalConfiguration.Configuration이 아닌 new HttpConfiguration ()입니다.


답변

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

        }
    }

API 작업 메서드가 다음과 같은 방식으로 데이터를 반환하는지 확인하고 최신 버전의 Json.Net/Newtonsoft.Json을 설치했는지 확인합니다.

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


답변

Owin Startup에서 다음 줄을 추가하십시오.

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


답변

다음은 모호한 것입니다. route 속성이 GET URL과 일치하지 않지만 GET URL이 메소드 이름과 일치하면 jsonserializer camel case 지시문이 무시됩니다.

http : // website / api / geo / geodata

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