【发布时间】:2017-08-24 01:41:42
【问题描述】:
我在我的 WepAPI OData Web 服务中集成了 Swashbuckle.OData 3.2.0 和 Swashbuckle.Core 5.5.3 以生成 Swagger 文档。
当我尝试访问 swagger 端点(http://localhost:52460/swagger)时,出现以下异常,这似乎是由一个函数(AppointmentsForUsers)引起的,该函数采用 Microsoft.OData.Edm.Date 类型的 2 个参数(没有时间的日期类型零件)。
当我在我的 Register 函数中注释掉 var function = builder,Function...part 时,一切正常,
当我将参数类型 Microsoft.OData.Edm.Date 替换为 System.DateTimeOffset 时,它也可以正常工作,但这不是我们/我们项目的解决方案。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<UserDTO>("Users");
builder.EntitySet<AppointmentDTO>("Appointments");
var function = builder.Function("AppointmentsForUsers");
function.ReturnsCollectionFromEntitySet<AppointmentDTO>("Appointments");
function.Parameter<Date>("FromDate");
function.Parameter<Date>("ToDate");
function.CollectionParameter<int>("UserIds");
config.MapODataServiceRoute(
routeName: "odata",
routePrefix: "odata",
model: builder.GetEdmModel());
}
}
public async Task<IHttpActionResult> AppointmentsForUsers(Date DateFrom, Date DateTo, Enumerable<int> UserIds)
{
...
}
我在浏览器中得到的错误是:
500 : {"Message":"发生错误。","ExceptionMessage":"Der DateTimeOffset-Text \"2015-12-12T12:00\" sollte das Format \"yyyy-mm-ddThh:mm :ss('.'s+)?(zzzzzz)?\" aufweisen, und jeder Feldwert muss innerhalb des gültigen Bereichs liegen.","ExceptionType":"Microsoft.OData.ODataException","StackTrace":" bei Microsoft.OData .UriUtils.ConvertUriStringToDateTimeOffset(String text, DateTimeOffset& targetValue)\r\n bei Microsoft.OData.UriParser.ExpressionLexer.TryParseDateTimeoffset(Int32 tokenPos)\r\n bei Microsoft.OData.UriParser.ExpressionLexer.ParseFromDigit()\r\n bei Microsoft.OData.UriParser.ExpressionLexer.NextTokenImplementation(Exception& 错误)\r\n 在 Microsoft.OData.UriParser.ExpressionLexer.NextToken()\r\n 在 Microsoft.OData.UriParser.FunctionParameterParser.TrySplitOperationParameters(UriQueryExpressionParser parser, ExpressionTokenKind endTokenKind, ICollection1& splitParameters)\r\n bei Microsoft.OData.UriParser.FunctionParameterParser.TrySplitOperationParameters(String parenthesisExpression, ODataUriParserConfiguration configuration, ICollection1& splitParameters)\r\n 在 Microsoft.OData.UriParser.ODataPathParser.TryBindingParametersAndMatchingO perationImport(字符串标识符,字符串括号表达式,ODataUriParserConfiguration 配置,ICollection1& boundParameters, IEdmOperationImport& matchingFunctionImport)\r\n bei Microsoft.OData.UriParser.ODataPathParser.TryCreateSegmentForOperationImport(String identifier, String parenthesisExpression)\r\n bei Microsoft.OData.UriParser.ODataPathParser.CreateFirstSegment(String segmentText)\r\n bei Microsoft.OData.UriParser.ODataPathParser.ParsePath(ICollection1 段)\r\n 在 Microsoft.OData.UriParser.ODataPathFactory.BindPath(ICollection1 segments, ODataUriParserConfiguration configuration)\r\n bei Microsoft.OData.UriParser.ODataUriParser.ParsePathImplementation()\r\n bei Microsoft.OData.UriParser.ODataUriParser.Initialize()\r\n bei System.Web.OData.Routing.DefaultODataPathHandler.Parse(String serviceRoot, String odataPath, IServiceProvider requestContainer, Boolean template)\r\n bei System.Web.OData.Routing.DefaultODataPathHandler.Parse(String serviceRoot, String odataPath, IServiceProvider requestContainer)\r\n bei Swashbuckle.OData.Descriptions.SwaggerRouteStrategy.GenerateSampleODataPath(Operation operation, SwaggerRoute swaggerRoute, IServiceProvider rootContainer) in C:\\Users\\rbeauchamp\\Documents\\GitHub\\Swashbuckle.OData\\Swashbuckle.OData\\Descriptions\\SwaggerRouteStrategy.cs:Zeile 162.\r\n bei Swashbuckle.OData.Descriptions.SwaggerRouteStrategy.CreateHttpRequestMessage(HttpMethod httpMethod, Operation potentialOperation, SwaggerRoute potentialSwaggerRoute, HttpConfiguration httpConfig) in C:\\Users\\rbeauchamp\\Documents\\GitHub\\Swashbuckle.OData\\Swashbuckle.OData\\Descriptions\\SwaggerRouteStrategy.cs:Zeile 94.\r\n bei Swashbuckle.OData.Descriptions.SwaggerRouteStrategy.GetActionDescriptors(HttpMethod httpMethod, Operation potentialOperation, SwaggerRoute potentialSwaggerRoute, HttpConfiguration httpConfig) in C:\\Users\\rbeauchamp\\Documents\\GitHub\\Swashbuckle.OData\\Swashbuckle.OData\\Descriptions\\SwaggerRouteStrategy.cs:Zeile 67.\r\n bei Swashbuckle.OData.Descriptions.SwaggerRouteStrategy.GetActionDescriptors(SwaggerRoute potentialSwaggerRoute, HttpConfiguration httpConfig) in C:\\Users\\rbeauchamp\\Documents\\GitHub\\Swashbuckle.OData\\Swashbuckle.OData\\Descriptions\\SwaggerRouteStrategy.cs:Zeile 52.\r\n bei Swashbuckle.OData.Descriptions.SwaggerRouteStrategy.<>c__DisplayClass3_0.<Generate>b__1(SwaggerRoute potentialSwaggerRoute) in C:\\Users\\rbeauchamp\\Documents\\GitHub\\Swashbuckle.OData\\Swashbuckle.OData\\Descriptions\\SwaggerRouteStrategy.cs:Zeile 41.\r\n bei System.Linq.Enumerable.<SelectManyIterator>d__162.MoveNext()\r\n 在 System.Linq .Enumerable.d__162.MoveNext()\r\n bei System.Linq.Enumerable.<DistinctIterator>d__631.MoveNext()\r\n 在 System.Linq.Enumerable.d__162.MoveNext()\r\n bei System.Collections.Generic.List1..ctor(IEnumerable1 collection)\r\n bei System.Linq.Enumerable.ToList[TSource](IEnumerable1 源)\r\n 在 Swashbuckle.OData.CollectionExtentions。 ToCollection[T](IEnumerable1 source) in C:\\Users\\rbeauchamp\\Documents\\GitHub\\Swashbuckle.OData\\Swashbuckle.OData\\CollectionExtentions.cs:Zeile 77.\r\n bei Swashbuckle.OData.Descriptions.ODataApiExplorer.GetApiDescriptions() in C:\\Users\\rbeauchamp\\Documents\\GitHub\\Swashbuckle.OData\\Swashbuckle.OData\\Descriptions\\ODataApiExplorer.cs:Zeile 43.\r\n bei System.Lazy1.CreateValue()\r\n 在 System.Lazy1.LazyInitValue()\r\n bei System.Lazy1.get_Value()\r\n 在 Swashbuckle.OData.Descriptions.ODataApiExplorer.get_ApiDescriptions() 在 C:\ Users\rbeauchamp\Documents\GitHub\Swashbuckle.OData\Swashbuckle.OData\Descriptions\ODataApiExplorer.cs:Zeile 39.\r\n 在 C:\Users\rbeauchamp\Documents 中的 Swashbuckle.OData.ODataSwaggerProvider.GetApiDescriptionsFor(String apiVersion) \GitHub\Swashbuckle.OData\Swashbuckle.OData\ODataSwaggerProvider.cs:Zeile 297.\r\n 北 Swashbuckle.OData.ODataSwaggerProvider.GetSwagger(String rootUrl, St ring apiVersion) 在 C:\Users\rbeuchamp\Documents\GitHub\Swashbuckle.OData\Swashbuckle.OData\ODataSwaggerProvider.cs:Zeile 57.\r\n bei Swashbuckle.Application.SwaggerDocsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancelToken)\ r\n 在 System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancelToken)\r\n 在 System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancelToken)\r\n 在 System. Net.Http.DelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancelToken)\r\n 在 System.Web.Http.HttpServer.d__0.MoveNext()","InnerException":{"Message":"发生错误。" ,"ExceptionMessage":"Im DateTimeOffset-Wert '2015-12-12T12:00:00' fehlen die Zeitzoneninformationen. Ein DateTimeOffset-Wert muss Zeitzoneninformationen enthalten.","ExceptionType":"System.FormatException","StackTrace":" bei Microsoft.OData.PlatformHelper.ValidateTimeZoneInformationInDateTimeOffsetString(String text)\r\n bei Microsoft.OData.PlatformHelper.ConvertStringToDateTimeOffset( String text)\r\n bei Microsoft.OData.UriUtils.ConvertUriStringToDateTimeOffset(String text, DateTimeOffset& targetValue)"}} http://localhost:52460/swagger/docs/v1
消息的德语部分
Der DateTimeOffset-Text \"2015-12-12T12:00\" sollte das Format \"yyyy-mm-ddThh:mm:ss('.'s+)?(zzzzzz)?\" aufweisen, und jeder Feldwert muss innerhalb des gültigen Bereichs liegen。”
的意思: DateTimeOffset 文本 \"2015-12-12T12:00\" 的格式应为 \"yyyy-mm-ddThh:mm:ss('.'s+)?(zzzzzz)?\" 并且每个字段值必须在有效范围
m DateTimeOffset-Wert '2015-12-12T12:00:00' fehlen die Zeitzoneninformationen。 Ein DateTimeOffset-Wert muss Zeitzoneninformationen enthalten。”
表示:DateTimeOffset 值缺少时区信息。 DateTimeOffset 值必须包含时区信息。
这是一个错误吗?是否有任何解决方法(除了不使用 Date 类型)?任何帮助将不胜感激。
我还在 Swashbuckle.Odata Github 网站上打开了一个问题: https://github.com/rbeauchamp/Swashbuckle.OData/issues/134
更新:作为一种解决方法,我将参数类型更改为 System.DateTime
public async Task<IHttpActionResult> AppointmentsForUsers(DateTime DateFrom, DateTime DateTo, Enumerable<int> UserIds)
{
...
}
通过这种解决方法,我仍然可以使用日期作为参数,例如 AppointmentsForUsers(DateFrom=2017-04-07,.... 实际参数包含一个时间组件(取决于时区),但在内部我继续使用 Date(从 DateTime 隐式转换)。至少对我们来说效果很好,尽管最初的问题仍然存在。
【问题讨论】:
标签: c# odata swagger swashbuckle