我正在从WCF Web API转换到新的ASP.NET MVC4Web 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,但是如果我调用Get,则它将调用Get(而不是身份验证),并出现错误:
参数字典包含'Navtrak.Services.WCF.NavtrakAPI.Controllers.UsersController'.中'System.String Get(Int32)‘方法的非null类型为'System.Int32’的参数'id‘的null条目可选参数必须是引用类型、可以为must的类型或声明为可选参数。
如何调用自定义方法名称,如Authenticate?
发布于 2012-03-05 23:36:03
默认情况下,路由配置遵循RESTFul约定,这意味着它将只接受Get、Post、Put和Delete操作名称(查看global.asax =>中的路由,默认情况下,它不允许您指定任何操作名称=>,它使用HTTP动词进行分派)。因此,当您向/api/users/authenticate
发送GET请求时,您基本上是在调用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/users/getauthenticate
对用户进行身份验证。
发布于 2012-08-30 03:33:29
这是到目前为止我想出的最好的方法,在支持正常的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属性。
发布于 2013-08-30 20:48:25
我已经进入了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}时,它开始工作。显然,参数名与占位符中的值是匹配的。
请随意编辑此答案以使其更准确/更具说明性。
https://stackoverflow.com/questions/9569270
复制相似问题