简体   繁体   中英

Customize parameter in NSwag/ApiExplorer

I'm using NSwag to generate a Swagger document for my ASP.NET 6 API. My application uses strongly typed ids which are simple records with a value property.

public record Id(Guid Value);

Such ids are used as parameters in controller methods. Example:

public class MyController
{
    [HttpPost]
    public void Test(Id id)  {}
}

Execution wise this works fine. I have a custom model binder alongside with a factory that automatically handles binding from GUID strings. Same goes for serialization where a custom json converter handles this. To ensure that NSwag properly generates a string property I have a type mapper that maps Id properties as strings in the model.

The only remaining issue is that NSwag generates strange input parameters for my controller actions. It ends up looking like this:

在此处输入图像描述

I was able to dig into the code of NSwag and find the corresponding code for generating parameters. The OperationParameterProcessor uses the data generated by the api explorer provided by ASP.NET. The api explorer seems to interpret this property wrong and therefore generates two parameters instead of just a single one.

I was unable to find any resources on how to customize the behavior of the api explorer so you can customize models. How do I convince ASP.NET that my Id object is just a plain string instead of a complex object?

It seems that adding a pseudo type converter did the trick. I decorated my Id class with a custom type converter

internal class IdentityObjectTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) =>
        sourceType == typeof(string);
}

While this converter itself does not handle the value conversion it does provide ASP.NET with enough metadata so that the Api Explorer generated the proper definition. I would prefer a type converter over a model binder, however type converters are not flexible enough when it comes to polymorphism.

In the end the type converter fakes the type while the model binder does the actual binding. It's not ideal but probably the best solution as long as type converters are missing proper metadata when converting a value.

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM