AJ Tatum
AJ Tatum

Reputation: 713

How can I tell Swashbuckle 5 that the body content is required in dotnetcore 3.0?

I'm trying to implement Swashbuckle 5 and I have a couple of methods that read the Request Body like so:

var requestBody = await Request.GetRawBodyStringAsync();

How can I tell Swashbuckle/Swagger to read that as a parameter so that people can test out my API? I saw a very similar question being asked here but that was for Binary content and for earlier versions of Swashbuckle.

Any help would be greatly appreciated!

Upvotes: 3

Views: 4411

Answers (1)

Aleš Doganoc
Aleš Doganoc

Reputation: 12062

As you already discovered in Swashbuckle 5 it is different because it switched to using the Microsoft OpenApi.NET SDK. This is why the object model is different. Else it still works in the same way as the sample in the post you linked. I have translated the case to your scenario where you want to send a raw text string.

Create a custom Attribute to flag the methods that read raw strings. For example:

public class RawTextRequestAttribute : Attribute
{
   public RawTextRequestAttribute()
   {
      MediaType = "text/plain";
   }

   public string MediaType { get; set; }
}

To modify the Swagger definition you need a Swashbuckle operation filter that will check for this attribute and if found customize the the request body to be a plain string. Here is a sample implementation to do that:

public class RawTextRequestOperationFilter : IOperationFilter
{
   public void Apply(OpenApiOperation operation, OperationFilterContext context)
   {
      RawTextRequestAttribute rawTextRequestAttribute = context.MethodInfo.GetCustomAttributes(true)
         .SingleOrDefault((attribute) => attribute is RawTextRequestAttribute) as RawTextRequestAttribute;
      if (rawTextRequestAttribute != null)
      {
         operation.RequestBody = new OpenApiRequestBody();
         operation.RequestBody.Content.Add(rawTextRequestAttribute.MediaType, new OpenApiMediaType() 
         {
            Schema = new OpenApiSchema()
            {
               Type = "string"
            }
         });
      }
   }
}

For the filter to be used you need to register it in the startup when you configure Swagger.

public void ConfigureServices(IServiceCollection services)
{
   services.AddControllers();
   services.AddSwaggerGen(c =>
   {
      c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
      c.OperationFilter<RawTextRequestOperationFilter>();
   });
}

Then you add the attribute to the Methods where you read the raw request. For Example:

[HttpPost]
[RawTextRequest]
public async Task Post()
{
   var requestBody = await Request.GetRawBodyStringAsync();
   _logger.LogDebug(requestBody);
}

The result is that you get a text input box for the body of the request in Swagger UI.

Swagger UI

Upvotes: 11

Related Questions