如何向ASP.NET WebAPI控制器添加自定义方法?

时间:2014-07-19 17:49:13

标签: c# asp.net-mvc asp.net-web-api2

默认情况下,在 ASP.NET MVC WebAPI 项目中,我们创建了以下控制器

 public class ValuesController : ApiController
    {
        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/values
        public void Post([FromBody]string value)
        {
        }

        // PUT api/values/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/values/5
        public void Delete(int id)
        {
        }
}

但是可以在这里添加任何自定义方法,以便它们也可以支持get / post吗?

谢谢!

4 个答案:

答案 0 :(得分:18)

您可以使用带有Http类型的RoutePrefix等属性。

[Route("ChangePassword")]
[HttpPost] // There are HttpGet, HttpPost, HttpPut, HttpDelete.
public async Task<IHttpActionResult> ChangePassword(ChangePasswordModel model)
{        
}

http类型会将其与路径名称一起映射回正确的方法。

答案 1 :(得分:14)

我不确定我是否按照您的代码中GETPOST进行操作,但无论如何您还有其他选择:

选项1

首先,您可以在App_Start文件的WebApiConfig.cs文件夹中配置自定义路由。这是我通常使用的:

    // GET /api/{resource}/{action}
    config.Routes.MapHttpRoute(
        name: "Web API RPC",
        routeTemplate: "{controller}/{action}",
        defaults: new { },
        constraints: new { action = @"[A-Za-z]+", httpMethod = new HttpMethodConstraint("GET") }
        );

    // GET|PUT|DELETE /api/{resource}/{id}/{code}
    config.Routes.MapHttpRoute(
        name: "Web API Resource",
        routeTemplate: "{controller}/{id}/{code}",
        defaults: new { code = RouteParameter.Optional },
        constraints: new { id = @"\d+" }
        );

    // GET /api/{resource}
    config.Routes.MapHttpRoute(
        name: "Web API Get All",
        routeTemplate: "{controller}",
        defaults: new { action = "Get" },
        constraints: new { httpMethod = new HttpMethodConstraint("GET") }
        );

    // PUT /api/{resource}
    config.Routes.MapHttpRoute(
        name: "Web API Update",
        routeTemplate: "{controller}",
        defaults: new { action = "Put" },
        constraints: new { httpMethod = new HttpMethodConstraint("PUT") }
        );

    // POST /api/{resource}
    config.Routes.MapHttpRoute(
        name: "Web API Post",
        routeTemplate: "{controller}",
        defaults: new { action = "Post" },
        constraints: new { httpMethod = new HttpMethodConstraint("POST") }
        );

    // POST /api/{resource}/{action}
    config.Routes.MapHttpRoute(
        name: "Web API RPC Post",
        routeTemplate: "{controller}/{action}",
        defaults: new { },
        constraints: new { action = @"[A-Za-z]+", httpMethod = new HttpMethodConstraint("POST") }
        );

我使用RESTful个端点和RPC端点的组合。对于一些纯粹主义者来说,这是进行圣战的理由。对我来说,我使用两者的组合,因为它是一个强大的组合,我找不到任何理智的理由。

选项2

正如其他人已经指出的那样,并且我自己现在正在做更多的事情,使用属性路由:

    [HttpGet]
    [GET("SomeController/SomeUrlSegment/{someParameter}")]
    public int SomeUrlSegment(string someParameter)
    {
        //do stuff
    }

我需要一个用于属性路由的NuGet包才能使其工作(只需在NuGet中搜索“属性路由”),但我认为MVC 5 / WebAPI 2本身就有它。

希望这有帮助。

答案 2 :(得分:11)

您可以使用属性路由:

[Route("customers/{customerId}/orders")]
public IEnumerable<Order> GetOrdersByCustomer(int customerId) { ... }

一些文档可以帮助您入门:

http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

答案 3 :(得分:1)

首先将此路线放到webapiconfig.cs

config.Routes.MapHttpRoute(
            name: "ApiWithAction",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

现在您可以像这样添加动作到控制器

 [HttpPost]
    public void Upload()
    {
           //Do some thing
    }

我使用httppost属性修饰上传操作,这意味着此操作只接受帖子请求,如果您想要操作GET,您可以移除属性或只是装饰到您的套件