background
When we usually write the interface, such a problem cannot be avoided. The field type stored in the database is datetime
, and the corresponding entity class in the code is also DateTime
a type field, so the data returned after reading the database content is also DateTime
a type value, for example 2022-10-24 18:34:56.110
, But for server requesters, they may only need to display the year, month, and day, and the subsequent hours, minutes, and seconds are not needed. If we can convince them that we don't need to modify our code, the day is the best. So for our service providers, how to deal with such problems?
Implementation method 1
You can directly modify the returned entity class DateTime
to string, and the format can be customized, but the disadvantages are also obvious.
1. Unable to use
ToList
,MapTo
etc. toDateTime
directly convert the value read in the database intoString
.
2. If there are multiple interfaces that need to be modified, it will be troublesome.
3. The applicable situation is single. If there are other field types to modify, it will be troublesome.
Implementation method 2 (recommended)
Use JsonConverterAttribute
classes and JsonConverter<T>
classes, and modify them by adding attribute classes to attributes.
The brief steps to implement are as follows.
Here I create a ASP.NET Core Web API
new project to demonstrate. After the project is built, the content is as follows.
WeatherForecastController.cs
The content is as follows.
using Microsoft.AspNetCore.Mvc;
namespace DateTime返回年月日.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}
In Get
the interface, an array of one is returned WeatherForecast
. In this entity class, there is a DateTime
type field Date
. We request the interface to see the return value.
As you can see here, Date
the field returns a string containing the year, month, day, and time zone.
WeatherForecast
The entity class is as follows
using System.Text.Json.Serialization;
namespace DateTime返回年月日
{
public class WeatherForecast
{
public DateTime Date {
get; set; }
public int TemperatureC {
get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary {
get; set; }
}
}
Here comes the point. Refer to https://docs.microsoft.com/zh-cn/dotnet/api/system.text.json.serialization.jsonconverterattribute?view=net-6.0
JsonConverterAttribute
to specify a converter class by reflection. Then we create a new DateOnlyConverter
class named , inherit JsonConverter<T>
this generic class, and specify the type as DateTime
follows.
using System.Text.Json;
using System.Text.Json.Serialization;
namespace DateTime返回年月日
{
public class DateOnlyConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString("yyyy-MM-dd"));
}
}
}
JsonConverter<T>
Containing two abstract interfaces must add the corresponding implementation, Read
and Write
we only need to modify the specific Write
method, and the implementation content is also very simple, that is, to convert the corresponding type.
Finally, add the corresponding features to the properties WeatherForecast
of the class .Date
using System.Text.Json.Serialization;
namespace DateTime返回年月日
{
public class WeatherForecast
{
[JsonConverter(typeof(DateOnlyConverter))]
public DateTime Date {
get; set; }
public int TemperatureC {
get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
public string? Summary {
get; set; }
}
}
Finally, let's look at the results of the call.
By adding features, there is no need to modify the type of the entity class, nor to modify the specific business logic.
epilogue
Reference content:
https://docs.microsoft.com/zh-cn/dotnet/api/system.text.json.serialization.jsonconverter-1?view=net-6.0
have a wonderful day.