【问题标题】:OData function with Microsoft.OData.Edm.Date parameters causing error in Swashbuckle带有 Microsoft.OData.Edm.Date 参数的 OData 函数在 Swashbuckle 中导致错误
【发布时间】: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&amp; 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&amp; boundParameters, IEdmOperationImport&amp; 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.&lt;&gt;c__DisplayClass3_0.&lt;Generate&gt;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.&lt;SelectManyIterator&gt;d__162.MoveNext()\r\n 在 System.Linq .Enumerable.d__162.MoveNext()\r\n bei System.Linq.Enumerable.&lt;DistinctIterator&gt;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


    【解决方案1】:

    如果使用动作而不是函数可以成为解决方案... 您是否尝试过使用接收 ODataActionParameters 对象作为参数的操作,如此处所述?:

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/odata-actions-and-functions

    public async Task<IHttpActionResult> AppointmentsForUsers(ODataActionParameters parameters) 
    {
        Date fromDate = (Date)parameters["FromDate"];
        Date toDate = (Date)parameters["ToDate"];
        Enumerable[int] UserIds= (Enumerable[int])parameters["UserIds"];
    }
    

    另一种选择是使用三个参数创建模型并将其作为 ODataActionParameter 传递

     var function = builder.Action("AppointmentsForUsers");
            function.ReturnsCollectionFromEntitySet<AppointmentDTO>("Appointments");
            function.Parameter<ModelWithDatesAndUsers >("Model");
    
    public class ModelWithDatesAndUsers
    {
        Date fromDate;
        Date toDate;
        Enumerable[int] userIds;
    }
    
    public async Task<IHttpActionResult> AppointmentsForUsers(ODataActionParameters parameters) 
    {
             ModelWithDateAndUsers model= (ModelWithDatesAndUsers)parameters["Model"];        
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-12
      • 1970-01-01
      • 2011-07-03
      • 1970-01-01
      相关资源
      最近更新 更多