Search code examples
c#serializationjson.netrefitdateonly

How to serialize DateOnly using refit.?


I'm searching for this since 3-4 days I've almost got the answer but still I can't implement in my code. Actually I never understand or can't work by seeing the documentation. :/

And I need another suggestion as well I'm using date only because I need to implement a date range filter from and to some point of date and I don't need any time. Is this a right way or should I use DateTime.?

this link explain about C# DateOnly Serialization

This link explain about modification on Refit serialization options(I guess)


Solution

  • Try this minimal-reproducible-example below. When you create a Refit instance from an interface it's possible to pass some options and one of them is the ContentSerializer property where custom converters can be attached.

    using Refit;
    using System.Text.Json;
    using System.Text.Json.Serialization;
    
    var options = new JsonSerializerOptions();
    options.Converters.Add(new DateOnlyConverter());
    options.Converters.Add(new TimeOnlyConverter());
    
    var postmanEchoApi = RestService.For<IPostmanEchoApi>("https://postman-echo.com", new RefitSettings
    {
      ContentSerializer = new SystemTextJsonContentSerializer(options)
    });
    
    var echo = await postmanEchoApi.Echo(new Args
    {
      dateOnly = DateOnly.FromDateTime(DateTime.Now),
      timeOnly = TimeOnly.FromDateTime(DateTime.Now),
    });
    
    Console.WriteLine(echo.args.dateOnly);
    Console.WriteLine(echo.args.timeOnly);
    
    
    public class DateOnlyConverter : JsonConverter<DateOnly>
    {
      private readonly string serializationFormat;
    
      public DateOnlyConverter() : this(null) { }
    
      public DateOnlyConverter(string? serializationFormat)
      {
        this.serializationFormat = serializationFormat ?? "yyyy-MM-dd";
      }
    
      public override DateOnly Read(ref Utf8JsonReader reader,
                              Type typeToConvert, JsonSerializerOptions options)
      {
        var value = reader.GetString();
        return DateOnly.FromDateTime(DateTime.Parse(value!));
      }
    
      public override void Write(Utf8JsonWriter writer, DateOnly value,
                                          JsonSerializerOptions options)
          => writer.WriteStringValue(value.ToString(serializationFormat));
    }
    
    public class TimeOnlyConverter : JsonConverter<TimeOnly>
    {
      private readonly string serializationFormat;
    
      public TimeOnlyConverter() : this(null) { }
    
      public TimeOnlyConverter(string? serializationFormat)
      {
        this.serializationFormat = serializationFormat ?? "HH:mm:ss.fff";
      }
    
      public override TimeOnly Read(ref Utf8JsonReader reader,
                              Type typeToConvert, JsonSerializerOptions options)
      {
        var value = reader.GetString();
        return TimeOnly.FromDateTime(DateTime.Parse(value!));
      }
    
      public override void Write(Utf8JsonWriter writer, TimeOnly value,
                                          JsonSerializerOptions options)
          => writer.WriteStringValue(value.ToString(serializationFormat));
    }
    
    public class Args {
        public DateOnly dateOnly { get; set; }
        public TimeOnly timeOnly { get; set; }
    }
    
    public class Echo
    {
        public Args args { get; set; }
    }
    
    [Headers("user-agent: curl/7.79.1")]
    public interface IPostmanEchoApi
    {
      [Get("/get")]
      Task<Echo> Echo(Args queryParams);
    }