我有一个现有的API,我正在迁移到WebAPI上,所以我不能随意更改URL。打破现有客户对我来说不是一个选择。
知道这一点后,原始API将接受给定操作方法的Guid ( ID)或字符串(名称)。旧的API处理程序将破译URL参数,并将请求发送到旨在接受给定参数类型的控制器操作。
举个例子:
Get(Guid id)
对比
Get(string name)
使用WebAPI时,参数绑定跨值类型是贪婪的,因此取决于控制器源文件中的第一个操作,该操作就是被调用的操作。对于我的需求,这是行不通的。我希望绑定器会意识到,对于一个名称,到Guid的转换将失败,然后选择更通用的基于字符串的操作。没有骰子。Guid只是看起来是一个空值(有趣的是,因为它是一个值类型,但这就是我在处理过程中的某个时刻在调试器中得到的)。
所以我的问题是如何最好地处理这个问题?我需要实现自定义的IHttpActionSelector吗?我尝试了属性路由方法(带约束),但它不是很有效(看起来很酷,很糟糕)。在WebAPI中有没有一种机制可以解释这一点,我还不知道呢?(我知道我可以通过测试字符串的Guid-ness并调用另一个控制器方法来破解它,但我希望有一个更优雅的、基于WebAPI的解决方案……)
发布于 2015-05-07 23:26:16
我花了很多时间尝试适应基于属性的路由,但我还没有让它工作。但是,我确实使用路由约束解决了我的特定问题。如果首先注册受约束较多的路由,WebAPI (如MVC)将应用约束并跳过受约束较多的路由,直到找到可以选择的路由。
因此,使用我的示例,我可以像这样设置路由:
_config.Routes.MapHttpRoute(name: "ById",
routeTemplate: "product/{id}",
defaults: new { controller = "ProductDetails" },
constraints: new { id = @"^\{?[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\}?$" });
_config.Routes.MapHttpRoute(name: "ByName",
routeTemplate: "product/{name}",
defaults: new { controller = "ProductDetails" });
第一个路由接受Guid的正则表达式形式的约束。第二个函数接受所有其他值,控制器将处理非产品名称(返回404)。我在自托管的WebAPI服务器上对此进行了测试,它工作得非常棒。
我确信基于属性的路由将会更优雅,但在我使用它之前,它仍然是我的老方法。至少我找到了一个合理的基于WebAPI的解决方案。
https://stackoverflow.com/questions/30087270
复制相似问题