1

该场景是一个使用 OData v4 的应用程序,服务器端 API 基于使用 ODataLib 的实体框架模型,客户端使用 Visual Studio 的 OData 客户端代码生成器扩展

我无法让 OData 属性路由用于删除 m:m 关系中实体的关系,客户端为此生成 DELETE 请求,格式如下:

http://developer4:8080/odata/tblTestRestaurant(241)/tblTestDishes/$ref?$id=http://developer4:8080/odata/tblTestDish(1)

用于创建链接的 POST 属性路由工作得很好 - 相关实体标识符在正文中编码,并且以下控制器操作方法声明有效(控制器本身具有[ODataRoutePrefix("tblTestRestaurant")]):

    [ODataRoute("({pRestaurantID})/tblTestDishes/$ref")]
    [HttpPost]
    [EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
    public async Task<IHttpActionResult> PostAttachtblTestDishes([FromODataUri] int pRestaurantID,
        [FromBody] Uri uri) { ... }

但是我无法为 DELETE 获得类似的工作,其中相关实体的 ID 是使用$ref?id=...URL 中的语法指定的。

我使用 ODataRoute 属性尝试了以下操作:

    [ODataRoute("({pRestaurantID})/tblTestDishes/$ref")]
    [HttpDelete]
    public async Task<IHttpActionResult> TestRemoveRef1([FromODataUri] int pRestaurantID,
        [FromODataUri] Uri relatedUri)
    {
        throw new NotImplementedException();
    }
    [ODataRoute("({pRestaurantID})/tblTestDishes/$ref")]
    [HttpDelete]
    public async Task<IHttpActionResult> TestRemoveRef2([FromODataUri] int pRestaurantID,
        [FromODataUri] string relatedUri)
    {
        throw new NotImplementedException();
    }
    [ODataRoute("({pRestaurantID})/tblTestDishes/$ref?$id={pRelated}")]
    [HttpDelete]
    public async Task<IHttpActionResult> TestRemoveRef3([FromODataUri] int pRestaurantID,
        [FromODataUri] string pRelated)
    {
        throw new NotImplementedException();
    }
    [ODataRoute("({pRestaurantID})/tblTestDishes/$ref?$id={pRelated}")]
    [HttpDelete]
    public async Task<IHttpActionResult> TestRemoveRef4([FromODataUri] int pRestaurantID,
        [FromODataUri] Uri pRelated)
    {
        throw new NotImplementedException();
    }

但是上述控制器操作都没有响应对http://developer4:8080/odata/tblTestRestaurant(241)/tblTestDishes/$ref?$id=http://developer4:8080/odata/tblTestDish(1).

我可以让它工作的唯一方法是不使用属性路由,而是依赖 OData 路由约定,即

    [HttpDelete]
    public async Task<IHttpActionResult> DeleteRef([FromODataUri] int key,
        [FromODataUri] string relatedKey, string navigationProperty)
    {
        throw new NotImplementedException();
    }

此方法依赖于测试字符串 navigationProperty 来确定要修改实体上的哪个集合导航属性 - 相反,我更喜欢使用属性路由并在我的控制器中为每个集合导航属性设置一个单独的操作方法。

我使用了许多教程和文档,特别是 https://damienbod.wordpress.com/2014/06/10/getting-started-with-web-api-and-odata-v4/

我也经历了一些 OData WebApi 测试用例,特别是这个混合使用属性路由和 OData 路由约定的测试用例 - 但不包含删除链接的属性路由示例。

所以我的问题是 - 我应该使用什么 ODataRoute 属性语法和方法参数,假设 ODataRoute 属性确实支持删除 URL 中的这种 ...$ref?id=... 语法;如果没有,那么还有什么选择?

4

1 回答 1

2

Web API OData 解析 Uri$Id以创建附加到源路径段的关键段。因此,如果您按以下方式更改模板,它应该可以工作:

[ODataRoute("({pRestaurantID})/tblTestDishes({pRelated})/$ref")]
[HttpDelete]
public async Task<IHttpActionResult> TestRemoveRef([FromODataUri] int pRestaurantID, [FromODataUri] int pRelated)
{
        ...
}

你可以在这里参考我的示例项目。希望它可以帮助你。谢谢。

于 2015-07-08T07:31:17.367 回答