首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >ASP.NET Web API中的自定义方法名称

ASP.NET Web API中的自定义方法名称
EN

Stack Overflow用户
提问于 2012-03-05 23:30:13
回答 8查看 171.8K关注 0票数 113

我正在从WCF Web API转换到新的ASP.NET MVC4Web API。我有一个UsersController,并且我想有一个名为Authenticate的方法。我看到了如何执行GetAll、GetOne、Post和Delete的示例,但是,如果我想向这些服务中添加额外的方法怎么办?例如,我的UsersService应该有一个名为Authenticate的方法,它们在其中传入用户名和密码,但是它不起作用。

代码语言:javascript
复制
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?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 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中修改路径定义

代码语言:javascript
复制
Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { action = "get", id = RouteParameter.Optional }
);

现在,您可以导航到/api/users/getauthenticate对用户进行身份验证。

票数 138
EN

Stack Overflow用户

发布于 2012-08-30 03:33:29

这是到目前为止我想出的最好的方法,在支持正常的REST方法的同时还集成了额外的GET方法。将以下路由添加到您的WebApiConfig:

代码语言:javascript
复制
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)});

我用下面的测试类验证了这个解决方案。我成功地在下面的控制器中找到了每一个方法:

代码语言:javascript
复制
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)
    {
    }
}

我验证了它支持以下请求:

代码语言:javascript
复制
GET /Test
GET /Test/1
GET /Test/GetAll
POST /Test
PUT /Test/1
DELETE /Test/1

请注意,如果额外的GET操作不是以'Get‘开始的,则可能需要向该方法添加一个HttpGet属性。

票数 89
EN

Stack Overflow用户

发布于 2013-08-30 20:48:25

我已经进入了MVC4的世界。

不管它有什么价值,我有一个SitesAPIController,并且我需要一个自定义方法,它可以像这样调用:

代码语言:javascript
复制
http://localhost:9000/api/SitesAPI/Disposition/0

对最后一个参数使用不同的值,以获得具有不同配置的记录。

最终对我起作用的是:

SitesAPIController中的方法:

代码语言:javascript
复制
// 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中

代码语言:javascript
复制
// 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},我就会遇到:

代码语言:javascript
复制
{
"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}时,它开始工作。显然,参数名与占位符中的值是匹配的。

请随意编辑此答案以使其更准确/更具说明性。

票数 22
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9569270

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档