Search code examples
c#asp.net.netswagger-ui.net-8.0

Make record JSON-convertible as `string` in SwaggerUI


I have a record that implements string conversion:

[JsonConverter(typeof(ExamplePropJsonConverter))]
public record ExampleProp
{
    private string? Value { get; init; }
    
    public static implicit operator string(ExampleProp value) => value.Value ?? throw new ArgumentNullException();
    public static implicit operator ExampleProp(string value) => new ExampleProp() { Value = value };
    public override string ToString() => (string)this;
}

public class ExamplePropJsonConverter : JsonConverter<ExampleProp>
{
    public override ExampleProp Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
        reader.GetString() ?? throw new ArgumentNullException();
    public override void Write(Utf8JsonWriter writer, ExampleProp value, JsonSerializerOptions options) => 
        writer.WriteStringValue(value);
}

I want it to make JSON representation in API as ordinary string easy way.

And I have controller:

[HttpPost("/ep-test")]
public IResult TestEP([FromBody] ExampleProp ep) => Results.Json(ep);

[HttpPost("/string-test")]
public IResult TestString([FromBody] string s) => Results.Json(s);

[HttpPost("/string-as-ep-test")]
public IResult TestStringAsEP([FromBody] string s) => Results.Json((ExampleProp)s);

It works OK except SwaggerUI:

In SwaggerUI I see:

  • /ep-test
    Example value: {}
    Schema: ExampleProp:{}

And I would like to see scheme like url has, or at least string:

  • /ep-test
    Example value: "string"
    Schema: ExampleProp: string
  • /ep-test
    Example value: "examplePropFormat"
    Schema: ExampleProp: string($exampleProp)

I expect that there may be some magic attribute I'm missing like [JsonConvertAs(typeof(string))] that may both throw away explicit converter implementation and tell Swagger to interpret type as string.


Solution

  • You should add these lines to your Program.cs:

    builder.Services.AddSwaggerGen(o =>
    {
        o.MapType<ExampleProp>(() => new OpenApiSchema { Type = "string" });
    });
    

    More info: https://github.com/domaindrivendev/Swashbuckle.AspNetCore#override-schema-for-specific-types