ASP.NET Web API中的自定义方法名称
我正在从WCF Web API转换到新的ASP.NET MVC 4 Web API。 我有一个UsersController,我想要一个名为Authenticate的方法。 我看到了如何执行GetAll,GetOne,Post和Delete的例子,但是如果我想向这些服务中添加额外的方法呢? 例如,我的UsersService应该有一个名为Authenticate的方法,它们传递用户名和密码,但它不起作用。
public class UsersController : BaseApiController
{
public string GetAll()
{
return "getall!";
}
public string Get(int id)
{
return "get 1! " + id;
}
public User GetAuthenticate(string userName, string password, string applicationName)
{
LogWriter.Write(String.Format("Received authenticate request for username {0} and password {1} and application {2}",
userName, password, applicationName));
//check if valid leapfrog login.
var decodedUsername = userName.Replace("%40", "@");
var encodedPassword = password.Length > 0 ? Utility.HashString(password) : String.Empty;
var leapFrogUsers = LeapFrogUserData.FindAll(decodedUsername, encodedPassword);
if (leapFrogUsers.Count > 0)
{
return new User
{
Id = (uint)leapFrogUsers[0].Id,
Guid = leapFrogUsers[0].Guid
};
}
else
throw new HttpResponseException("Invalid login credentials");
}
}
我可以浏览到myapi / api / users /,它会调用GetAll,我可以浏览到myapi / api / users / 1,它会调用Get,但是如果我调用myapi / api / users / authenticate?username = {0} &password = {1},那么它会调用Get(NOT Authenticate)和错误:
参数字典包含'Navtrak.Services.WCF.NavtrakAPI.Controllers.UsersController'中方法'System.String Get(Int32)'的非空类型'System.Int32'的参数'id'的空项。 可选参数必须是引用类型,可为空类型,或者声明为可选参数。
我如何调用自定义方法名称,例如Authenticate?
默认情况下,路由配置遵循RESTFul约定,这意味着它将只接受Get,Post,Put和Delete操作名称(查看global.asax中的路由=>默认情况下,它不允许您指定任何操作name =>它使用HTTP动词来分派)。 所以,当你发送一个GET请求到/api/users/authenticate
你基本上调用Get(int id)
动作并传递id=authenticate
,这显然会崩溃,因为你的Get动作需要一个整数。
如果你想有不同于标准动作名称的动作名称,你可以在global.asax
修改你的路由定义:
Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = "get", id = RouteParameter.Optional }
);
现在您可以导航到/api/values/getauthenticate
来验证用户身份。
这是迄今为止我想出的最好的方法,它在支持正常的REST方法的同时还包含额外的GET方法。 将以下路由添加到您的WebApiConfig中:
routes.MapHttpRoute("DefaultApiWithId", "Api/{controller}/{id}", new { id = RouteParameter.Optional }, new { id = @"d+" });
routes.MapHttpRoute("DefaultApiWithAction", "Api/{controller}/{action}");
routes.MapHttpRoute("DefaultApiGet", "Api/{controller}", new { action = "Get" }, new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) });
routes.MapHttpRoute("DefaultApiPost", "Api/{controller}", new {action = "Post"}, new {httpMethod = new HttpMethodConstraint(HttpMethod.Post)});
我使用下面的测试课来验证这个解决方案。 我能够成功地击中我的控制器中的每个方法:
public class TestController : ApiController
{
public string Get()
{
return string.Empty;
}
public string Get(int id)
{
return string.Empty;
}
public string GetAll()
{
return string.Empty;
}
public void Post([FromBody]string value)
{
}
public void Put(int id, [FromBody]string value)
{
}
public void Delete(int id)
{
}
}
我证实它支持以下请求:
GET /Test
GET /Test/1
GET /Test/GetAll
POST /Test
PUT /Test/1
DELETE /Test/1
请注意,如果您的额外GET操作不以“Get”开头,您可能需要为该方法添加HttpGet属性。
我是进入MVC4世界的日子。
对于它的价值,我有一个SitesAPIController,我需要一个自定义方法,可以这样调用:
http://localhost:9000/api/SitesAPI/Disposition/0
用最后一个参数的不同值来获取不同配置的记录。
最后为我工作的是:
SitesAPIController中的方法:
// GET api/SitesAPI/Disposition/1
[ActionName("Disposition")]
[HttpGet]
public Site Disposition(int disposition)
{
Site site = db.Sites.Where(s => s.Disposition == disposition).First();
return site;
}
而这个在WebApiConfig.cs中
// this was already there
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// this i added
config.Routes.MapHttpRoute(
name: "Action",
routeTemplate: "api/{controller}/{action}/{disposition}"
);
只要我将{disposition}命名为我遇到的{id}:
{
"Message": "No HTTP resource was found that matches the request URI 'http://localhost:9000/api/SitesAPI/Disposition/0'.",
"MessageDetail": "No action was found on the controller 'SitesAPI' that matches the request."
}
当我将它重命名为{disposition}时,它开始工作。 显然,参数名称与占位符中的值匹配。
随意编辑这个答案,使其更加准确/解释。
链接地址: http://www.djcxy.com/p/20533.html