-
Notifications
You must be signed in to change notification settings - Fork 221
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
C# .NET HttpValidationProblem not working (or at least extremely unergonomic) #4862
Comments
Hi @linde12 |
Hi @baywet I was celebrating a Swedish holiday so excuse the delay 😄 Here is a full OAS: {
"openapi": "3.0.1",
"info": {
"title": "ex",
"version": "1.0"
},
"paths": {
"/weatherforecast": {
"get": {
"tags": [
"ex"
],
"operationId": "GetWeatherForecast",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WeatherForecast"
}
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/HttpValidationProblemDetails"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"DateOnly": {
"type": "object",
"properties": {
"year": {
"type": "integer",
"format": "int32"
},
"month": {
"type": "integer",
"format": "int32"
},
"day": {
"type": "integer",
"format": "int32"
},
"dayOfWeek": {
"$ref": "#/components/schemas/DayOfWeek"
},
"dayOfYear": {
"type": "integer",
"format": "int32",
"readOnly": true
},
"dayNumber": {
"type": "integer",
"format": "int32",
"readOnly": true
}
},
"additionalProperties": false
},
"DayOfWeek": {
"enum": [
0,
1,
2,
3,
4,
5,
6
],
"type": "integer",
"format": "int32"
},
"HttpValidationProblemDetails": {
"type": "object",
"properties": {
"type": {
"type": "string",
"nullable": true
},
"title": {
"type": "string",
"nullable": true
},
"status": {
"type": "integer",
"format": "int32",
"nullable": true
},
"detail": {
"type": "string",
"nullable": true
},
"instance": {
"type": "string",
"nullable": true
},
"errors": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"type": "string"
}
},
"nullable": true
}
},
"additionalProperties": { }
},
"WeatherForecast": {
"type": "object",
"properties": {
"date": {
"$ref": "#/components/schemas/DateOnly"
},
"temperatureC": {
"type": "integer",
"format": "int32"
},
"summary": {
"type": "string",
"nullable": true
},
"temperatureF": {
"type": "integer",
"format": "int32",
"readOnly": true
}
},
"additionalProperties": false
}
}
}
} This is generated from a standard WebAPI application, and my endpoint looks like so: static Results<Ok<WeatherForecast[]>, ValidationProblem> GetWeatherForecast()
{
if (Random.Shared.Next(0, 2) == 0)
{
var errors = new Dictionary<string, string[]>
{
{ "username", new[] { "Required" } }
};
return TypedResults.ValidationProblem(errors);
}
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
"Freezing"
))
.ToArray();
return TypedResults.Ok(forecast);
}
app.MapGet("/weatherforecast", GetWeatherForecast)
.WithName("GetWeatherForecast")
.WithOpenApi()
.ProducesValidationProblem(); and 50% of the time it will produce a validation problem response containing an error like so (retrieved with curl): {"type":"https://tools.ietf.org/html/rfc9110#section-15.5.1","title":"One or more validation errors occurred.","status":400,"errors":{"username":["Required"]}} Then i am using the generated client from Kiota like so: using ApiSdk;
using Microsoft.Kiota.Abstractions.Authentication;
using Microsoft.Kiota.Http.HttpClientLibrary;
var adapter = new HttpClientRequestAdapter(new AnonymousAuthenticationProvider());
adapter.BaseUrl = "http://localhost:5117";
var client = new ApiClient(adapter);
try
{
var res = await client.Weatherforecast.GetAsync();
}
catch (ApiSdk.Models.HttpValidationProblemDetails problem)
{
var errors = problem.Errors; // type is HttpValidationProblemDetails_errors, only contains a "AdditionalData" field
foreach (var error in errors.AdditionalData)
{
Console.WriteLine($"Error: {error.Key} - {error.Value}");
}
} This piece of code will print the following when an error occurs:
I'd expect to be able to do the following (according to OAS): var errors = problem.Errors; // type is HttpValidationProblemDetails_errors, only contains a "AdditionalData" field
foreach (var error in errors.AdditionalData)
{
Console.WriteLine($"Error: {error.Key}");
foreach (var message in error.Value)
{
Console.WriteLine($"{message}"); // print every error message for the given key
}
} but this does not work since |
The OpenAPI Schema was generated using the standard I'm not sure how i should work with validation errors here. |
At the moment, the type information for the isn't used by the deserializer for the items in the additionalData. So they are represented using UntypedNodes as documented at https://learn.microsoft.com/en-us/openapi/kiota/serialization?tabs=csharp#untyped-node. Any chance you are able to print out the information with the code below? foreach (var error in errors.AdditionalData)
{
Console.WriteLine($"Error: {error.Key}");
if (error.Value is UntypedArray arrayValue)
{
foreach (var message in arrayValue.GetValue())
{
if (message is UntypedString messageString)
Console.WriteLine($"{messageString.GetValue()}"); // print every error message for the given key
}
}
} |
@andrueastman Ah, that explains it. Is this something that is being actively worked or something that's planned? We ended up with a similar workaround to reach the wanted values, it was just a bit cumbersome and we had to do some digging to understand how to approach this. Thank you for prompt replies 🙏 |
Hi everyone, |
What are you generating using Kiota, clients or plugins?
API Client/SDK
In what context or format are you using Kiota?
Linux executable
Client library/SDK language
Csharp
Describe the bug
I'm generating towards an endpoint that returns a .NET
HttpProblemResult
or anything that produces a problem details response, but when i instead switch to the built-inValidationProblem
(e.g.return TypedResults.ValidationProblem(errors);
from my endpoint) and annotate the endpoint with.ProducesValidationProblem();
Kiota produces an extremely unusable client.The generated OpenAPI Schema (from the .NET application) is fine (see screenshot), and in the generated .NET client there is a
ex.Errors
which in turn contains anAdditionalData
dictionary. This dictionary is not what you would expect though (Dictionary<string, string[]>
of errors) but a dict containing one key ("errors") which is anMicrosoft.Kiota.Abstractions.Serialization.UntypedArray
As it stands, by following the problem details standard and using the
ValidationProblem
provided by .NET, Kiota generates a pretty unusable or at least very unergonomic (i have not looked into UntypedArray) exception for non-200 OK situations.Expected behavior
I expect Kiota to follow the API Schema (see screenshot in description above) and generate a
MyApi.Models.HttpValidationProblemDetails
exception which contains aErrors
(alternativelyErrors.AdditionalData
if thats some convention Kiota follows?) that is of typeDictionary<string, string[]>
)The OpenAPI Schema clearly states that
errors
is an object where eachadditionalProperty
(every property in this case) is an array of strings.How to reproduce
Create e.g. a .NET Minimal API endpoint that produces the schema above and make the endpoint throw return a
TypedResults.ValidationProblem
and "annotate" the route with theProducesValidationProblem
method. Generate a client and look at theHttpValidationProblemDetails.cs
Open API description file
Cannot provide since it is confidential, but would be willing to produce a more complete minimally reproducible example if this is written off as expected behavior.
Kiota Version
1.14
Latest Kiota version known to work for scenario above?(Not required)
No response
Known Workarounds
No response
Configuration
No response
Debug output
No response
Other information
No response
The text was updated successfully, but these errors were encountered: