ASP.NET Web API属性路由到错误的操作

时间:2017-07-18 11:44:48

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

我已经在我的控制器上应用了属性路由,并且它正在进行错误的操作。我不知道我在哪里弄错了。

这是我的控制器:

using System.Collections.Generic;
using System.Web.Http;
using System.Web.Http.Description;
using System.Linq;
using System;

namespace Iboo.API.Controllers
{
    public class ClientsController : ApiController
    {
        private readonly IClientRepository _repository;

        public ClientsController(IClientRepository repository)
        {
            _repository = repository;
        }

        // GET: api/Clients
        [Route("api/v1/clients")]
        public IEnumerable<Client> Get()
        {

           //code
        }


        // GET: api/Clients/5
        [HttpGet]
        [ResponseType(typeof(Client))]
        [Route("api/v1/clients/get/{id}")]
        public IHttpActionResult GetClientById(int id)
        {
            //code
        }

        // GET: api/Clients/5
        [HttpGet]
        [ResponseType(typeof(string))]
        [Route("api/v1/clients/{id}/emailid")]
        public IHttpActionResult GetClientEmailId(int id)
        {
            //code
        }        
    }
}

我对 GetClientEmailId 方法特别感兴趣。下面是我的WebApiConfig

public static void Register(HttpConfiguration config)
{
    // Web API configuration and services
    var container = new UnityContainer();
    container.RegisterType<IClientRepository, ClientRepository>(new 
    HierarchicalLifetimeManager());


    // Web API routes
    config.MapHttpAttributeRoutes();

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

我的Global.asax.cs如下

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}

在浏览器中如果我输入http://localhost:54919/api/v1/clients/?id=1/getemailid,它会将我带到http://localhost:54919/api/v1/clients,这不是我想要的。

如果我尝试http://localhost:54919/api/v1/clients/1/getemailid,我收到404错误。

我不确定我的错误。

3 个答案:

答案 0 :(得分:0)

您可以尝试在控制器上使用路由前缀。

[RoutePrefix("api/v1/clients")]
public class ClientsController : ApiController
{
    // GET: api/Clients/5
    [ResponseType(typeof(string))]
    [Route("{id:int}/emailid"),HttpGet]
    public IHttpActionResult GetClientEmailId(int id)
    {
        //code
    }     
}

答案 1 :(得分:0)

你说:

  

在浏览器中如果我输入http://localhost:54919/api/v1/clients/?id=1/getemailid,则会将我带到http://localhost:54919/api/v1/clients,这不是我想要的。

从您设置路线的方式来看,您似乎需要前往http://localhost:54919/api/v1/client/1/emailid才能到达您想要的路线

为了解释这种差异,当您致电http://localhost:54919/api/v1/clients/?id=1/getemailid时,与之匹配的路线如下:

[Route("api/v1/clients")]
public IHttpActionResult GetClientEmailId(string id)
{
    //code
}

因为您已将id参数添加为查询字符串参数。在这种情况下,id参数的值为1/getemailid,这没有多大意义。

使用路线参数(将?id=1/getemailid替换为1/emailid),您将实际匹配您想要的路线

答案 2 :(得分:0)

您根据操作路线调用错误的网址。您得到404,因为您调用的URL与您的操作中的任何路径模板不匹配

[RoutePrefix("api/v1/clients")]
public class ClientsController : ApiController {
    //...other code removed for brevity

    [HttpGet]
    [Route("")] //Matches GET api/v1/Clients
    public IHttpActionResult Get() {
       //code
    }

    [HttpGet]
    [ResponseType(typeof(Client))]
    [Route("{id:int}")] //Matches GET api/v1/Clients/5
    public IHttpActionResult GetClientById(int id) {
        //code
    }

    [HttpGet]
    [ResponseType(typeof(string))]
    [Route("{id:int}/emailid")] //Matches GET api/v1/Clients/5/emailid
    public IHttpActionResult GetClientEmailId(int id) {
        //code
    }        
}

记下评论中的预期网址

您还应该阅读What's the best way to validate an XML file against an XSD file?,以便更好地了解如何进行属性路由。