it-swarm.dev

웹 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을 사용함에 따라 생성 된 코드에 이러한 속성을 추가해야한다는 것을 알기 전까지는 만족스럽지 않지만 실행 가능한 답변처럼 보였습니다. ..

이 작업을 자동으로 수행하는 방법이 있습니까? 이 '불쾌한'은 지금 오랫동안 저를 괴롭 혔습니다.

93
Tom

모두 모아서 ...

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

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

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

CamelCasePropertyNamesContractResolver 클래스는 Json.NET 라이브러리의 Newtonsoft.Json.dll에서 가져옵니다.

26
felix-b

그것은 밝혀졌다

return Json(result);

원인이되어 직렬화 프로세스에서 낙타 설정을 무시했습니다. 그리고

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

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

또한

json.UseDataContractJsonSerializer = true;

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

12
Tom

위의 모든 답변은 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 ()입니다.

12
mkaj

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);
        }
    }
9
Jay Shah

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

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

나는 다음과 같은 방법으로 그것을 해결했다.

[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
Khademul Basher

Breeze와 함께 WebApi를 사용하고 있으며 산들 바람 컨트롤러에 산들 바람이 아닌 동작을 실행하려고 할 때도 같은 문제가 발생했습니다. apprach Request.GetConfiguration을 사용하려고했지만 동일한 결과를 얻었습니다. 그래서 Request.GetConfiguration에 의해 반환 된 객체에 액세스 할 때 요청에 사용 된 직렬 변환기가 breeze-server가 마법을 만들기 위해 사용하는 직렬 변환기라는 것을 알고 있습니다. 어쨌든 다른 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;
            }
        }

request.CreateResponse에서 다음과 같이 매개 변수로 전달하십시오.

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