该场景是一个使用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中的语法;如果它没有那么有什么替代品呢?
答案 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。希望它可以帮到你。感谢。