skip to Main Content

I have the following endpoints in my project

A -> http://localhost:8089/products/
B -> http://localhost:8089/products/{id}

I need to add the following:

C -> http://localhost:8089/products/{id}/track

but when I run the new endpoint I get the following error (endpoint B is also affected):

Multiple actions were found that match the request: 
GetProduct on type ProductsApi.Controllers.ProductsController
GetProductTracking on type ProductsApi.Controllers.ProductsController
   en System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)
   en System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)
   en System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)
   en System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()

My controller has:

using System;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;

namespace ProductsApi.Controllers
{
    [Route("controller")]
    [Authorize]
    public class ProductsController : BaseController
    {
        private readonly IProductService _ProductService;

        public ProductsController(IProductService ProductService)
        {
            _ProductService = ProductService;
        }

        [HttpGet]
        public async Task<IHttpActionResult> ListProducts(string startDate = "", string endDate = "", string brand = "")
        {
            ProductFilterRequest filterProductRequest = new ProductFilterRequest(startDate, endDate, brand);
            var result = await _ProductService.ListProducts(filterProductRequest);
            return Ok(result);
        }

        [HttpGet]
        public async Task<IHttpActionResult> GetProduct(int id)
        {
            var result = await _ProductService.GetProductDetail(id);
            return Ok(result);
        }

        [HttpGet()]
        [Route("{id}/track")]
        public async Task<IHttpActionResult> GetProductTracking(int id)
        {
            var result = await _ProductService.GetProductTracking(id);
            return Ok(result);
        }

    }
}

Startup.cs

using Microsoft.Owin;
using System.Web.Http;
using System.Configuration;

[assembly: OwinStartup(typeof(Product.Api.Startup))]
namespace Product.Api
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ....

            // configure web api
            var config = new HttpConfiguration();
            config.MapHttpAttributeRoutes();           
            app.UseWebApi(config);
        }
    }
}

Global.asax.cs

using Newtonsoft.Json.Serialization;
...
using System.Web.Http;

namespace Product.Api
{
    public class WebApiApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AutoMapperConfig.Initialize();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            ...
        }
    }
}

WebApiConfig.cs

I have configured the routing and I have tried making modifications in the routetemplate but without any result.

using System.Web.Http;

namespace Product.Api
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                 name: "DefaultApi",
                 routeTemplate: "{controller}/{id}/{name}",
                 defaults: new
                 { 
                     id = RouteParameter.Optional,
                     name=RouteParameter.Optional
                 }
             );
        }
    }
}

3

Answers


  1. [Route("track/{id}")]
    Could you try put the variable {id} at the end of the address?

    Login or Signup to reply.
  2. Try this

            [HttpGet("track/{id}")]
            public async Task<IHttpActionResult> GetProductTracking(int id)
            {
                var result = await _ProductService.GetProductTracking(id);
                return Ok(result);
            }
    
    Login or Signup to reply.
  3. In Startup.cs
    Comment the code below, this setting is not being applied correctly

    using Microsoft.Owin;
    using System.Web.Http;
    using System.Configuration;
    
    [assembly: OwinStartup(typeof(Product.Api.Startup))]
    namespace Product.Api
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                ....
    
                // configure web api
                //var config = new HttpConfiguration();
                //config.MapHttpAttributeRoutes();
                //app.UseWebApi(config);
            }
        }
    }
    

    In WebApiConfig.cs you need add below line

    config.MapHttpAttributeRoutes();
    

    Finally in your controller, You can set a common prefix for an entire controller by using the [RoutePrefix] attribute and for actions add [Route] attribute

    using System;
    using System.Diagnostics;
    using System.Net;
    using System.Net.Http;
    using System.Threading.Tasks;
    using System.Web.Http;
    
    namespace ProductsApi.Controllers
    {
        [RoutePrefix("orders")]
        [Authorize]
        public class ProductsController : BaseController
        {
            private readonly IProductService _ProductService;
    
            public ProductsController(IProductService ProductService)
            {
                _ProductService = ProductService;
            }
            public OrdersController()
            {            
            }
    
            [HttpGet]
            public async Task<IHttpActionResult> ListProducts(string startDate = "", string endDate = "", string brand = "")
            {
                ProductFilterRequest filterProductRequest = new ProductFilterRequest(startDate, endDate, brand);
                var result = await _ProductService.ListProducts(filterProductRequest);
                return Ok(result);
            }
    
            [HttpGet]
            public async Task<IHttpActionResult> GetProduct(int id)
            {
                var result = await _ProductService.GetProductDetail(id);
                return Ok(result);
            }
    
            [HttpGet()]
            [Route("{id}/track")]
            public async Task<IHttpActionResult> GetProductTracking(int id)
            {
                var result = await _ProductService.GetProductTracking(id);
                return Ok(result);
            }
    
        }
    }
    

    See more in https://learn.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search