mccalltd / AttributeRouting

Define your routes using attributes on actions in ASP.NET MVC and Web API.
http://mccalltd.github.io/AttributeRouting/
MIT License
416 stars 89 forks source link

QueryStringConstraints #248

Open smolesen opened 11 years ago

smolesen commented 11 years ago

Hi

I know AR doesn't really support QueryStringConstraint, though there seem to be support for the OptionalConstraint... However, running the following test fails in OptionalRouteConstraint

using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http;
using AttributeRouting;
using AttributeRouting.Web.Http;
using AttributeRouting.Web.Http.WebHost;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using HttpConfiguration = System.Web.Http.HttpConfiguration;

namespace UnitTestProject1
{
    [RoutePrefix("product")]
    public class ValuesController : ApiController
    {
        [GET("description?{count?}"), HttpGet]
        public HttpResponseMessage Description(string count = "0")
        {
            return Request.CreateResponse(HttpStatusCode.OK, string.Format("The quick brown fox jumps {0} times over the lazy dog", count));
        }
    }

    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            var configuration = new HttpConfiguration();

            configuration.Routes.MapHttpAttributeRoutes(cfg =>
                {
                    cfg.AutoGenerateRouteNames = true;
                    cfg.AddRoutesFromController<ValuesController>();
                    cfg.InMemory = true;
                });

            using (var server = new HttpServer(configuration))
            using (var client = new HttpClient(server))
            {

                var request = new HttpRequestMessage
                    {
                        RequestUri = new Uri("http://localhost:8080/product/description?count=6")
                    };

                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                request.Method = HttpMethod.Get;

                using (var response = client.SendAsync(request).Result)
                {
                    var description = response.Content.ReadAsStringAsync().Result;
                    Console.WriteLine(description);
                }
            }
        }
    }
}

Though changing

// If the param is optional and has no value, then pass the constraint
if (allDefaults.ContainsKey(parameterName) && allDefaults[parameterName] == RouteParameter.Optional)
{
    if (values[parameterName].HasNoValue())
    {
        return true;
    }
}

to

// If the param is optional and has no value, then pass the constraint
if (allDefaults.ContainsKey(parameterName) && allDefaults[parameterName] == RouteParameter.Optional)
{
    if (!values.ContainsKey(parameterName) || values[parameterName].HasNoValue())
    {
        return true;
    }
}

will solve the problem....