ASP.NET MVC 컨트롤러 메소드에서 JSON.NET으로 직렬화 된 camelCase JSON을 어떻게 반환 할 수 있습니까?


246

내 문제는 JSON.NET으로 직렬화 된 ASP.NET MVC 컨트롤러 메소드의 ActionResult 를 통해 camelCased (표준 PascalCase와 달리) JSON 데이터를 반환하고 싶습니다 .

예를 들어 다음 C # 클래스를 고려하십시오.

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

기본적으로 MVC 컨트롤러에서이 클래스의 인스턴스를 JSON으로 반환하면 다음과 같은 방식으로 직렬화됩니다.

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

JSON.NET에서 다음과 같이 직렬화하고 싶습니다.

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

어떻게해야합니까?

답변:


389

또는 간단히 말하면 다음과 같습니다.

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

예를 들어 :

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

2
각 컨트롤러 메소드에 대해 ContentResult를 구성해야하므로 사용하기가 더 복잡합니다.
aknuds1

2
예, 귀하의 답변이 재사용 가능한 솔루션이라는 것을 알고 있습니다. 제 요점은 그것이 직렬화 방법의 매개 변수라는 것을 더 명확하게하는 것입니다.
WebDever

1
Controller메소드 에서 JSON을 반환 ApiController하는 경우 아마도을 사용해야합니다 .이 경우이 답변이 효과적입니다.
Simon Hartcher

1
@SimonHartcher 일반적인 경우가 아니라 질문의 범위를 고려하십시오.
aknuds1

1
JSON에 대한 유효한 내용 유형이다 application/json,하지 text/plain.
Fred

94

Mats Karlsson의 블로그 에서이 문제에 대한 훌륭한 해결책을 찾았습니다 . 해결 방법은 JSON.NET을 통해 데이터를 직렬화하여 camelCase 규칙을 따르도록 구성하는 ActionResult의 서브 클래스를 작성하는 것입니다.

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

그런 다음 MVC 컨트롤러 메소드에서 다음과 같이이 클래스를 사용하십시오.

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

3
정답 : 깨끗하고 재사용 가능! 감사합니다.
샌더

1
이 솔루션이 여전히 작동하는 동안. 그러나 그것은 4 년 전에 제안되었습니다. 더 나은 솔루션이 있습니까?
SharpCoder

59

들어 WebAPI :이 링크를 체크 아웃 http://odetocode.com/blogs/scott/archive/2013/03/25/asp-net-webapi-tip-3-camelcasing-json.aspx을

기본적 으로이 코드를 다음에 추가하십시오 Application_Start.

var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();

4
웹 API와 MVC는 ASP.NET 6에서 병합되었습니다
AlexFoxGill

1
편의를 위해 연결; 이 설정은 stackoverflow.com/a/26068063/398630 (다른 질문이지만 함께 사용 하므로이 링크는 나와 다른 사람들을 나중에 구할 수 있습니다)과 함께 잘 작동합니다.
BrainSlugs8383

37

나는 이것이 당신이 찾고있는 간단한 대답이라고 생각합니다. Shawn Wildermuth 의 블로그 에서 가져온 것입니다 .

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

2
사과합니다 이 게시물을 너무 빨리 읽었습니다. ASP.NET 5 용입니다.
Quantium

8
아이러니하게도, 나는 당신이 여기에 대답 한 질문에 대한 답변을 찾기 위해 여기에 왔으므로 OP의 질문에 대한 대답은 아니지만 어쨌든 도움이되었습니다. 감사! :)
porcus

1
나는 @porcus가 말한 것을 두 번째로! @Quantium 감사합니다!
Gromer

4
참고 ASP.NET Core 1.0의 경우 기본적으로 낙타의 경우입니다. OOTB
Chris Marisic

3
결국 이것은 .NET Core 1.0의 기본값이 아닙니다. 이 솔루션은 동적 속성에 영향을 미치며 기본적으로 영향을받지 않습니다. stackoverflow.com/questions/41329279/…
Niels Brinch

13

사용자 정의 필터의 대안은 모든 객체를 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);
    }
}

그런 다음 컨트롤러 조치에서 돌아올 때 호출하십시오.

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

우아하고 간단합니다.
markau

1
설정을 정적 읽기 전용 필드로 전송하고 FromJson 보완 방법을 추가 할 수도 있습니다.
골목에서 증기

8

IMO가 간단할수록 좋습니다!

왜 이러지 그래?

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

간단한 기본 클래스 컨트롤러

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

7

ASP.NET Core MVC에서.

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

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

        return Json(data, settings);
    }

또한 Startup.cs 파일에 넣으십시오.
FatAlbert

6

다음은 객체 배열을 직렬화하여 json 문자열 (cameCase)을 반환하는 작업 방법입니다.

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

JsonSerializerSettings 인스턴스가 두 번째 매개 변수로 전달되었습니다. 그것이 camelCase가 일어나는 이유입니다.


4

나는 이것을 좋아했다 :

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

이 MVC 코어의 간단한 확장 방법은 프로젝트의 모든 객체에 ToJson () 기능을 제공 할 것입니다 .MVC 프로젝트에서 내 의견으로는 대부분의 객체가 json이 될 수 있어야합니다.


ToJson 메소드가 호출 될 때마다 새 변수를 초기화하지 않도록 메소드 외부의 "설정"변수 추출 (개인 정적 필드 "camelCaseSettings")을 고려하십시오.
에쿠스

4

'Startup.cs'파일에서 설정을 설정해야합니다

또한 JsonConvert의 기본값으로 정의해야합니다. 나중에 라이브러리를 사용하여 오브젝트를 직렬화하려는 경우입니다.

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

이 답변은 ASP.NET Core에는 맞지만 ASP.NET (문제의 프레임 워크)에는 맞지 않습니다.
Nate Barbettini

0

.net 코어 웹 API 또는 IHttpAction 결과로 ActionResult를 반환하는 경우 프런트 엔드의 경우와 일치하는 Ok () 메서드로 모델을 마무리하고 직렬화 할 수 있습니다. JsonConvert를 사용할 필요가 없습니다. :)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.