1

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)

1 Answers1

4

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);
}
lepsch
  • 8,927
  • 5
  • 24
  • 44
  • Thank you so much for helping and giving time. However I'd already managed to work around some hoe As I was doing this in my existing code which was written by other seniors It looks like this It's similar but done slight differently. Had added all the default serialization options as didin't work out using them. Have commented the code below as It may help others as well. – Rupesh Plant Aug 08 '22 at 16:08
  • Serialiazation options: `var jsonSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web); jsonSerializerOptions.Converters.Add(new DateOnlyJsonConverter()); jsonSerializerOptions.PropertyNameCaseInsensitive = true; jsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; jsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter()); jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)); ` – Rupesh Plant Aug 08 '22 at 16:09
  • Refit Settings: `services.AddRefitClient(new RefitSettings() { ContentSerializer = new SystemTextJsonContentSerializer(jsonSerializerOptions), }).ConfigureHttpClient(c => { c.BaseAddress = new Uri(config.GetSection("ApiServiceUrls:APIUrl").Value); }).AddHttpMessageHandler();` – Rupesh Plant Aug 08 '22 at 16:10