IT story

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

hot-time 2020. 8. 29. 12:43
반응형

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

다음은 경로 속성이 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();
}

나는 다음과 같이 그것을 해결했다.

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

I'm using WebApi with Breeze and I ran the same issue when trying to execute a non-breeze action into a breeze controller. I tried to use the apprach Request.GetConfiguration but the same result. So, when I access the object returned by Request.GetConfiguration I realize that the serializer used by request is the one that breeze-server use to make it's magic. Any way, I resolved my issue creating a different HttpConfiguration:

public static HttpConfiguration BreezeControllerCamelCase
        {
            get
            {
                var config = new HttpConfiguration();
                var jsonSerializerSettings = config.Formatters.JsonFormatter.SerializerSettings;
                jsonSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                jsonSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                config.Formatters.JsonFormatter.UseDataContractJsonSerializer = false;

                return config;
            }
        }

and passing it as parameter at Request.CreateResponse as follow:

return this.Request.CreateResponse(HttpStatusCode.OK, result, WebApiHelper.BreezeControllerCamelCase);

참고URL : https://stackoverflow.com/questions/28552567/web-api-2-how-to-return-json-with-camelcased-property-names-on-objects-and-the

반응형