Search code examples
c#asp.net-coreasp.net-core-2.2asp.net-core-routing

Asp.net core Routing with multiple optional parameters calling different action


In Asp.net WebApi2

when api/values/9b858599-7639-45da-acd6-a1323fb019b5 is called get Action is invoked.

Action with optional parameters.

When api/values/9b858599-7639-45da-acd6-a1323fb019b5?maxRecords=100 or api/values/?maxRecords=100 GetProducts Action is invoked.

In Asp.net Core

But in asp.net core when api/values/9b858599-7639-45da-acd6-a1323fb019b5 is called GetProducts Action is getting invoked. I wanted to call Get action without changing existing url's.

How to fix this issue in Asp.net core 2.0

Contoller

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    //https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5
    [HttpGet("{productId:Guid}", Order = 1)]
    public ActionResult<string> Get(Guid productId)
    {
        return "value1";
    }


    //https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5?maxRecords=100
    //https://localhost:44323/api/values/?maxRecords=100
    [HttpGet("{startRecordId:Guid?}")]
    public ActionResult<IEnumerable<string>> GetProducts(Guid? startRecordId, int maxRecords, DateTimeOffset? minimumChangeDate = null)
    {
        return new string[] { "value1", "value2" };

    }

}

Startup.cs

app.UseMvc(routes =>
        {
            routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
            routes.MapRoute("DefaultApi", "api/{controller}/{id?}");
        });

Solution

  • While not ideal, and this is a temporary shoehorn, till you can update the client calls. You could try this, if you can assume that you must have a maxRecords QueryString. Since if it defaults to 0 it is useless, unless you have logic in place in the case that it is 0.

        //https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5
        [HttpGet("{productId:Guid}", Order = 1)]
        public ActionResult<string> Get(Guid productId)
        {
            return "value1";
        }
    
    
        //https://localhost:44323/api/values/9b858599-7639-45da-acd6-a1323fb019b5?maxRecords=100
        //https://localhost:44323/api/values/?maxRecords=100
        [HttpGet("{startRecordId:Guid?}")]
        public ActionResult<IEnumerable<string>> GetProducts(Guid? startRecordId, [FromQuery] int maxRecords, [FromQuery] DateTimeOffset? minimumChangeDate = null)
        {
            if (!Request.GetDisplayUrl().Contains(nameof(maxRecords)) &&
                startRecordId.HasValue)
            {
                return Get(startRecordId.Value);
            }
    
            return new string[] { "value1", "value2" };
    
        }