Open weitzhandler opened 5 years ago
It happened also to me and I cannot understand why... is there any update on this problem?
it happened to me too :/
Are there any updates on this? Thank you
@freemstr Is it still happening in latest 7.4.1 version? Would you please share me a repo?
to remove routeBuilder.EnableDependencyInjection();
can help to resolve the problem?
@xuzhg I worked around the issue, for now, by using $expand but here is what I ran into:
Project is being migrated from OData v3 to v4 7.4.1 so this is happening in a new project with the following configurations and no explicitly called model builder and no entity framework:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.EnableDependencyInjection();
endpoints.Select().Filter().OrderBy().Count().Expand().MaxTop(100);
endpoints.SetUrlKeyDelimiter(ODataUrlKeyDelimiter.Parentheses);
});
The error is happening only when calling GetGroupMembers
public class GroupController {
IGroupManager groupManager;
public GroupController (IGroupManager di_groupManager)
{
groupManager= di_groupManager;
}
[HttpGet]
[ODataRoute]
[Route("/api/[controller]({key})")]
public virtual Group Get([FromODataUri] int key)
{
return groupManager.GetById(key);
}
[HttpPost]
[Route("Delete({id})")]
[ODataRoute]
public virtual ActionResult DeletePost([FromODataUri] TKey id)
{
var i = groupManager.DeleteEntity(id);
return i ? NoContent() : ValidationProblem(ModelState);
}
[HttpGet]
[ODataRoute]
[Route("GetGroupMember({id})")]
public ICollection<GroupMembers> GetGroupMembers([FromODataUri] int key)
{
return groupManager.GetGroupMembersById(key);
}
}
Thank you for looking into this.
For anyone looking for a possible work around to this problem that's been open a very long time, this workaround has probably been found multiple times.
The issue is still in Microsoft.AspNetCore.OData, Version=7.5.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
You can simply return an OK() rather than a created.
/// <summary>
/// Create a new <see cref="PaCase"/> instance
/// </summary>
/// <param name="paCase">The <see cref="PaCase"/> to create</param>
/// <returns>The created <see cref="PaCase"/></returns>
[HttpPost]
[ODataRoute("Post")]
[Produces(typeof(PaCase))]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> Post(PaCase paCase)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
Context.PaCases.Add(paCase);
await Context.SaveChangesAsync();
#warning Bug in odata framework throws System.InvalidOperationException: The operation cannot be completed because no ODataPath is available for the request. See https://github.com/OData/WebApi/issues/1866
//return Created(paCase);
return Ok(paCase);
}
The reason for the error is due to a check in the Microsoft.AspNet.OData.Results.ResultHelpers.GenerateODataLink method.
Microsoft.AspNet.OData.Routing.ODataPath path = request.ODataFeature().Path;
if (path == null)
{
throw new InvalidOperationException(SRResources.ODataPathMissing);
}
The request.ODataFeature().Path is null because the ODataFeature() extension method calls another extension method, that creates an instance of the ODataFeature because there is none on the HttpContext
public static class HttpContextExtensions
{
/// <summary>
/// Extension method to return the <see cref="T:Microsoft.AspNet.OData.Interfaces.IODataFeature" /> from the <see cref="T:Microsoft.AspNetCore.Http.HttpContext" />.
/// </summary>
/// <param name="httpContext">The Http context.</param>
/// <returns>The <see cref="T:Microsoft.AspNet.OData.Interfaces.IODataFeature" />.</returns>
public static IODataFeature ODataFeature(this HttpContext httpContext)
{
if (httpContext == null)
{
throw Error.ArgumentNull("httpContext");
}
IODataFeature iODataFeature = httpContext.Features.Get<IODataFeature>();
if (iODataFeature == null)
{
iODataFeature = new ODataFeature();
httpContext.Features.Set(iODataFeature);
}
return iODataFeature;
}
There is an interesting comment on the ODataFeature
/// <summary>
/// Contains the details of a given OData request. These properties should all be mutable.
/// None of these properties should ever be set to null.
/// </summary>
public class ODataFeature : IODataFeature, IDisposable
{
So somewhere further up the request response call chain the ODataFeature is not being set. No idea why because I did not investigate further.
I am still facing this error. Was anyone able to find a workaround?
I am using Assembly Microsoft.AspNetCore.OData, Version=7.5.5.0
For anyone looking for a possible work around to this problem that's been open a very long time, this workaround has probably been found multiple times.
The issue is still in Microsoft.AspNetCore.OData, Version=7.5.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
You can simply return an OK() rather than a created.
/// <summary> /// Create a new <see cref="PaCase"/> instance /// </summary> /// <param name="paCase">The <see cref="PaCase"/> to create</param> /// <returns>The created <see cref="PaCase"/></returns> [HttpPost] [ODataRoute("Post")] [Produces(typeof(PaCase))] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] public async Task<IActionResult> Post(PaCase paCase) { if (!ModelState.IsValid) { return BadRequest(ModelState); } Context.PaCases.Add(paCase); await Context.SaveChangesAsync(); #warning Bug in odata framework throws System.InvalidOperationException: The operation cannot be completed because no ODataPath is available for the request. See https://github.com/OData/WebApi/issues/1866 //return Created(paCase); return Ok(paCase); }
The reason for the error is due to a check in the Microsoft.AspNet.OData.Results.ResultHelpers.GenerateODataLink method.
Microsoft.AspNet.OData.Routing.ODataPath path = request.ODataFeature().Path; if (path == null) { throw new InvalidOperationException(SRResources.ODataPathMissing); }
The request.ODataFeature().Path is null because the ODataFeature() extension method calls another extension method, that creates an instance of the ODataFeature because there is none on the HttpContext
public static class HttpContextExtensions { /// <summary> /// Extension method to return the <see cref="T:Microsoft.AspNet.OData.Interfaces.IODataFeature" /> from the <see cref="T:Microsoft.AspNetCore.Http.HttpContext" />. /// </summary> /// <param name="httpContext">The Http context.</param> /// <returns>The <see cref="T:Microsoft.AspNet.OData.Interfaces.IODataFeature" />.</returns> public static IODataFeature ODataFeature(this HttpContext httpContext) { if (httpContext == null) { throw Error.ArgumentNull("httpContext"); } IODataFeature iODataFeature = httpContext.Features.Get<IODataFeature>(); if (iODataFeature == null) { iODataFeature = new ODataFeature(); httpContext.Features.Set(iODataFeature); } return iODataFeature; }
There is an interesting comment on the ODataFeature
/// <summary> /// Contains the details of a given OData request. These properties should all be mutable. /// None of these properties should ever be set to null. /// </summary> public class ODataFeature : IODataFeature, IDisposable {
So somewhere further up the request response call chain the ODataFeature is not being set. No idea why because I did not investigate further.
thanks, i forgot the return should be Ok(), not Created()
Hi, I'm trying to use
Assemblies affected
Assembly Microsoft.AspNetCore.OData, Version=7.1.0.21120
*Which assemblies and versions are known to be affected e.g. OData WebApi lib 6.1.0
Reproduce steps
Here's my OData setup:
Expected result
No excceptions
Actual result
When posting data using OData, it gets to the controller action and data saves just fine, but then, during processing of the action-result, in some of the middlewares, the following exception is thrown:
Additional detail
StackTrace: