用于删除m:m实体

时间:2015-07-03 11:55:02

标签: asp.net-web-api odata odata-v4 odatalib odatacontroller

该场景是一个使用OData v4的应用程序,基于使用ODataLib的Entity Framework模型的服务器端API,客户端使用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工作,使用URL中的$ref?id=...语法指定相关实体的ID。

我使用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)的DELETE请求而被命中。

我能让它工作的唯一方法是不使用属性路由,而是依赖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测试用例,特别是this one,它使用了属性路由和OData路由约定的混合 - 但是没有包含删除链接的属性路由的示例。

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

1 个答案:

答案 0 :(得分:2)

Web API OData在$Id中解析Uri以创建附加到原始路径段的关键段。因此,如果您更改下面的模板,它应该工作:

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

您可以参考我的示例项目here。希望它可以帮到你。感谢。