0

所以我正在为一个 WebAPI 应用程序制作一个概念验证原型,所有常用方法都很好用。但我也想证明能够通过 WebAPI 调用自定义方法。所以我的 RouteConfig.cs 中有以下路由:

routes.MapHttpRoute(
               name: "ActionApi",
               routeTemplate: "api/{controller}/{action}/{id}",
               defaults: new { id = RouteParameter.Optional }
            );

在控制器中,我有一个简单的方法:

[HttpGet]
public string Test()
{
    return "this is a string";
}

当我尝试调用我的方法时:http://localhost:43225/api/values/test我在浏览器中收到以下错误:

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.String Get(Int32)' in 'WebAPI_Listener.Controllers.ValuesController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
</string>

但是,如果我在 url 的末尾指定一个 ID,例如http://localhost:43225/api/values/test/1它可以工作,即使方法本身根本不带参数。

因此,在路由中,如果我将 id} 设置为可选,为什么当我不指定 {id} 时它不起作用,但如果我这样做了,即使方法本身不期望 { ID}??

4

1 回答 1

5

您需要在 ~/App_Start/WebAPIConfig.cs 注册方法中声明您的 API 路由。WebAPIConfig 中的包罗万象的路由在 RouteConfig 路由之前,因此永远不会选择您的路由。

这是一个将类似于您的路由添加到 WebAPIConfig 的示例。这个例子有一个缺点:你必须为一个匹配这个路由的控制器显式声明 HTTP 动词(即 ~/api/values/get/5 而不是 ~/localhost:43225/api/values/5)。

        config.Routes.MapHttpRoute(
            name: "CustomAPIActions",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        ); 

为了避免这个缺点,你可以像这样限制到给定控制器的路由:

        config.Routes.MapHttpRoute(
            name: "ApiNonCrudActionsForMyController",
            routeTemplate: "MyController/{action}/{id}",
            defaults: new { controller = "MyController", id = RouteParameter.Optional }
        ); 

您还可以将路由限制到控制器和操作,以保留标准动词,但如果您经常这样做,这可能会成为维护问题或混淆点。

        config.Routes.MapHttpRoute(
            name: "ApiNonCrudActionsForMyController",
            routeTemplate: "MyController/Test/{id}",
            defaults: new { controller = "MyController", action = "Test", id = RouteParameter.Optional }
        ); 

有关更多详细信息和其他一些方法,请查看:http ://encosia.com/rest-vs-rpc-in-asp-net-web-api-who-cares-it-does-both/ 。您还可以考虑将您的操作限制为 HTTP 动词,并为自定义操作添加额外的控制器(即 ~/localhost:43225/api/TestValues/5)。

于 2012-09-12T20:02:45.203 回答