Json.Net으로 직렬화 할 때 사용자 정의 DateTime 형식 지정


137

ASP.NET Web API를 사용하여 일부 데이터를 노출하는 API를 개발 중입니다.

API 중 하나에서 클라이언트는 날짜를 yyyy-MM-dd형식으로 노출하기를 원합니다 . 전역 설정 (예 :) GlobalConfiguration.Configuration.Formatters.JsonFormatter은이 클라이언트에만 적용되므로 변경하고 싶지 않습니다 . 그리고 여러 고객을위한 솔루션으로 개발하고 있습니다.

내가 생각할 수있는 해결책 중 하나는 사용자 지정 JsonConverter을 만든 다음 사용자 지정 서식을 지정 해야하는 속성에 넣는 것입니다.

예 :

class ReturnObjectA 
{
    [JsonConverter(typeof(CustomDateTimeConverter))]
    public DateTime ReturnDate { get;set;}
}

다른 쉬운 방법이 있는지 궁금합니다.


16
가치가있는 API는 사용자 가독성이 아닌 컴퓨터 가독성을위한 것이므로 ISO 8601 과 같은 지정된 단일 날짜 형식을 고수하는 것이 좋습니다 . 클라이언트가 API 결과를 사용자에게 직접 표시하거나 API에 대한 자체 날짜 구문 분석 코드를 작성하는 경우, 잘못하고 있습니다. 표시 날짜 형식은 최상위 UI 레이어에 두어야합니다.
MCattle

답변:


162

당신은 올바른 길을 가고 있습니다. 전역 설정을 수정할 수 없다고 말 했으므로 다음으로 가장 좋은 방법은 JsonConverter제안한대로 필요에 따라 속성 을 적용하는 것입니다 . Json.Net에는 이미 IsoDateTimeConverter날짜 형식을 지정할 수 있는 내장 기능 이 있습니다. 불행히도 JsonConverter속성의 유일한 인수는 유형이므로 속성을 통해 형식을 설정할 수 없습니다 . 그러나 간단한 해결책이 있습니다. subclass the IsoDateTimeConverter다음 서브 클래스 생성자에서 날짜 형식을 지정하십시오. JsonConverter사용자 지정 변환기를 지정하여 필요한 곳에 특성을 적용하면 준비가 완료됩니다. 필요한 코드 전체는 다음과 같습니다.

class CustomDateTimeConverter : IsoDateTimeConverter
{
    public CustomDateTimeConverter()
    {
        base.DateTimeFormat = "yyyy-MM-dd";
    }
}

거기에 시간이 없어도 IsoDateTimeConverter를 서브 클래스로 만들 필요조차 없습니다. 기본 날짜 형식은 소스 코드yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK 에서 볼 수 있습니다.


1
@ Koen Zomers-내 날짜 형식에서 제거 한 작은 따옴표는 기술적으로 정확하지만 여기서 반드시 필요한 것은 아닙니다. 사용자 정의 날짜 및 시간 형식 문자열 에 대한 설명서 에서 리터럴 문자열 구분 기호 를 참조하십시오 . 그러나 내가 기본 형식으로 인용 한 형식 은 Json.Net 소스 코드 에서 직접 가져온 것입니다 . 따라서 편집 내용을 되돌립니다. IsonDateTimeConverter
브라이언 로저스

따옴표로 여기에서 작동하지 않았으며 따옴표없이 수행되었지만, 말해야한다면, 아마도 뭔가 잘못했을 것입니다. 편집 해 주셔서 죄송합니다.
Koen Zomers

96

이 방법을 사용할 수 있습니다.

public class DateFormatConverter : IsoDateTimeConverter
{
    public DateFormatConverter(string format)
    {
        DateTimeFormat = format;
    }
}

그리고 이런 식으로 사용하십시오 :

class ReturnObjectA 
{
    [JsonConverter(typeof(DateFormatConverter), "yyyy-MM-dd")]
    public DateTime ReturnDate { get;set;}
}

DateTimeFormat 문자열은 여기에 설명 된 .NET 형식 문자열 구문을 사용합니다. https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings


