Query string not working while using attribute routing

后端 未结 8 2157
無奈伤痛
無奈伤痛 2020-11-27 12:52

I\'m using System.Web.Http.RouteAttribute and System.Web.Http.RoutePrefixAttribute to enable cleaner URLs for my Web API 2 application. For most of

相关标签:
8条回答
  • 2020-11-27 13:27

    With the Attribute routing you need to specify default values so they would be optional.

    [Route("{name}/{sport=Football}/{drink=Coke}")]
    

    Assigning a value will allow it to be optional so you do not have to include it and it will pass the value to specify.

    I have not tested the query string for this but it should work the same.

    I just re-read the question and I see that you have 2 Get verbs with the same path, I believe this would cause conflict as routing would not know which one to utilize, perhaps using the optional params will help. You can also specify one can be null and do checking in the method as to how to proceed.

    [Route("{name}/{sport?}/{drink?}")]
    

    Then check the variables in the method to see if they are null and handle as needed.

    Hope this helps, some? lol

    If not perhaps this site will, it has more details about attribute routing.

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

    Clip from that site:

    Optional parameters and default values You can specify that a parameter is optional by adding a question mark to the parameter, that is:

    [Route("countries/{name?}")]
    public Country GetCountry(string name = "USA") { }
    

    Currently, a default value must be specified on the optional parameter for action selection to succeed, but we can investigate lifting that restriction. (Please let us know if this is important.)

    Default values can be specified in a similar way:

    [Route("countries/{name=USA}")]
    public Country GetCountry(string name) { }
    

    The optional parameter '?' and the default values must appear after inline constraints in the parameter definition.

    0 讨论(0)
  • 2020-11-27 13:34

    I use FromUri attribute as solution

    [Route("UsageAggregationDaily")]
    public async Task<HttpResponseMessage> UsageAggregationDaily([FromUri] string userId = null, [FromUri] DateTime? startDate = null, [FromUri] DateTime? endDate = null)
    
    0 讨论(0)
  • 2020-11-27 13:36

    Using Route("search/{categoryid=categoryid}/{ordercode=ordercode}") will enable you to use both Querystrings and inline route parameters as answered by mosharaf hossain. Writing this answer as this should be top answer and best way. Using Route("") will cause problems if you have multiple Gets/Puts/Posts/Deletes.

    0 讨论(0)
  • 2020-11-27 13:36

    Here's a slight deviant of @bhargav kishore mummadireddy's answer, but an important deviation. His answer will default the querystring values to an actual non-empty value. This answer will default them to empty.

    It allows you to call the controller through path routing, or using the querystring. Essentially, it sets the default value of the querystring to empty, meaning it will always be routed.

    This was important to me, because I want to return 400 (Bad Request) if a querystring is not specified, rather than having ASP.NET return the "could not locate this method on this controller" error.

    [RoutePrefix("api/AppUsageReporting")]
    public class AppUsageReportingController : ApiController
        {
            [HttpGet]
            // Specify default routing parameters if the parameters aren't specified
            [Route("UsageAggregationDaily/{userId=}/{startDate=}/{endDate=}")]
            public async Task<HttpResponseMessage> UsageAggregationDaily(string userId, DateTime? startDate, DateTime? endDate)
            {
                if (String.IsNullOrEmpty(userId))
                {
                    return Request.CreateResponse(HttpStatusCode.BadRequest, $"{nameof(userId)} was not specified.");
                }
    
                if (!startDate.HasValue)
                {
                    return Request.CreateResponse(HttpStatusCode.BadRequest, $"{nameof(startDate)} was not specified.");
                }
    
                if (!endDate.HasValue)
                {
                    return Request.CreateResponse(HttpStatusCode.BadRequest, $"{nameof(endDate)} was not specified.");
                }
            }
        }
    
    0 讨论(0)
  • 2020-11-27 13:37

    I was facing the same issue of 'How to include search parameters as a query string?', while I was trying to build a web api for my current project. After googling, the following is working fine for me:

    Api controller action:

    [HttpGet, Route("search/{categoryid=categoryid}/{ordercode=ordercode}")]
    
    public Task<IHttpActionResult> GetProducts(string categoryId, string orderCode)
    {
    
    }
    

    The url I tried through postman:

    http://localhost/PD/search?categoryid=all-products&ordercode=star-1932
    
    http://localhost/PD is my hosted api
    
    0 讨论(0)
  • 2020-11-27 13:46

    After much painstaking fiddling and Googling, I've come up with a 'fix'. I don't know if this is ideal/best practice/plain old wrong, but it solves my issue.

    All I did was add [Route("")] in addition to the route attributes I was already using. This basically allows Web API 2 routing to allow query strings, as this is now a valid Route.

    An example would now be:

    [HttpGet]
    [Route("")]
    [Route("{name}/{drink}/{sport?}")]
    public List<int> Get(string name, string drink, string sport = "")
    {
        // Code removed...
    }
    

    This makes both localhost:12345/1/Names/Ted/coke and localhost:12345/1/Names?name=Ted&drink=coke valid.

    0 讨论(0)
提交回复
热议问题