Json.Net के साथ क्रमबद्ध करते समय एक कस्टम डेटाइम प्रारूप निर्दिष्ट करना


137

मैं ASP.NET वेब एपीआई का उपयोग कर कुछ डेटा को उजागर करने के लिए एक एपीआई विकसित कर रहा हूं।

एपीआई में से एक में, क्लाइंट हमें yyyy-MM-ddप्रारूप में तारीख को उजागर करना चाहता है । मैं इसके लिए वैश्विक सेटिंग्स (जैसे GlobalConfiguration.Configuration.Formatters.JsonFormatter) को बदलना नहीं चाहता क्योंकि यह इस क्लाइंट के लिए बहुत विशिष्ट है। और मैं कई ग्राहकों के लिए एक समाधान में विकसित कर रहा हूँ।

एक उपाय जो मैं सोच सकता था, वह है एक कस्टम बनाना JsonConverterऔर फिर उस प्रॉपर्टी में रखना जो मुझे कस्टम फॉर्मेटिंग करने की जरूरत है

जैसे

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

बस सोच रहा था कि ऐसा करने का कोई और आसान तरीका है।


16
इसके लायक क्या है, एपीआई कंप्यूटर की पठनीयता के लिए हैं, उपयोगकर्ता की पठनीयता के लिए नहीं, इसलिए आईएसओ 8601 जैसे एकल निर्दिष्ट तिथि प्रारूप में रहना बेहतर है । यदि क्लाइंट सीधे उपयोगकर्ता को एपीआई परिणाम प्रदर्शित कर रहा है, या एपीआई के लिए अपनी खुद की तारीख पार्सिंग कोड लिख रहा है, तो वे इसे गलत कर रहे हैं। प्रदर्शन के लिए एक तारीख तैयार करना सबसे ऊपरी UI परत पर छोड़ दिया जाना चाहिए।
एमसील्ट

Visual Studio 2019 का उपयोग करके वेब एपीआई बनाएं, ASP.NET कोर 3.0 में दिनांक का समय
स्टीफन

जवाबों:


162

आप सही रास्ते पर हैं। चूंकि आपने कहा था कि आप वैश्विक सेटिंग्स को संशोधित नहीं कर सकते हैं, तो अगली सबसे अच्छी बात यह है कि जैसा JsonConverterकि आपने सुझाव दिया है, वैसा ही आवश्यक है। यह बताता है कि Json.Net में पहले से ही एक अंतर्निहित IsoDateTimeConverterहै जो आपको तिथि प्रारूप निर्दिष्ट करने देता है। दुर्भाग्य से, आप JsonConverterविशेषता के माध्यम से प्रारूप निर्धारित नहीं कर सकते , क्योंकि विशेषता का एकमात्र तर्क एक प्रकार है। हालांकि, एक सरल समाधान है: उपवर्ग 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
ब्रायन रोजर्स

यह यहाँ उद्धरण के साथ काम नहीं किया और यह उनके बिना किया था, लेकिन अगर आप कहते हैं कि यह चाहिए, मैंने शायद कुछ गलत किया। एडिट के लिए क्षमा करें।
कोएन जोमर्स

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
टैम कॉटन

1
यह सबसे लचीला उपाय है। यदि आपको निम्न त्रुटि मिलती है: 'JsonConverterAttribute' does not contain a constructor that takes 2 argumentsइसका मतलब है कि आपका json.net का संस्करण बहुत पुराना है। आपको नवीनतम json.net संस्करण में अपडेट करने की आवश्यकता है।
फ्लोरियन लिवरेल

मेरे लिये कार्य करता है। किसी भी विचार कैसे मैं समय निकाल सकते हैं? इसलिए केवल T20: 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
FYI करें मुझे लगता है कि आपका मतलब है yyyy-MM-ddTHH:mm:ssZ.. घंटे पर 24 घंटे की घड़ी।
नेक

9

सहायक वर्ग का निर्माण करें और इसे अपनी संपत्ति विशेषता पर लागू करें

सहायक वर्ग:

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

आपका कोड इस तरह उपयोग होता है:

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

8
आपने अभी तक पुन: पुनरावृति क्यों की है जो पहले से ही कई अन्य लोगों ने बताई है?
लियाम

3

एक और उपाय है जिसका मैं उपयोग कर रहा हूं। बस एक स्ट्रिंग प्रॉपर्टी बनाएं और इसे json के लिए उपयोग करें। यह प्रॉपर्टी wil रिटर्न डेट को ठीक से फॉर्मेट किया गया है।

class JSonModel {
    ...

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

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

    ...
}

इस तरह आपको अतिरिक्त कक्षाएं नहीं बनानी होंगी। इसके अलावा, यह आपको अलग-अलग डेटा प्रारूप बनाने की अनुमति देता है। उदाहरण के लिए, आप उसी DateTime का उपयोग करके घंटे के लिए एक और संपत्ति आसानी से बना सकते हैं।


0

कुछ बार जोंस कन्वर्ट विशेषता को सजाने से काम नहीं चलेगा, यह अपवाद के माध्यम से कहेगा कि " 2010-10-01" वैध तिथि है । इस प्रकार से बचने के लिए मैंने संपत्ति पर json कन्वर्ट विशेषता को हटा दिया और नीचे की तरह 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;}
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.