5
이것은 나를 위해 작동하지 않습니다-내가 얻을'JsonConverterAttribute' does not contain a constructor that takes 2 arguments
Tam Coton

1
가장 유연한 솔루션입니다. 다음과 같은 오류가 발생하면 : 'JsonConverterAttribute' does not contain a constructor that takes 2 argumentsjson.net 버전이 너무 오래된 것입니다. 최신 json.net 버전으로 업데이트해야합니다.
Florian Lavorel

나를 위해 작동합니다. 어떻게 시간을 없앨 수 있을까요? 예를 들어 T00 : 00 : 00
Enrico

53

IsoDateTimeConverter전역 서식 설정을 변경하지 않고 인스턴스를 사용하여 수행 할 수도 있습니다 .

string json = JsonConvert.SerializeObject(yourObject,
    new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" });

인수 JsonConvert.SerializeObject를 취하는 오버로드를 사용합니다 params JsonConverter[].


5
여러 곳에서 동일한 클래스 객체를 직렬화하는 경우 허용되는 답변이 이보다 낫습니다
kgzdev

16

직렬 변환기 설정 과부하 중 하나를 사용하여 사용할 수도 있습니다.

var json = JsonConvert.SerializeObject(someObject, new JsonSerializerSettings() { DateFormatString = "yyyy-MM-ddThh:mm:ssZ" });

또는

var json = JsonConvert.SerializeObject(someObject, Formatting.Indented, new JsonSerializerSettings() { DateFormatString = "yyyy-MM-ddThh:mm:ssZ" });

타입을 사용하는 과부하도 가능합니다.


2
참고로 당신은 yyyy-MM-ddTHH:mm:ssZ.. 24 시간제 를 의미한다고 생각합니다 .
Neek

9

헬퍼 클래스를 빌드하고 속성 속성에 적용

헬퍼 클래스 :

public class ESDateTimeConverter : IsoDateTimeConverter
{
    public ESDateTimeConverter()
    {
        base.DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffZ";
    }
}

코드는 다음과 같이 사용됩니다.

[JsonConverter(typeof(ESDateTimeConverter))]
public DateTime timestamp { get; set; }

8
왜 다른 사람들이 이미 언급 한 내용을 다시 언급 한 적이 있습니까?
Liam

3

내가 사용한 다른 솔루션이 있습니다. 문자열 속성을 만들고 json에 사용하십시오. 이 속성은 올바른 형식의 날짜를 반환합니다.

class JSonModel {
    ...

    [JsonProperty("date")]
    public string MyDate { get; set; }

    public string CustomDate {
        get { return MyDate.ToString("DDMMYY"); }
        set { MyDate = DateTime.Parse(value); }
    }

    ...
}

이런 식으로 추가 클래스를 만들 필요가 없습니다. 또한 다른 데이터 형식을 만들 수 있습니다. 예를 들어, 동일한 DateTime을 사용하여 시간에 대한 다른 속성을 쉽게 만들 수 있습니다.


0

때때로 json convert 속성을 꾸미는 것은 효과가 없을 것입니다. " 2010-10-01"이 유효한 날짜라는 예외를 통해 처리 할 것 입니다. 이 유형을 피하기 위해 속성에서 json convert 속성을 제거하고 아래처럼 deserilizedObject 메소드에서 언급했습니다.

var addresss = JsonConvert.DeserializeObject<AddressHistory>(address, new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd" });

0

아래 변환기로

public class CustomDateTimeConverter : IsoDateTimeConverter
    {
        public CustomDateTimeConverter()
        {
            DateTimeFormat = "yyyy-MM-dd";
        }

        public CustomDateTimeConverter(string format)
        {
            DateTimeFormat = format;
        }
    }

기본 사용자 정의 형식으로 사용할 수 있습니다

class ReturnObjectA 
{
    [JsonConverter(typeof(DateFormatConverter))]
    public DateTime ReturnDate { get;set;}
}

또는 속성에 대해 지정된 형식

class ReturnObjectB 
{
    [JsonConverter(typeof(DateFormatConverter), "dd MMM yy")]
    public DateTime ReturnDate { get;set;}
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.