阻止调用 Web API 方法

本文关键字:API 方法 Web 调用 | 更新日期: 2023-09-27 17:56:38

我正在使用 ASP.NET Web API创建一个Web API。 我目前正在我的端点上删除功能,以便我可以开始针对它进行开发。

我的 WebApiConfig.cs 文件如下所示:

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

在我的用户控制器.cs文件中,我有以下方法:

//Maps to /Users endpoint
[HttpGet]
public IEnumerable<User> GetAllUsers()
{
   //Code
}
//Maps to /Users/{id} endpoint
[HttpGet]
public User GetUser(int id)
{
   //Code
}
//Maps to /Users/{id}/Enrollments endpoint
[HttpGet, ActionName("Enrollments")]
public IEnumerable<Enrollment> GetUserEnrollments(int id)
{
   //Code
}
//Maps to /Users/{id}/Enrollments/{id}
[HttpGet, ActionName("Enrollments")]
public IEnumerable<Enrollment> GetUserEnrollment(int userid, int id)
{
   //Code
}

如何防止/Users/GetUser成为有效路由?

GetUser(int id)上使用[NonAction]会阻止它完全工作。

编辑:这是/Users/GetUser的当前输出

<Error>
    <Message>An error has occurred.</Message>
    <ExceptionMessage>
        Multiple actions were found that match the request: Byui.ILearnAPI2.Business.Entities.User GetUser(Int32) on type Byui.ILearnAPI2.API.Controllers.UsersController System.Collections.Generic.IEnumerable`1[System.String] GetUserEnrollments(Int32) on type Byui.ILearnAPI2.API.Controllers.UsersController
    </ExceptionMessage>
    <ExceptionType>System.InvalidOperationException</ExceptionType>
    <StackTrace>
at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext) at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext) at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    </StackTrace>
</Error>

阻止调用 Web API 方法

再次查看您的帖子后,我认为您没有正确查看错误。

由于您配置控制器的方式,存在不明确的路由。

找到与请求匹配的多个操作:

GetUser(Int32) on type Byui.ILearnAPI2.API.Controllers.UsersController

GetUserEnrollments(Int32) on type Byui.ILearnAPI2.API.Controllers.UsersController

GetUser

和 GetUserEnrollments 共享相同的路由。据我所知,如果您向 GetUser 传递 int 或字符串或其他任何东西,它将无法工作,因为它不知道如何正确解析。

您可以在默认值之前添加路由配置以解决此问题。

config.Routes.MapHttpRoute(
    name: "GetUsers",
    routeTemplate: "api/users/{id}",
    defaults: new { controller = "Users", action = "GetUser" }
);

试试这个。

  1. 注释掉GetUserEnrollments(int id)
  2. 致电/Users/GetUser - 你会得到
 请求无效。  参数字典包含参数 'id' 的空条目  方法"so14610664"的不可为空类型"System.Int32"。模型.用户  GetUser(Int32)' 在 'so14610664.控制器.用户控制器'.一个可选的  参数必须是引用类型、可为 null 的类型或声明为  可选参数。
  1. 现在致电/User/abcdefg - 您会收到与上述相同的消息。 "The request is invalid..."

看,不是GetUser暴露了,而是它试图将/Users/之后的任何东西映射到id并失败,因为GetUser"abcdefg"在值Int32无效;换句话说:它认为你忘记了id


尝试使用属性路由包。 这是一个位于 MVC 路由(App_Start/RouteConfig 中的路由)和/或 Web API 路由(您正在执行的操作 - App_Start/WebApiConfig 中的路由)之上的包

使用该包,可以将 App_Start 中的路由映射替换为代码示例中的类似映射:

//Maps to /Users endpoint
[HttpGet, GET("/Users")]
public IEnumerable<User> GetAllUsers()
{
   //Code
}
//Maps to /Users/{id} endpoint
[HttpGet, GET("/Users/{id)"]
public User GetUser(int id)
{
   //Code
}
//Maps to /Users/{id}/Enrollments endpoint
[HttpGet, GET("/Users/{id}/Enrollments")]
public IEnumerable<Enrollment> GetUserEnrollments(int id)
{
   //Code
}
//Maps to /Users/{userid}/Enrollments/{id}
[HttpGet, GET("/Users/{userid}/Enrollments/{id}")]
public IEnumerable<Enrollment> GetUserEnrollment(int userid, int id)
{
   //Code
}

您可以使用 IHttpRouteConstraint 来验证 {id} 是否为整数,并在路由中指定路由约束。

可以在此处找到示例。

GetUsers返回 404,这是处理它的 Restful 方法。

您可以执行类似操作来验证提供的 id。如果未找到 Id,则可以返回包含所需代码的自定义响应消息。

[HttpGet]
public User GetUser(int id)
{
    if (id > 0 && validIds.Contains(id))
    {
        //Go do something fun...
    }
    else
        throw new HttpResponseException(
            new HttpResponseMessage(HttpStatusCode.NotFound)
                {
                    ReasonPhrase = String.Format("A valid id is required. {0} is most definitely not a valid id.", id);
                }

  );

}