-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Inconsistent DateTime UTC conversion between Response and Parameters #2770
Comments
It seems this is a bug in ASP.Net Core, which NSwag has no influence over. More details can be found here: dotnet/aspnetcore#11584. |
I can confirm there is a bug within NSwag from the point of view of the request - not related to the ASP .NET Core bug dotnet/aspnetcore#11584 referenced above (which causes issues on the response). Reproduced with the latest version of NSwag.CodeGeneration.CSharp as of this writing (v13.8.2). Given a Controller/Action that looks like this: [HttpGet("test/{value:datetime}")]
[ProducesResponseType(typeof(DateTime), StatusCodes.Status200OK)]
public IActionResult GetDateAndReturnDate(DateTime value)
{
return Ok(value);
} Generating a client with NSwag results in the following client code being generated: // ...
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append("test/{value}");
urlBuilder_.Replace("{value}", System.Uri.EscapeDataString(value.ToString("s",
System.Globalization.CultureInfo.InvariantCulture)));
// ... As can be seen, the generated code is assuming a
Expected:
Swagger definition from the Controller above {
"/test/{value}": {
"get": {
"tags": [
"Test"
],
"operationId": "Test_GetDateAndReturnDate",
"produces": [
"text/plain",
"application/json",
"text/json"
],
"parameters": [
{
"type": "string",
"name": "value",
"in": "path",
"required": true,
"format": "date-time",
"x-nullable": false
}
],
"responses": {
"200": {
"x-nullable": false,
"description": "",
"schema": {
"type": "string",
"format": "date-time"
}
}
}
}
}
} |
A workaround for now is to set the This should work for most cases when all APIs handle DateTime the same way. Of course, this is not ideal given that each API client can have a different This is what I ended up with: var clientSettings = new CSharpClientGeneratorSettings
{
ClientBaseClass = "ApiClientBase",
ClientClassAccessModifier = "internal",
GenerateUpdateJsonSerializerSettingsMethod = false,
// Inconsistent DateTime UTC conversion between Response and Parameters #2770
// https://github.com/RicoSuter/NSwag/issues/2770
ParameterDateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'FFFFFFFZ",
CSharpGeneratorSettings =
{
DateType = "System.DateTime",
DateTimeType = "System.DateTime",
// ...
},
// ...
}; internal abstract class ApiClientBase
{
protected void UpdateJsonSerializerSettings(JsonSerializerSettings settings)
{
// Json.NET interprets and modifies ISO dates when deserializing to JObject #862
// https://github.com/JamesNK/Newtonsoft.Json/issues/862
settings.DateParseHandling = DateParseHandling.None;
// Inconsistent DateTime UTC conversion between Response and Parameters #2770
// https://github.com/RicoSuter/NSwag/issues/2770
settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
}
} |
I am using NSwag to generate a controller.
I have a DateTime field in my response, which is generated as follows:
/// <summary>The UTC timestamp.</summary> [Newtonsoft.Json.JsonProperty("timestamp", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)] public System.DateTime Timestamp { get; set; }
The yaml definition is:
timestamp: description: The UTC timestamp. type: string format: date-time
The DateTime value in my c# is always DateTimeKind.Utc and in the response it undergoes no conversion to local time, and has a value such as: "timestamp": "2020-04-03T09:33:52.784818Z" in the json.
However I have now added a DateTime query parameter, defined as follows in the yaml file:
name: fromdate in: query type: string format: date-time required: false
The parameter in my c# code generated method is as follows:
[Microsoft.AspNetCore.Mvc.FromQuery] System.DateTime? fromdate = null
I now pass in a value for this parameter in the API call, e.g. the one returned above as follows, via Postman:
requests?fromDate=2020-04-03T09:33:52.784818Z
The problem here is that the value in my fromDate DateTime parameter in the method call has undergone a utc/local time conversion (in my case it is 11:33 not 09:33), which does not occur when a DateTime value is returned in the response.
I would expect the value to have had no conversion and be the exact same value as that passed in.
I tried setting the configuration parameter as follows "parameterDateTimeFormat": "u" in the hope that specifying the UTC format instead of the default "s" format would influence this, but it had no effect.
I have attached my nswag configuration file.
Can anyone explain the behavior - do I need to configure something, is it a bug, etc.?
Thank you!
api.txt
The text was updated successfully, but these errors were encountered: