用于删除 m:m 个实体之间关系的 OData 属性路由
OData attribute routing for deleting relationship between m:m entities
该场景是一个使用 OData v4 的应用程序,服务器端 API 基于使用 ODataLib 的 Entity Framework 模型,客户端使用 [=44= 的 OData 客户端代码生成器扩展]
我无法让 OData 属性路由用于删除 m:m 关系中实体的关系,客户端为此生成 DELETE 请求,格式为:
http://developer4:8080/odata/tblTestRestaurant(241)/tblTestDishes/$ref?$id=http://developer4:8080/odata/tblTestDish(1)
用于创建 link 的 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 是使用 URL.
中的 $ref?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();
}
但是上述控制器操作中的 none 被命中以响应对 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 路由约定 - 但不包含用于删除属性路由的示例 link秒。
所以我的问题是 - 我应该使用什么 ODataRoute 属性语法和方法参数,假设 ODataRoute 属性确实支持 URL 中的这个 ...$ref?id=... 语法删除;如果没有,那么还有哪些替代方案?
Web API OData 解析 $Id
中的 Uri 以创建附加到原始路径段的关键段。因此,如果您按如下方式更改模板,它应该可以工作:
[ODataRoute("({pRestaurantID})/tblTestDishes({pRelated})/$ref")]
[HttpDelete]
public async Task<IHttpActionResult> TestRemoveRef([FromODataUri] int pRestaurantID, [FromODataUri] int pRelated)
{
...
}
你可以参考我的示例工程here。希望它能帮助你。谢谢
该场景是一个使用 OData v4 的应用程序,服务器端 API 基于使用 ODataLib 的 Entity Framework 模型,客户端使用 [=44= 的 OData 客户端代码生成器扩展]
我无法让 OData 属性路由用于删除 m:m 关系中实体的关系,客户端为此生成 DELETE 请求,格式为:
http://developer4:8080/odata/tblTestRestaurant(241)/tblTestDishes/$ref?$id=http://developer4:8080/odata/tblTestDish(1)
用于创建 link 的 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 是使用 URL.
中的$ref?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();
}
但是上述控制器操作中的 none 被命中以响应对 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 路由约定 - 但不包含用于删除属性路由的示例 link秒。
所以我的问题是 - 我应该使用什么 ODataRoute 属性语法和方法参数,假设 ODataRoute 属性确实支持 URL 中的这个 ...$ref?id=... 语法删除;如果没有,那么还有哪些替代方案?
Web API OData 解析 $Id
中的 Uri 以创建附加到原始路径段的关键段。因此,如果您按如下方式更改模板,它应该可以工作:
[ODataRoute("({pRestaurantID})/tblTestDishes({pRelated})/$ref")]
[HttpDelete]
public async Task<IHttpActionResult> TestRemoveRef([FromODataUri] int pRestaurantID, [FromODataUri] int pRelated)
{
...
}
你可以参考我的示例工程here。希望它能帮助你。谢谢