繁体   English   中英

具有Microsoft.OData.Edm.Date参数的OData函数导致Swashbuckle错误

[英]OData function with Microsoft.OData.Edm.Date parameters causing error in Swashbuckle

我在WepAPI OData Web服务中集成了Swashbuckle.OData 3.2.0和Swashbuckle.Core 5.5.3,以生成Swagger文档。 当我尝试访问swagger端点( http:// localhost:52460 / swagger )时,出现以下异常,这似乎是由一个带有2个类型为Microsoft.OData.Edm.Date的参数的函数(AppointmentsForUsers)引起的(不带时间成分的日期类型)。 当我注释掉我的Register函数中的var function = builder,Function...部分时,一切工作正常,当我用System.DateTimeOffset替换参数类型Microsoft.OData.Edm.Date时,它也能正常工作,但是不是我们/我们项目的解决方案。

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:{“消息”:“发生错误。”,“ ExceptionMessage”:“ Der DateTimeOffset-Text \\” 2015-12-12T12:00 \\“ sollte das Format \\” yyyy-mm-ddThh:mm:ss( '。's +)?(zzzzzz)?\\“ aufweisen,和jeder Feldwert解释说,Berichichs liegen是内部的。”,“ ExceptionType”:“ Microsoft.OData.ODataException”,“ StackTrace”:“是Microsoft.OData.UriUtils。 ConvertUriStringToDateTimeOffset(字符串文本,DateTimeOffset&targetValue)\\ r \\ n从Microsoft.OData.UriParser.ExpressionLexer.TryParseDateTimeoffset(Int32 tokenPos)\\ r \\ n从Microsoft.OData.UriParser.ExpressionLexer.ParseFromDigit()\\ r \\ n从Microsoft.OData 1& splitParameters)\\r\\n bei Microsoft.OData.UriParser.FunctionParameterParser.TrySplitOperationParameters(String parenthesisExpression, ODataUriParserConfiguration configuration, ICollection 1& splitParameters)\\r\\n bei Microsoft.OData.UriParser.FunctionParameterParser.TrySplitOperationParameters(String parenthesisExpression, ODataUriParserConfiguration configuration, ICollection 1和splitParameters)\\ r \\ n位于Microsoft.OData.UriParser.ODataPathParser.TryBindingParametersAndMatchingOperationImport(字符串标识符,字符串括号表示,ODataUriParserConfiguration配置,ICollection 1& 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(ICollection 1 segment)\\ r \\ n bei Microsoft.OData.UriParser.ODataPathFactory.BindPath(ICollection 1 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__16 1 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__16 1 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__16 2.MoveNext()\\ r \\ n bei System.Linq.Enumerable.d__16 2.MoveNext()\\r\\n bei System.Linq.Enumerable.<DistinctIterator>d__63 1.MoveNext()\\ r \\ n在System.Linq.Enumerable.d__16 2.MoveNext()\\r\\n bei System.Collections.Generic.List 2.MoveNext()\\r\\n bei System.Collections.Generic.List 1..ctor(IEnumerable 1 collection)\\r\\n bei System.Linq.Enumerable.ToList[TSource](IEnumerable 1来源)\\ r \\ n在Swashbuckle.OData.CollectionExtentions.ToCollection [T](IEnumerable 1 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.Lazy 1.CreateValue() \\ r \\ n bei System.Lazy 1.LazyInitValue()\\r\\n bei System.Lazy 1.get_Value()\\ r \\ n bei Swashbuckle.OData.Descriptions.ODataApiExplorer.get_ApiDescriptions()in C:\\ Users \\ rbeauchamp \\ Documents \\ GitHub \\ Swashbuckle.OData \\ Swashbuckle.OData \\ Descriptions \\ ODataApiExplorer.cs:Zeile 39. \\ r \\ n be Swashbuckle.OData.ODataSwaggerProvider.GetApiDescriptionsFor(String apiVersion)位于C:\\ Users \\ rbeauchamp \\ Documents \\ GitHub \\ Swashbuckle .OData \\ Swashbuckle.OData \\ ODataSwaggerProvi der.cs:Zeile 297. \\ r \\ n be Swashbuckle.OData.ODataSwaggerProvider.GetSwagger(String rootUrl,String apiVersion)在C:\\ Users \\ rbeauchamp \\ Documents \\ GitHub \\ Swashbuckle.OData \\ Swashbuckle.OData \\ ODataSwaggerProvider.cs: Zeile 57. \\ r \\ n北Swashbuckle.Application.SwaggerDocsHandler.SendAsync(HttpRequestMessage请求,CancellationToken cancelToken)\\ r \\ n北System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage请求,CancellationToken cancelToken)\\ r \\ n北系统。 Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(HttpRequestMessage请求,CancellationToken cancelleToken)\\ r \\ n在System.Net.Http.DelegatingHandler.SendAsync(HttpRequestMessage请求,CancellationToken cancellingToken)\\ r \\ n在System.Web.Http.HttpServer中。 d__0.MoveNext()“,” InnerException“:{” Message“:”发生错误。“,” ExceptionMessage“:” Im DateTimeOffset-Wert'2015-12-12T12:00:00'这是Zeitzoneninformationen中的问题。 Ein DateTimeOffset-Wert会引起Zeitzoneninformationen的热情。“,” ExceptionType“:” System.FormatException“,” StackTrace“:”“ Microsoft.OData.PlatformHelper.ValidateTimeZoneInformationInDateTimeOffsetString(String text)\\ r \\ n bei Microsoft.OData.PlatformSetset(StringToCont。字符串文本)\\ r \\ n Microsoft.OData.UriUtils.ConvertUriStringToDateTimeOffset(字符串文本,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和jeder Feldwert muss innerhalb des gültigenBereichs liegen。”

表示:DateTimeOffset文本\\“ 2015-12-12T12:00 \\\\”的格式应为\\“ yyyy-mm-ddThh:mm:ss('。s +)?(zzzzzz)?\\”,并且每个字段值都必须为在有效范围内

m DateTimeOffset-Wert'2015-12-12T12:00:00'将关闭Zeitzonen信息。 Ein DateTimeOffset-Wert迷住了Zeitzoneninformationen的热情。”

表示:DateTimeOffset值缺少时区信息。 DateTimeOffset值必须包含时区信息。

这是错误吗? 有什么解决方法(除了不使用日期类型外)? 任何帮助将非常感激。

我还在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,....。实际参数包含一个时间分量(取决于时区),但是在内部,我继续日期(从DateTime的隐式转换):至少对我们来说很好,尽管原始问题仍然存在。

如果使用动作代替函数可以是解决方案...您是否尝试过使用将ODataActionParameters对象作为参数接收的动作,如下所述?:

https://docs.microsoft.com/zh-cn/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"];        
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM