diff --git a/Directory.Build.props b/Directory.Build.props index 5e38c7b..1b0caac 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ - 3.6.0 + 3.7.0 11.0 enable enable @@ -33,8 +33,8 @@ - 2.10.1 - 2.19.0 + 2.11.0 + 2.22.0 diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 7e3df45..fdfcc36 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,5 +1,9 @@ # Release Notes +## 3.7.0 + +* Update Facility and FacilityCSharp to add support for `datetime` fields. + ## 3.6.0 * Support `extern` data and enum types. diff --git a/conformance/ConformanceApi.fsd b/conformance/ConformanceApi.fsd index e51d494..ff35857 100644 --- a/conformance/ConformanceApi.fsd +++ b/conformance/ConformanceApi.fsd @@ -149,14 +149,13 @@ service ConformanceApi int32: int32; int64: int64; decimal: decimal; - - [validate] - enum: Answer; + [validate] enum: Answer; + datetime: datetime; }: { } - [http(method: GET, path: "/checkPath/{string}/{boolean}/{double}/{int32}/{int64}/{decimal}/{enum}")] + [http(method: GET, path: "/checkPath/{string}/{boolean}/{double}/{int32}/{int64}/{decimal}/{enum}/{datetime}")] method checkPath { string: string; @@ -165,9 +164,8 @@ service ConformanceApi int32: int32; int64: int64; decimal: decimal; - - [validate] - enum: Answer; + [validate] enum: Answer; + datetime: datetime; }: { } @@ -182,6 +180,7 @@ service ConformanceApi [http(from: header)] int64: int64; [http(from: header)] decimal: decimal; [http(from: header)] enum: Answer; + [http(from: header)] datetime: datetime; }: { [http(from: header)] string: string; @@ -191,6 +190,7 @@ service ConformanceApi [http(from: header)] int64: int64; [http(from: header)] decimal: decimal; [http(from: header)] enum: Answer; + [http(from: header)] datetime: datetime; } [http(path: "/mixed/{path}")] @@ -261,6 +261,7 @@ service ConformanceApi int32: int32; int64: int64; decimal: decimal; + datetime: datetime; bytes: bytes; object: object; error: error; @@ -280,6 +281,7 @@ service ConformanceApi int32: int32[]; int64: int64[]; decimal: decimal[]; + datetime: datetime[]; bytes: bytes[]; object: object[]; error: error[]; @@ -299,6 +301,7 @@ service ConformanceApi int32: map; int64: map; decimal: map; + datetime: map; bytes: map; object: map; error: map; @@ -318,6 +321,7 @@ service ConformanceApi int32: result; int64: result; decimal: result; + datetime: result; bytes: result; object: result; error: result; @@ -337,6 +341,7 @@ service ConformanceApi int32: nullable; int64: nullable; decimal: nullable; + datetime: nullable; bytes: nullable; object: nullable; error: nullable; diff --git a/conformance/ConformanceTests.json b/conformance/ConformanceTests.json index cb036f7..405be38 100644 --- a/conformance/ConformanceTests.json +++ b/conformance/ConformanceTests.json @@ -10,7 +10,8 @@ "int32": 42, "int64": 12345678910, "decimal": 1.5, - "enum": "yes" + "enum": "yes", + "datetime": "2001-02-03T04:05:06Z" }, "response": {} }, @@ -24,7 +25,8 @@ "int32": 42, "int64": 12345678910, "decimal": 1.5, - "enum": "yes" + "enum": "yes", + "datetime": "2001-02-03T04:05:06Z" }, "response": {} }, @@ -205,6 +207,7 @@ "int32": [42, 24], "int64": [12345678910, -987654321], "decimal": [1.5, 6.875], + "datetime": ["2001-02-03T04:05:06Z", "2023-08-10T19:41:21Z"], "bytes": ["aGk=", ""], "object": [{ "": null, " ": [null] }, {}], "error": [{ "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } }], @@ -227,6 +230,7 @@ "int32": [42, 24], "int64": [12345678910, -987654321], "decimal": [1.5, 6.875], + "datetime": ["2001-02-03T04:05:06Z", "2023-08-10T19:41:21Z"], "bytes": ["aGk=", ""], "object": [{ "": null, " ": [null] }, {}], "error": [{ "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } }], @@ -252,6 +256,7 @@ "int32": 42, "int64": 12345678910, "decimal": 1.5, + "datetime": "2001-02-03T04:05:06Z", "bytes": "aGk=", "object": { "": null, " ": [null] }, "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } }, @@ -267,6 +272,7 @@ "int32": 42, "int64": 12345678910, "decimal": 1.5, + "datetime": "2001-02-03T04:05:06Z", "bytes": "aGk=", "object": { "": null, " ": [null] }, "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } }, @@ -285,7 +291,8 @@ "int32": 42, "int64": 12345678910, "decimal": 1.5, - "enum": "yes" + "enum": "yes", + "datetime": "2001-02-03T04:05:06Z" }, "response": { "string": "string", @@ -294,7 +301,8 @@ "int32": 42, "int64": 12345678910, "decimal": 1.5, - "enum": "yes" + "enum": "yes", + "datetime": "2001-02-03T04:05:06Z" } }, { @@ -315,6 +323,7 @@ "int32": { "": 42, " ": 24 }, "int64": { "": 12345678910, " ": -987654321 }, "decimal": { "": 1.5, " ": 6.875 }, + "datetime": { "": "2001-02-03T04:05:06Z", " ": "2023-08-10T19:41:21Z" }, "bytes": { "": "aGk=", " ": "" }, "object": { "": { "": null, " ": [null] }, " ": {} }, "error": { "": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } }, " ": {} }, @@ -336,6 +345,7 @@ "int32": { "": 42, " ": 24 }, "int64": { "": 12345678910, " ": -987654321 }, "decimal": { "": 1.5, " ": 6.875 }, + "datetime": { "": "2001-02-03T04:05:06Z", " ": "2023-08-10T19:41:21Z" }, "bytes": { "": "aGk=", " ": "" }, "object": { "": { "": null, " ": [null] }, " ": {} }, "error": { "": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } }, " ": {} }, @@ -361,6 +371,7 @@ "int32": 42, "int64": 12345678910, "decimal": 1.5, + "datetime": "2001-02-03T04:05:06Z", "bytes": "aGk=", "object": { "": null, " ": [null] }, "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } }, @@ -381,6 +392,7 @@ "int32": 42, "int64": 12345678910, "decimal": 1.5, + "datetime": "2001-02-03T04:05:06Z", "bytes": "aGk=", "object": { "": null, " ": [null] }, "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } }, @@ -421,6 +433,7 @@ "int32": null, "int64": null, "decimal": null, + "datetime": null, "bytes": null, "object": null, "error": null, @@ -441,6 +454,7 @@ "int32": null, "int64": null, "decimal": null, + "datetime": null, "bytes": null, "object": null, "error": null, @@ -465,6 +479,7 @@ "int32": { "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, "int64": { "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, "decimal": { "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, + "datetime": { "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, "bytes": { "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, "object": { "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, "error": { "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, @@ -485,6 +500,7 @@ "int32": { "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, "int64": { "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, "decimal": { "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, + "datetime": { "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, "bytes": { "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, "object": { "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, "error": { "error": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, @@ -509,6 +525,7 @@ "int32": { "value": 42 }, "int64": { "value": 12345678910 }, "decimal": { "value": 1.5 }, + "datetime": { "value": "2001-02-03T04:05:06Z" }, "bytes": { "value": "aGk=" }, "object": { "value": { "": null, " ": [null] } }, "error": { "value": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, @@ -530,6 +547,7 @@ "int32": { "value": 42 }, "int64": { "value": 12345678910 }, "decimal": { "value": 1.5 }, + "datetime": { "value": "2001-02-03T04:05:06Z" }, "bytes": { "value": "aGk=" }, "object": { "value": { "": null, " ": [null] } }, "error": { "value": { "code": "code", "message": "message", "innerError": { "code": "code" }, "details": { "": null, " ": [null] } } }, @@ -767,7 +785,7 @@ "method": "checkPath", "httpRequest": { "method": "GET", - "path": "/CHECKPATH/pathCase/true/1.5/3/4/0.625/yes" + "path": "/CHECKPATH/pathCase/true/1.5/3/4/0.625/yes/2001-02-03T04:05:06Z" }, "request": { "string": "pathCase", @@ -776,7 +794,8 @@ "int32": 3, "int64": 4, "decimal": 0.625, - "enum": "yes" + "enum": "yes", + "datetime": "2001-02-03T04:05:06Z" }, "response": {} }, @@ -785,7 +804,7 @@ "method": "checkPath", "httpRequest": { "method": "GET", - "path": "/checkPath/booleanCase/TRUE/1.5/3/4/0.625/yes" + "path": "/checkPath/booleanCase/TRUE/1.5/3/4/0.625/yes/2001-02-03T04:05:06Z" }, "request": { "string": "booleanCase", @@ -794,7 +813,8 @@ "int32": 3, "int64": 4, "decimal": 0.625, - "enum": "yes" + "enum": "yes", + "datetime": "2001-02-03T04:05:06Z" }, "response": {} }, @@ -803,7 +823,7 @@ "method": "checkQuery", "httpRequest": { "method": "GET", - "path": "/CHECKQUERY?string=pathCase&boolean=true&double=1.5&int32=3&int64=4&decimal=0.625&enum=yes" + "path": "/CHECKQUERY?string=pathCase&boolean=true&double=1.5&int32=3&int64=4&decimal=0.625&enum=yes&datetime=2001-02-03T04:05:06Z" }, "request": { "string": "pathCase", @@ -812,7 +832,8 @@ "int32": 3, "int64": 4, "decimal": 0.625, - "enum": "yes" + "enum": "yes", + "datetime": "2001-02-03T04:05:06Z" }, "response": {} }, @@ -821,7 +842,7 @@ "method": "checkQuery", "httpRequest": { "method": "GET", - "path": "/checkQuery?STRING=queryCase&boolean=true&double=1.5&int32=3&int64=4&decimal=0.625&enum=yes" + "path": "/checkQuery?STRING=queryCase&boolean=true&double=1.5&int32=3&int64=4&decimal=0.625&enum=yes&datetime=2001-02-03T04:05:06Z" }, "request": { "string": "queryCase", @@ -830,7 +851,8 @@ "int32": 3, "int64": 4, "decimal": 0.625, - "enum": "yes" + "enum": "yes", + "datetime": "2001-02-03T04:05:06Z" }, "response": {} }, diff --git a/conformance/CoreControllerServer/Controllers/ConformanceApiController.g.cs b/conformance/CoreControllerServer/Controllers/ConformanceApiController.g.cs index 1864f21..234a9c5 100644 --- a/conformance/CoreControllerServer/Controllers/ConformanceApiController.g.cs +++ b/conformance/CoreControllerServer/Controllers/ConformanceApiController.g.cs @@ -62,7 +62,7 @@ public partial class ConformanceApiController return GetServiceHttpHandler().TryHandleCheckQueryAsync(httpRequest, cancellationToken); } - [HttpGet, Route("checkPath/{string}/{boolean}/{double}/{int32}/{int64}/{decimal}/{enum}")] + [HttpGet, Route("checkPath/{string}/{boolean}/{double}/{int32}/{int64}/{decimal}/{enum}/{datetime}")] public Task CheckPath(HttpRequestMessage httpRequest, CancellationToken cancellationToken = default(CancellationToken)) { return GetServiceHttpHandler().TryHandleCheckPathAsync(httpRequest, cancellationToken); diff --git a/conformance/WebApiControllerServer/Controllers/ConformanceApiController.g.cs b/conformance/WebApiControllerServer/Controllers/ConformanceApiController.g.cs index 03998ab..9b8a6f8 100644 --- a/conformance/WebApiControllerServer/Controllers/ConformanceApiController.g.cs +++ b/conformance/WebApiControllerServer/Controllers/ConformanceApiController.g.cs @@ -62,7 +62,7 @@ public partial class ConformanceApiController return GetServiceHttpHandler().TryHandleCheckQueryAsync(httpRequest, cancellationToken); } - [HttpGet, Route("checkPath/{string}/{boolean}/{double}/{int32}/{int64}/{decimal}/{enum}")] + [HttpGet, Route("checkPath/{string}/{boolean}/{double}/{int32}/{int64}/{decimal}/{enum}/{datetime}")] public Task CheckPath(HttpRequestMessage httpRequest, CancellationToken cancellationToken = default(CancellationToken)) { return GetServiceHttpHandler().TryHandleCheckPathAsync(httpRequest, cancellationToken); diff --git a/dotnet-tools.json b/dotnet-tools.json index 8e16642..93fafc8 100644 --- a/dotnet-tools.json +++ b/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "facilityconformance": { - "version": "2.19.0", + "version": "2.22.0", "commands": [ "FacilityConformance" ] diff --git a/src/Facility.AspNetCore/FacilityActionFilter.cs b/src/Facility.AspNetCore/FacilityActionFilter.cs index c365a23..c8bbbe7 100644 --- a/src/Facility.AspNetCore/FacilityActionFilter.cs +++ b/src/Facility.AspNetCore/FacilityActionFilter.cs @@ -7,8 +7,7 @@ public sealed class FacilityActionFilter : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext context) { - if (context.ActionArguments.ContainsKey(c_httpRequestKey) && - context.ActionArguments[c_httpRequestKey]!.GetType() == typeof(HttpRequestMessage)) + if (context.ActionArguments.TryGetValue(c_httpRequestKey, out var request) && request?.GetType() == typeof(HttpRequestMessage)) { context.ActionArguments[c_httpRequestKey] = FacilityAspNetCoreUtility.CreateHttpRequestMessage(context.HttpContext.Request); }