Rupesh Plant
Rupesh Plant

Reputation: 45

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)

Upvotes: 1

Views: 1294

Answers (1)

lepsch
lepsch

Reputation: 10379

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);
}

Upvotes: 4

Related Questions