AspNetCoreOData
AspNetCoreOData copied to clipboard
Odata 8.0.4 with .net6: not matching DeleteRef route
Hello everyone!
I'm using OData 8.0.4 with asp net core 6.0, and I can't find the correct way to implement ODataController's DeleteRef method. I can't understand if I'm failing something or it's a library problem.
This is the signature of my method:
public async Task<ActionResult> DeleteRef([FromODataUri] int key, string navigationProperty, [FromODataUri] string relatedKey)
If I remove the relatedKey parameter, it then matches, but I cannot access the id of the related entity.
For now, I'm extracting data by getting the id manually from Request's Query, but then another problem occurs. I use the following method to extract the id from the odata string https://localhost:44336/api/Components(3994)
.
public static TKey GetKeyFromUri<TKey>(HttpRequest request, Uri uri)
{
if (uri == null)
{
throw new ArgumentNullException("uri");
}
var odataFeature = request.ODataFeature();
var uriParser = new ODataUriParser(odataFeature.Model, new Uri(odataFeature.BaseAddress), uri);
var keySegment = uriParser.ParsePath().OfType<KeySegment>().FirstOrDefault();
if (keySegment?.Keys == null || !keySegment.Keys.Any())
{
throw new InvalidOperationException("The link does not contain a key.");
}
return (TKey)keySegment.Keys.FirstOrDefault().Value;
}
But only in this case, oDataFeature.BaseAddress returns null. Other data, like Model, are correctly evaluated.
This is the complete route I'm trying to match: https://localhost:44336/api/Tools(8)/Components/$ref?$id=https://localhost:44336/api/Components(3994)
Thanks to anyone who will help me!
I'm facing the same problem (using AspNetCore.OData 8.0.10). Is there a solution in the meantime?
The convention documentation has the arguments in a different order than what you are using.
(I don't know why the action is called DeleteLink
there and not DeleteRef
though...)
Does it make any difference for you if you swap the last two arguments and use:
public async Task<ActionResult> DeleteRef(
[FromODataUri] int key,
[FromODataUri] string relatedKey,
string navigationProperty)
?
I've tried that too. The result is the same: 404 Not found. The route cannot be resolved. It looks like there are problems with the RefRoutingConvention.
@kfrentzel @GabrieleVolpato
For a single-valued navigation property, you should implement controller actions matching either of the following:
// Let's say the single-valued navigation property is named "Customer"
// DELETE http://localhost:19644/odata/Orders(1)/Customer/$ref
public ActionResult DeleteRefToCustomer([FromRoute] int key)
{
// ...
}
// Or
// DELETE http://localhost:19644/odata/Orders(1)/Customer/$ref
public ActionResult DeleteRef([FromRoute] int key, [FromRoute] string navigationProperty)
{
// ...
}
For a collection-valued navigation property, you should implement controller actions matching either of the following:
// Let's say the collection-valued navigation property is named "Orders"
// DELETE http://localhost:5000/odata/Customers(1)/Orders(2)/$ref
public ActionResult DeleteRefToOrders([FromRoute] int key, [FromRoute] int relatedKey)
{
// ...
}
// Or
// DELETE http://localhost:5000/odata/Customers(1)/Orders(2)/$ref
public ActionResult DeleteRef([FromRoute] int key, [FromRoute] int relatedKey, [FromRoute] string navigationProperty)
{
// ...
}
Kindly let me know if this helps...
@GabrieleVolpato I'll go ahead and close this. If the solution I proposed doesn't work, feel free to reopen it