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

上一篇: Custom method names in ASP.NET Web API

下一篇: ASP.NET Web API Authorization with AuthorizeAttribute