Reputation: 117146
How to force a single property to format as a Date and not a DateTime when serializing to Json? I am using System.Text.Json.Serialization
NOT newtonsoft json, any solutions requiring that I use NewtonSoft jSon will not help.
I have an object which has two datetime properties in it, one is actually a date though and not a datetime.
[JsonPropertyName("startDate")]
public DateTime StartDate { get; set; }
[JsonPropertyName("startDate")]
public DateTime ActionDateTime { get; set; }
When I set it I specify that it is in fact a date.
StarDate = DateTime.Now.Date,
However when I try to serialize it to JSon
var json = JsonSerializer.Serialize(this);
I get
{"startDate":"2021-05-20T00:00:00+02:00"}
The problem being that the API endpoint I am sending this to is complaining about it being a datetime, it needs to serialize as a date. I know I could use JsonSerializerOptions but this will serialize all of the dates and I cant have that.
full code sample for your testing enjoyment
public class Dummy
{
[JsonPropertyName("startDate")]
public DateTime StartDate { get; set; }
[JsonPropertyName("actiondatetime ")]
public DateTime ActionDateTime { get; set; }
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var hold = new Dummy();
hold.StartDate = DateTime.Now.Date;
hold.ActionDateTime = DateTime.Now
var json = JsonSerializer.Serialize(hold);
Console.WriteLine(json);
Console.ReadLine();
}
}
I have searched high and low there must be a way of adding an attribute to force the single property to format as a date.
Upvotes: 1
Views: 2368
Reputation: 1177
The most simple way is create a "setter property" to set serializable property.
//....else....
[JsonIgnore]
public DateTime StartDateSetter { set => StartDate = value.ToString("d"); }
[JsonPropertyName("startDate")]
public string StartDate { get; private set; }
//....else....
Because of DateTime
in json will be a string, so it doesn't matter whether the source of date/time is a DateTime
or string
.
Upvotes: 0
Reputation: 1030
You can create a "ShortDate" type that have a DateTime property and create a JsonSerializerOptions for this format tha basically transform the Date field to the ToShortDateString() format on serialization.
Something like this:
public class ShortDateConverter : JsonConverter<ShortDate>
{
public override ShortDate ReadJson(JsonReader reader, Type objectType, ShortDate existingValue, bool hasExistingValue, JsonSerializer serializer)
{
return new ShortDate()
{
Date = DateTime.Parse((string)reader.Value)
};
}
public override void WriteJson(JsonWriter writer, ShortDate value, JsonSerializer serializer)
{
writer.WriteValue(value.Date.ToShortDateString());
}
}
public class ShortDate
{
[JsonProperty("date")]
public DateTime Date { get; set; }
public string ShotDateString => Date.ToShortDateString();
}
And using like this:
class Program
{
static async Task Main(string[] args)
{
var ds = new ShortDate() { Date = DateTime.Now };
var json = JsonConvert.SerializeObject(dh, new JsonSerializerSettings() { Converters = new List<JsonConverter> { new ShortDateConverter() } });
Console.WriteLine(json);
var obj = JsonConvert.DeserializeObject<ShortDate>(json, new JsonSerializerSettings() { Converters = new List<JsonConverter> { new ShortDateConverter() } });
Console.WriteLine(obj);
}
}
Of couse you will need to add validations and stuff, and register this converter on your app to not have to always specifie the formatter you want for this type. But this is the basic idea.
Upvotes: -1
Reputation: 4453
It looks like a custom converter applied using the JsonConverter
attribute can do what you want. The following is sample code from the linked article:
Converter:
public class DateTimeOffsetJsonConverter : JsonConverter<DateTimeOffset>
{
public override DateTimeOffset Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options) =>
DateTimeOffset.ParseExact(reader.GetString(),
"MM/dd/yyyy", CultureInfo.InvariantCulture);
public override void Write(
Utf8JsonWriter writer,
DateTimeOffset dateTimeValue,
JsonSerializerOptions options) =>
writer.WriteStringValue(dateTimeValue.ToString(
"MM/dd/yyyy", CultureInfo.InvariantCulture));
}
Applied using attribute:
public class WeatherForecastWithConverterAttribute
{
[JsonConverter(typeof(DateTimeOffsetJsonConverter))]
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string Summary { get; set; }
}
Upvotes: 3