在ASP.NET Web API中使用多个Get方法进行路由

时间:2012-10-08 05:03:55

标签: c# asp.net-web-api asp.net-web-api-routing

我正在使用带有ASP.NET MVC的Web Api,我对它很新。我在asp.net网站上经历过一些演示,我正在尝试做以下事情。

我有4个get方法,带有以下签名

public List<Customer> Get()
{
    // gets all customer
}

public List<Customer> GetCustomerByCurrentMonth()
{
    // gets some customer on some logic
}

public Customer GetCustomerById(string id)
{
    // gets a single customer using id
}

public Customer GetCustomerByUsername(string username)
{
    // gets a single customer using username
}

对于上述所有方法,我希望我的web api有点像下面所示

  • 列出Get()= api/customers/
  • 客户GetCustomerById(字符串ID)= api/customers/13
  • 列出GetCustomerByCurrentMonth()= /customers/currentMonth
  • 客户GetCustomerByUsername(字符串用户名)= /customers/customerByUsername/yasser

我尝试对路由进行更改,但由于我是新手,所以不太了解。

所以,请一些人帮助我理解并指导我如何做到这一点。感谢

10 个答案:

答案 0 :(得分:73)

从这里Routing in Asp.net Mvc 4 and Web Api

Darin Dimitrov 发布了一个非常好的答案,对我有用。

它说......

你可以有几条路线:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "ApiById",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: new { id = @"^[0-9]+$" }
        );

        config.Routes.MapHttpRoute(
            name: "ApiByName",
            routeTemplate: "api/{controller}/{action}/{name}",
            defaults: null,
            constraints: new { name = @"^[a-z]+$" }
        );

        config.Routes.MapHttpRoute(
            name: "ApiByAction",
            routeTemplate: "api/{controller}/{action}",
            defaults: new { action = "Get" }
        );
    }
}

答案 1 :(得分:47)

首先,在顶部添加 action 的新路线:

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

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

然后使用ActionName属性进行映射:

[HttpGet]
public List<Customer> Get()
{
    //gets all customer
}

[ActionName("CurrentMonth")]
public List<Customer> GetCustomerByCurrentMonth()
{
    //gets some customer on some logic
}

[ActionName("customerById")]
public Customer GetCustomerById(string id)
{
    //gets a single customer using id
}

[ActionName("customerByUsername")]
public Customer GetCustomerByUsername(string username)
{
    //gets a single customer using username
}

答案 2 :(得分:16)

  

您还将为设置路线指定行动路线

[HttpGet]
[Route("api/customers/")]
public List<Customer> Get()
{
   //gets all customer logic
}

[HttpGet]
[Route("api/customers/currentMonth")]
public List<Customer> GetCustomerByCurrentMonth()
{
     //gets some customer 
}

[HttpGet]
[Route("api/customers/{id}")]
public Customer GetCustomerById(string id)
{
  //gets a single customer by specified id
}
[HttpGet]
[Route("api/customers/customerByUsername/{username}")]
public Customer GetCustomerByUsername(string username)
{
    //gets customer by its username
}

答案 3 :(得分:5)

只有一条足够的路线

config.Routes.MapHttpRoute("DefaultApiWithAction", "{controller}/{action}");

需要在所有操作中指定属性 HttpGet HttpPost

[HttpGet]
public IEnumerable<object> TestGet1()
{
    return new string[] { "value1", "value2" };
}

[HttpGet]
public IEnumerable<object> TestGet2()
{
    return new string[] { "value3", "value4" };
}

答案 4 :(得分:4)

这个问题已经有很多好的答案了。但是现在,Route配置已经被弃用了#34;。较新版本的MVC(.NET Core)不支持它。所以更好地利用它:)

所以我同意所有使用属性样式路由的答案。但我一直注意到每个人都重复了路线的基础部分(api / ...)。最好在Controller类的顶部应用 [RoutePrefix] 属性,不要反复重复相同的字符串。

[RoutePrefix("api/customers")]
public class MyController : Controller
{
 [HttpGet]
 public List<Customer> Get()
 {
   //gets all customer logic
 }

 [HttpGet]
 [Route("currentMonth")]
 public List<Customer> GetCustomerByCurrentMonth()
 {
     //gets some customer 
 }

 [HttpGet]
 [Route("{id}")]
 public Customer GetCustomerById(string id)
 {
  //gets a single customer by specified id
 }
 [HttpGet]
 [Route("customerByUsername/{username}")]
 public Customer GetCustomerByUsername(string username)
 {
    //gets customer by its username
 }
}

答案 5 :(得分:1)

在读完很多答案之后我终于明白了。

首先,我在WebApiConfig.cs中添加了3条不同的路线

public static void Register(HttpConfiguration config)
{
    // Web API configuration and services

    // Web API routes
    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "ApiById",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional },
        constraints: new { id = @"^[0-9]+$" }
    );

    config.Routes.MapHttpRoute(
        name: "ApiByName",
        routeTemplate: "api/{controller}/{action}/{name}",
        defaults: null,
        constraints: new { name = @"^[a-z]+$" }
    );

    config.Routes.MapHttpRoute(
        name: "ApiByAction",
        routeTemplate: "api/{controller}/{action}",
        defaults: new { action = "Get" }
    );
}

然后,从控制器功能中删除ActionName,Route等。所以基本上这是我的控制器;

// GET: api/Countries/5
[ResponseType(typeof(Countries))]
//[ActionName("CountryById")]
public async Task<IHttpActionResult> GetCountries(int id)
{
    Countries countries = await db.Countries.FindAsync(id);
    if (countries == null)
    {
        return NotFound();
    }

    return Ok(countries);
}

