我有一个现有的API,现在我要移至WebAPI,因此不能随意更改URL。打破现有客户不是我的选择。

知道这一点,原始API将为给定的操作方法接受Guid(ID)或字符串(名称)。旧的API处理程序将破译URL参数,并将请求发送到旨在接受给定参数类型的控制器操作。

举个例子:

Get(Guid id)




Get(string name)


使用WebAPI时,参数绑定在值类型之间是贪婪的,因此,取决于哪个是控制器源文件中的第一个,该操作是被调用的操作。对于我的需求,那是行不通的。我希望活页夹将意识到无法将Guid转换为名称,然后选择更通用的基于字符串的操作。没有骰子。 Guid只是作为一个空值出现(有趣的是,因为它是一个值类型,但这就是我在处理过程中的某个时刻在调试器中得到的结果)。

所以我的问题是如何最好地处理这个问题?我是否需要实现自定义IHttpActionSelector?我尝试了使用属性路由方法(带有约束),但是这种方法不太正确(因为看起来很酷,所以更加笨拙)。 WebAPI中有一种机制可以解决我尚不知道的问题吗? (我知道我可以通过测试字符串的Guidness并调用其他控制器方法来破解它,但我希望有一个更优雅的基于WebAPI的解决方案...)

最佳答案

我花了很多时间尝试将基于属性的路由放入其中,但是我还没有开始工作。但是,我确实使用路由约束解决了我的特定问题。如果您首先注册更受约束的路由,则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的解决方案。

关于c# - 值类型不同的WebAPI Controller 方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30087270/

10-13 07:24