Versions: Swashbuckle 6.5, .Net 7
We need to pass environment parameters into our controller methods. Those parameters are set with custom model binders. Here is a simple example for the IP address:
[Route("/api/persons")]
[HttpGet]
public ActionResult Get(
[ModelBinder(typeof(IPAddressBinder))] IPAddress? ipAddress)
{
...
}
The ipAddress
parameter will be shown as an object in Swagger, but it should be hidden, since it is not provided by the standard request parameters.
There are many posts on stackoverflow, GitHub, and blogs about programming a custom [SwaggerIgnore]
attribute or using the Swashbuckle.AspNetCore.Annotations
extension library that offers [SwaggerSchema(ReadOnly = true)]
. None of those have worked for me and I couldn't figure out why. Maybe they dont't work with custom model binders. A problem is that many posts use older libraries and frameworks.
I came up with a simple solution using the [FromServices]
attribute. I read that its purpose is to offer dependency injection though methods. But if I don't use an interface type and have no injection definition in the container it works really well. Since the parameter is filled by a service and not by the request payload it made sense to me.
[Route("/api/persons")]
[HttpGet]
public ActionResult Get(
[FromServices, ModelBinder(typeof(IPAddressBinder))] IPAddress? ipAddress)
{
...
}
Can I use this approach or does it have any unwanted side effects that I'm not aware of?
Additional Information:
I have been testing this approach using a record collecting multiple parameters:
[Route("/api/persons")]
[HttpGet]
public ActionResult<RequestAttributes> GetPersons(
[FromQuery] RequestAttributes requestAttributes)
{
return Ok(requestAttributes);
}
public record RequestAttributes
{
[FromHeader(Name = "Accept-Language"), ModelBinder(typeof(LanguageBinder))]
public List<Language> preferredLanguages { get; init; } = new();
[FromServices, ModelBinder(typeof(EnvironmentBinder))]
public IPAddress? ipAddress { get; init; }
[FromQuery(Name = "lang")]
public string? selectLanguage { get; init; }
}
The [FromServices]
attribute still works when I use the record class
syntax for RequestAttributes
. Only when I use the record struct
syntax it fails to work. Swagger then displays the ipAddress
parameter.