Open aureole82 opened 4 years ago
When I create a very simple Swagger API:
public void ConfigureServices(IServiceCollection services) { services .AddControllers() .AddNewtonsoftJson(options => { options.SerializerSettings.Converters.Add(new StringEnumConverter()); // We only allow undefined in TS. So ignore null properties. options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; }) ; // Register the Swagger services. services.AddSwaggerDocument(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ... // Register the Swagger generator and the Swagger UI middleware. app.UseOpenApi(); app.UseSwaggerUi3(); ... }
with this Controller Action:
[HttpGet("city/{city}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(typeof(OtherException), StatusCodes.Status400BadRequest)] [ProducesResponseType(typeof(CityNotFoundException), StatusCodes.Status404NotFound)] public async Task<ActionResult<WeatherForecast[]>> Get(string city) { try { return Ok(await _Get(city)); } catch (CityNotFoundException e) { return NotFound(e); } catch (OtherException e) { return BadRequest(e); } }
the "definitions" schema looks like:
{ "WeatherForecast": { "type": "object", "required": [ "date", "temperatureC", "temperatureF" ], "properties": { "city": { "type": "string" }, "date": { "type": "string", "format": "date-time" }, "temperatureC": { "type": "integer", "format": "int32" }, "temperatureF": { "type": "integer", "format": "int32" }, "summary": { "type": "string" } } }, "OtherException": { "allOf": [ { "$ref": "#/definitions/Exception" }, { "type": "object", "required": [ "timestamp" ], "properties": { "timestamp": { "type": "string", "format": "date-time" } } } ] }, "Exception": { "type": "object", "required": [ "Message" ], "properties": { "StackTrace": { "type": "string" }, "Message": { "type": "string" }, "InnerException": { "$ref": "#/definitions/Exception" }, "Source": { "type": "string" } } }, "CityNotFoundException": { "allOf": [ { "$ref": "#/definitions/Exception" }, { "type": "object" } ] } }
You'll notice the properties of base Exception are all pascal case. That's wrong because the response will be camel case:
Exception
{ "timestamp": "2020-09-24T15:50:55.1297797+02:00", "stackTrace": " at WebApplication1.Controllers.WeatherForecastController._Get(String city) in C:\\Users\\xxx\\Projects\\WebApplication1\\WebApplication1\\Controllers\\WeatherForecastController.cs:line 50\r\n at WebApplication1.Controllers.WeatherForecastController.Get(String city) in C:\\Users\\xxx\\Projects\\WebApplication1\\WebApplication1\\Controllers\\WeatherForecastController.cs:line 34", "message": "City required: -", "data": {}, "source": "WebApplication1", "hResult": -2146233088 }
This would result in buggy generated clients, e.g. Typescript:
export class Exception implements IException { ... init(_data?: any) { if (_data) { this.stackTrace = _data["StackTrace"]; // FAIL! this.message = _data["Message"]; // FAIL! this.innerException = _data["InnerException"] ? Exception.fromJS(_data["InnerException"]) : <any>undefined; // FAIL! this.source = _data["Source"]; // FAIL! } } ... }
WebApplication1.zip
I think you need this: https://github.com/RicoSuter/NSwag/wiki/JsonExceptionFilterAttribute
When I create a very simple Swagger API:
with this Controller Action:
the "definitions" schema looks like:
You'll notice the properties of base
Exception
are all pascal case. That's wrong because the response will be camel case:This would result in buggy generated clients, e.g. Typescript:
WebApplication1.zip