// GET: api/Countries/tur
//[ResponseType(typeof(Countries))]
////[Route("api/CountriesByName/{anyString}")]
////[ActionName("CountriesByName")]
//[HttpGet]
[ResponseType(typeof(Countries))]
//[ActionName("CountryByName")]
public async Task<IHttpActionResult> GetCountriesByName(string name)
{
    var countries = await db.Countries
            .Where(s=>s.Country.ToString().StartsWith(name))
            .ToListAsync();

    if (countries == null)
    {
        return NotFound();
    }

    return Ok(countries);
}

现在我可以运行以下url示例(带名称和id);

http://localhost:49787/api/Countries/GetCountriesByName/France

http://localhost:49787/api/Countries/1

答案 6 :(得分:0)

您可能不需要对路由进行任何更改。只需在customersController.cs文件中添加以下四种方法:

public ActionResult Index()
{
}

public ActionResult currentMonth()
{
}

public ActionResult customerById(int id)
{
}


public ActionResult customerByUsername(string userName)
{
}

将相关代码放入方法中。使用提供的默认路由,您应该根据给定URL的操作和参数从控制器获得适当的操作结果。

将您的默认路线修改为:

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Api", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

答案 7 :(得分:0)

  // this piece of code in the WebApiConfig.cs file or your custom bootstrap application class
  // define two types of routes 1. DefaultActionApi  and 2. DefaultApi as below

   config.Routes.MapHttpRoute("DefaultActionApi", "api/{controller}/{action}/{id}", new { id = RouteParameter.Optional });
   config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { action = "Default", id = RouteParameter.Optional });

  // decorate the controller action method with [ActionName("Default")] which need to invoked with below url
  // http://localhost:XXXXX/api/Demo/ -- will invoke the Get method of Demo controller
  // http://localhost:XXXXX/api/Demo/GetAll -- will invoke the GetAll method of Demo controller
  // http://localhost:XXXXX/api/Demo/GetById -- will invoke the GetById method of Demo controller
  // http://localhost:57870/api/Demo/CustomGetDetails -- will invoke the CustomGetDetails method of Demo controller
  // http://localhost:57870/api/Demo/DemoGet -- will invoke the DemoGet method of Demo controller


 public class DemoController : ApiController
 {
    // Mark the method with ActionName  attribute (defined in MapRoutes) 
    [ActionName("Default")]
    public HttpResponseMessage Get()
    {
        return Request.CreateResponse(HttpStatusCode.OK, "Get Method");
    }

    public HttpResponseMessage GetAll()
    {
        return Request.CreateResponse(HttpStatusCode.OK, "GetAll Method");
    }

    public HttpResponseMessage GetById()
    {
        return Request.CreateResponse(HttpStatusCode.OK, "Getby Id Method");
    }

    //Custom Method name
    [HttpGet]
    public HttpResponseMessage DemoGet()
    {
        return Request.CreateResponse(HttpStatusCode.OK, "DemoGet Method");
    }

    //Custom Method name
    [HttpGet]
    public HttpResponseMessage CustomGetDetails()
    {
        return Request.CreateResponse(HttpStatusCode.OK, "CustomGetDetails Method");
    }
}

答案 8 :(得分:0)

我有两个带有相同参数或没有参数的方法

[Route("api/ControllerName/FirstList")]
[HttpGet]
public IHttpActionResult FirstList()
{
}

[Route("api/ControllerName/SecondList")]
[HttpGet]
public IHttpActionResult SecondList()
{
}

只需在AppStart=>WebApiConfig.cs =&gt;中定义自定义路线即可在登记方法

config.Routes.MapHttpRoute(
       name: "GetFirstList",
       routeTemplate: "api/Controllername/FirstList"          
       );
config.Routes.MapHttpRoute(
       name: "GetSecondList",
       routeTemplate: "api/Controllername/SecondList"          
       );

答案 9 :(得分:0)

using Routing.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace Routing.Controllers
{
    public class StudentsController : ApiController
    {
        static List<Students> Lststudents =
              new List<Students>() { new Students { id=1, name="kim" },
           new Students { id=2, name="aman" },
            new Students { id=3, name="shikha" },
            new Students { id=4, name="ria" } };

        [HttpGet]
        public IEnumerable<Students> getlist()
        {
            return Lststudents;
        }

        [HttpGet]
        public Students getcurrentstudent(int id)
        {
            return Lststudents.FirstOrDefault(e => e.id == id);
        }
        [HttpGet]
        [Route("api/Students/{id}/course")]
        public IEnumerable<string> getcurrentCourse(int id)
        {
            if (id == 1)
                return new List<string>() { "emgili", "hindi", "pun" };
            if (id == 2)
                return new List<string>() { "math" };
            if (id == 3)
                return new List<string>() { "c#", "webapi" };
            else return new List<string>() { };
        }

        [HttpGet]
        [Route("api/students/{id}/{name}")]
        public IEnumerable<Students> getlist(int id, string name)
        { return Lststudents.Where(e => e.id == id && e.name == name).ToList(); }

        [HttpGet]
        public IEnumerable<string> getlistcourse(int id, string name)
        {
            if (id == 1 && name == "kim")
                return new List<string>() { "emgili", "hindi", "pun" };
            if (id == 2 && name == "aman")
                return new List<string>() { "math" };
            else return new List<string>() { "no data" };
        }
    }
}