简体   繁体   中英

SwashBuckle define Response Body on Error

My application is an ASP.NET Core 1.0 Web API.

I have the following Controller:

    [HttpGet("{someData:MinLength(5):MaxLength(5)}")]
    [Produces("application/json")]
    public async Task<IActionResult> GetSomeData(string someData)
    {
        return this.Ok(JsonConvert.SerializeObject("Data is: " + someData));
    }

Whenever I pass for example the string "111", swagger is showing me the following message:

在此输入图像描述

How can i achive a Response Body like:

"Please enter 5 numbers"

Thank you

You can annotate your actions with [ProducesResponseType(typeof(ModelStateDictionary), (int)HttpStatusCode.OK)] to return the typical Dictionary typed error messages like when using return BadRequest(ModelState) .

But you can't return a text in the schema definition. It is there for json structures, not for error messages. Instead you should use xmldoc (and also enable it in swagger) to add descriptions to the parameters.

Update: Alternative of adding documentation of the parameters and their meaning

/// <summary>
/// Returns some data based on <paramref name="someData"/> parameter.
/// </summary>
/// <param name="someData">Some data. (Must be exactly 5 characters wide)</param>
/// <response code="200">Returns indexed tags on success</response>
/// <response code="400">Invalid data sent</response>
/// <returns>A paged list of results</returns>
[HttpGet("{someData:MinLength(5):MaxLength(5)}")]
[ProducesResponseType(typeof(MyReturnType), (int)HttpStatusCode.OK)]
[ProducesResponseType(typeof(void), (int)HttpStatusCode.BadRequest)]
public async Task<IActionResult> GetSomeData(string someData)
{
}

Also you need to enable building of xmldocs in your project's properties.

And add to your startup:

services.AddSwaggerGen(options =>
{
    ...
    var appEnv = PlatformServices.Default.Application;

    options.IncludeXmlComments(Path.Combine(appEnv.ApplicationBasePath, $"{appEnv.ApplicationName}.xml"));
    ...
});

I am using ApiBadRequestResponse class , that constructs list of strings from modelState instead of direct ModelState. The class copied from a nice article https://www.devtrends.co.uk/blog/handling-errors-in-asp.net-core-web-api .

Example of use:

 [ProducesResponseType(typeof(ApiBadRequestResponse), (int)HttpStatusCode.BadRequest)]
 public async Task<IActionResult> GetSomeData(string someData)
 {
   return BadRequest(new ApiBadRequestResponse(ModelState));
 }

Implementation ( base class described in the article ):

/// <summary>
    ///  an ApiBadRequestResponse class to handle validation errors from modelState or exception.
    /// </summary>
    public class ApiBadRequestResponse : ApiResponse
    {
        public IEnumerable<string> Errors { get; }

        public ApiBadRequestResponse(ModelStateDictionary modelState)
            : base(HttpStatusCode.BadRequest) //400)
        {
            if (modelState.IsValid)
            {
                throw new ArgumentException("ModelState must be invalid", nameof(modelState));
            }

            Errors = modelState.SelectMany(x => x.Value.Errors)
                .Select(x => x.ErrorMessage).ToArray();
        }

        public ApiBadRequestResponse(Exception exception, string message=null)
            : base(HttpStatusCode.BadRequest, message) //400)
        {
            Errors = new List<string>() {exception.ToString()};
        }
    }

Another similar solution is in the article http://www.khalidabuhakmeh.com/a-better-validation-result-for-asp-net-webapi

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