4

我正在使用 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 }
);

在我的 UsersController.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成为有效路线?

使用[NonAction]onGetUser(int id)可以防止它完全工作。

编辑:这是当前的输出/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>
4

5 回答 5

2

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

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

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

类型 Byui.ILearnAPI2.API.Controllers.UsersController 上的GetUser(Int32)

类型 Byui.ILearnAPI2.API.Controllers.UsersController 上的GetUserEnrollments(Int32)

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

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

config.Routes.MapHttpRoute(
    name: "GetUsers",
    routeTemplate: "api/users/{id}",
    defaults: new { controller = "Users", action = "GetUser" }
);
于 2013-01-30T21:06:04.957 回答
2

试试这个。

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

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


试试AttributeRouting包。 这是一个位于 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
}
于 2013-01-30T22:04:32.867 回答
1

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

可以在此处找到示例。

于 2013-01-30T18:17:15.297 回答
0

返回一个 404,这是处理它的RestfulGetUsers方式。

于 2013-01-30T18:15:36.113 回答
0

你可以做这样的事情来验证提供的 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);
                }


  );

}

于 2013-01-30T20:35:46.547 回答