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

AttributeRouting not working with HttpConfiguration object for writing Integration tests #264

Open abpatel opened 11 years ago

abpatel commented 11 years ago

I'm creating some integration tests following the ideas outlined here: http://www.strathweb.com/2012/06/asp-net-web-api-integration-testing-with-in-memory-hosting/

When I try to register routes from a hand crafted HttpConfiguration object I'm getting the following error: "The constraint entry 'inboundHttpMethod' on the route with route template 'api/Contacts/{id}' must have a string value or be of a type which implements 'IHttpRouteConstraint'."

Sample code: Controller: [RoutePrefix("api")] public class ContactsController : ApiController { [GET("Contacts/{id}",RouteName="GetContactsById")] public ContactDTO Get(int id) { return new ContactDTO{ ID =1, Name="test"}; } } }

TestClass (MSTest): [TestClass] public class ContactsTest { private string _url = "http://myhost/api/"; private static HttpConfiguration config = null; private static HttpServer server = null; private HttpRequestMessage createRequest(string url, string mthv, HttpMethod method) { var request = new HttpRequestMessage(); request.RequestUri = new Uri(_url + url); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(mthv)); request.Method = method; return request; } private HttpRequestMessage createRequest(string url, string mthv, HttpMethod method, T content, MediaTypeFormatter formatter) where T : class { HttpRequestMessage request = createRequest(url, mthv, method); request.Content = new ObjectContent(content, formatter);

        return request;
    }

    [ClassInitializeAttribute]
    public static void ClassInitialize(TestContext ctx)
    {
        config = new HttpConfiguration();
        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
        config.Services.Replace(
            typeof(IDocumentationProvider), new DocProvider());

        config.Services.Replace(
            typeof(IApiExplorer),
            new VersionedApiExplorer(config));

        config.Services.Replace(
            typeof(IHttpControllerSelector),
            new VersionHeaderVersionedControllerSelector
                (config)
                );
        AttributeRoutingHttpConfig.RegisterRoutes(config.Routes);
        WebApiConfig.Register(config);
        server = new HttpServer(config);
    }

    public static void ClassCleanup()
    {
        config.Dispose();
        server.Dispose();
    }

    [TestMethod]
    public void RetrieveContact()
    {
        var request = createRequest("Contacts/12","application/json",HttpMethod.Get);
        var client = new HttpClient(server);

        using (HttpResponseMessage response = client.SendAsync(request).Result)
        {
            Assert.IsNotNull(response.Content);
        }
    }
}

The error occurs on the line "client.SendAsync". I inspected config.Routes and the datatype for the "Constraints" for ''inboundHttpMethod' ' is AttributeRouting.Web.Http.WebHost.Constraints.InboundHttpMethodConstraint It appears that a string value is expected. Any help would be much appreciated.

mccalltd commented 11 years ago

What version of Web API are you using? And what is the source (ie: file) for that error message?

abpatel commented 11 years ago

I was using 3.4.1 and then upgraded to the latest version(3.5.6) from nuget but no change in behavior

mccalltd commented 11 years ago

Sure, but what version of Web API from Microsoft? And again, what was the object that threw the error? I can't jump in and recreate right now, but if I can get more info I might be able to help quickly, or at least let you know what might be going on.

abpatel commented 11 years ago

Thanks Tim WebAPI Version:4.0.20710.0 Not sure if this is relevant or not but I noticed that I have 2 packages in packages.config <package id="AspNetWebApi" version="4.0.20710.0" targetFramework="net45" /> AND <package id="Microsoft.AspNet.WebApi" version="4.0.20710.0" targetFramework="net45" />

The error originated from "AttributeRouting.Web.Http.Framework.HttpAttributeRoute.GetRouteData" method. I've attached the stack trace. System.InvalidOperationException occurred HResult=-2146233079 Message=The constraint entry 'inboundHttpMethod' on the route with route template 'api/Contacts/{id}' must have a string value or be of a type which implements 'IHttpRouteConstraint'. Source=System.Web.Http StackTrace: at System.Web.Http.Routing.HttpRoute.ProcessConstraint(HttpRequestMessage request, Object constraint, String parameterName, HttpRouteValueDictionary values, HttpRouteDirection routeDirection) at System.Web.Http.Routing.HttpRoute.ProcessConstraints(HttpRequestMessage request, HttpRouteValueDictionary values, HttpRouteDirection routeDirection) at System.Web.Http.Routing.HttpRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request) at AttributeRouting.Web.Http.Framework.HttpAttributeRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request) at System.Web.Http.HttpRouteCollection.GetRouteData(HttpRequestMessage request) at System.Web.Http.Dispatcher.HttpRoutingDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.DelegatingHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Web.Http.HttpServer.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpMessageInvoker.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationToken cancellationToken) at System.Net.Http.HttpClient.SendAsync(HttpRequestMessage request) at ASPNETMVC4WEBAPI.Tests.Controllers.ContactsTest.RetrieveContact() in c:\Dev\ASPNETMVC4WEBAPI\ASPNETMVC4WEBAPI.Tests\Controllers\UnitTest1.cs:line 77 InnerException:

paulfryer commented 10 years ago

I'm getting the same error. Was this one ever resolved?

Details of error:

Message: "An error has occurred.", ExceptionMessage: "The constraint entry 'inboundHttpMethod' on the route with route template 'api/accounts' must have a string value or be of a type which implements 'IHttpRouteConstraint'.", ExceptionType: "System.InvalidOperationException", StackTrace: " at System.Web.Http.Routing.HttpRoute.ProcessConstraint(HttpRequestMessage request, Object constraint, String parameterName, HttpRouteValueDictionary values, HttpRouteDirection routeDirection) at System.Web.Http.Routing.HttpRoute.ProcessConstraints(HttpRequestMessage request, HttpRouteValueDictionary values, HttpRouteDirection routeDirection) at System.Web.Http.Routing.HttpRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request) at AttributeRouting.Web.Http.Framework.HttpAttributeRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request) at System.Web.Http.WebHost.Routing.HttpWebRoute.GetRouteData(HttpContextBase httpContext)"

mdmoura commented 10 years ago

Attribute Routing project has been stopped for quite a while since MSFT included Attribute Routing in MVC5 ... Can i suggest using the Attribute Routing of MVC with the new project Route Localization (https://github.com/Dresel/RouteLocalization) for localization?