Bart Calixto
Bart Calixto

Reputation: 19705

Serialize only Date part of DateTime in web api 2

Having this object :

public class Person {
    public string FirstName { get; set; }
    [DataType(DataType.Date)]
    public DateTime Birthday { get; set; }
}

Returning this object as content in Web Api 2 generates this json for Birthday :

"2014-02-20T17:00:32.7114097+00:00"

How can I make it to be : "2014-02-20" without the time part?

Upvotes: 6

Views: 13065

Answers (5)

Aage
Aage

Reputation: 6252

For .NET core 3.1 API:

public class ShortDateConverter : JsonConverter<DateTime>
{
    public override DateTime Read(
        ref Utf8JsonReader reader,
        Type typeToConvert,
        JsonSerializerOptions options)
    {
        // only supports writing
        throw new NotImplementedException();
    }

    public override void Write(
        Utf8JsonWriter writer,
        DateTime value,
        JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString("yyyy-MM-dd"));
    }
}

And register in Startup.cs in ConfigureServices:

 services.AddMvc()                
            .AddJsonOptions((options) =>
            {
                options.JsonSerializerOptions.Converters.Add(new ShortDateConverter());
            });
 

Upvotes: 3

Muhammad Rehan Saeed
Muhammad Rehan Saeed

Reputation: 38457

By far the simplest method is to subclass the built in IsoDateTimeConverter class and set a different DateTimeFormat.

public class IsoDateConverter : IsoDateTimeConverter
{
    public IsoDateConverter() => 
        this.DateTimeFormat = Culture.DateTimeFormat.ShortDatePattern;
}

public class Foo
{
    [JsonConverter(typeof(IsoDateConverter))]
    public DateTimeOffset Date { get; set; }
}

Upvotes: 11

Sr.PEDRO
Sr.PEDRO

Reputation: 2067

You should use a proxy property for the serialization and mark the actual property as not serializable: Can you specify format for XmlSerialization of a datetime?

Upvotes: 0

L.B
L.B

Reputation: 116118

var json = JsonConvert.SerializeObject(
            new Person() { FirstName = "Joe", Birthday = DateTime.Now.AddDays(-2) },
            new ShortDateConverter()
            );

var p = JsonConvert.DeserializeObject<Person>(json,new ShortDateConverter());

or Decorate your field with [JsonConverter(typeof(ShortDateConverter))]

and use like

var json = JsonConvert.SerializeObject(new Person() 
                     { FirstName = "Joe", Birthday = DateTime.Now.AddDays(-2) } );

var p = JsonConvert.DeserializeObject<Person>(json);

public class ShortDateConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DateTime);
    }

    public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
    {
        return DateTime.ParseExact((string)reader.Value, "yyyy-MM-dd",CultureInfo.InvariantCulture);
    }

    public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
    {
        DateTime d = (DateTime)value;
        writer.WriteValue(d.ToString("yyyy-MM-dd"));
    }
}

Upvotes: 10

Alexander Schmidt
Alexander Schmidt

Reputation: 5723

What about:

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

    [JsonIgnore]
    public DateTime Birthday { get; set; }

    public string Birthdate 
    {
        get { return Birthday.ToShortDateString(); }   
        set {}     
    }
}

EDIT: After Habibs comment I changed it to ToShortDateString. If you want another transformation you could use ToString with the format-overload.

This depends on whether you need the whole thing bidirectional. Not sure if the empty setter is needed but I something in mind about that.

Another option could be using Json.NET serializer directly which gives you more power on what is happening including control over DateTime and others.

Upvotes: 4

Related Questions