odata.net
odata.net copied to clipboard
Header Accept cannot ends with semicolon
When the Header uses semicolon as the end character, it throws the exception:
Microsoft.OData.ODataException: An error occurred when parsing the HTTP header 'Prefer'. The header value 'odata.track-changes;odata.maxpagesize=2;' is incorrect at position '40' because the header value should not end with the separator ';'. at Microsoft.OData.HttpHeaderValueLexer.HttpHeaderSeparator.ReadNext() at Microsoft.OData.HttpHeaderValueLexer.ReadHttpHeaderValueElement(HttpHeaderValueLexer& lexer) at Microsoft.OData.HttpHeaderValueLexer.ToHttpHeaderValue() at Microsoft.OData.ODataPreferenceHeader.ParsePreferences() at Microsoft.OData.ODataPreferenceHeader.get_Preferences() at Microsoft.OData.ODataPreferenceHeader.Get(String preferenceName) at Microsoft.OData.ODataPreferenceHeader.get_AnnotationFilter() at Microsoft.AspNetCore.OData.Formatter.ODataOutputFormatterHelper.WriteToStreamAsync(Type type, Object value, IEdmModel model, ODataVersion version, Uri baseAddress, MediaTypeHeaderValue contentType, HttpRequest request, IHeaderDictionary requestHeaders, IODataSerializerProvider serializerProvider) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeResultAsync>g__Logged|22_0(ResourceInvoker invoker, IActionResult result) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResultFilterAsync>g__Awaited|30_0[TFilter,TFilterAsync](ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()\r\n--- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker) at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Any reason why it is restricted like this? Is there any document saying OData header has this limitation?
It seems by design, we cannot have a separator at the last token in a header. Separations include =
,
and ;
Code throwing the exception https://github.com/OData/odata.net/blob/67365d65e0a98199820c076076e2e5978089d3f8/src/Microsoft.OData.Core/HttpHeaderValueLexer.cs#L556C90-L556C90
Tests https://github.com/OData/odata.net/blob/67365d65e0a98199820c076076e2e5978089d3f8/test/FunctionalTests/Microsoft.OData.Core.Tests/HttpHeaderValueLexerTests.cs#L162 https://github.com/OData/odata.net/blob/67365d65e0a98199820c076076e2e5978089d3f8/test/FunctionalTests/Microsoft.OData.Core.Tests/HttpHeaderValueLexerTests.cs#L171 https://github.com/OData/odata.net/blob/67365d65e0a98199820c076076e2e5978089d3f8/test/FunctionalTests/Microsoft.OData.Core.Tests/HttpHeaderValueLexerTests.cs#L180
Potential fix; Ignore comma and semi colon at the end.