我有一个现有的API我正在转移到WebAPI,所以我无法自由更改URL。打破现有客户对我来说不是一个选择。
知道原始API将接受给定操作方法的Guid(ID)或字符串(名称)。旧的API处理程序将解密URL参数并将请求发送到旨在接受给定参数类型的控制器操作。
举个例子:
Get(Guid id)
与
Get(string name)
使用WebAPI,参数绑定在值类型之间是贪婪的,因此根据控制器源文件中的第一个,该操作是被调用的操作。根据我的需要,这不起作用。我希望绑定器会意识到转换为Guid将失败一个名称,然后选择更通用的基于字符串的操作。没有骰子。 Guid只是一个空值(有趣的是因为它是一个值类型,但这就是我在处理过程中的某个点调试器中获得的内容)。
所以我的问题是如何最好地处理这个问题?我是否需要实现自定义IHttpActionSelector?我尝试了属性路由方法(带约束),但这样做不太正常(因为看起来很酷)。 WebAPI中是否有一个机制可以解释这个我还不知道的机制? (我知道我可以通过测试Guid-ness的字符串并调用其他控制器方法来破解它,但我希望有一个更优雅,基于WebAPI的解决方案...)
答案 0 :(得分:0)
我花费了大量时间尝试使用基于属性的路由,但我还没有这样做。但是,我确实使用路由约束来解决我的特定问题。如果首先注册更受约束的路由,则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的解决方案。