AttributeRouting icon indicating copy to clipboard operation
AttributeRouting copied to clipboard

AttributeRouting not working with HttpConfiguration object for writing Integration tests

Open abpatel opened this issue 10 years ago • 6 comments

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<T>(string url, string mthv, HttpMethod method, T content, MediaTypeFormatter formatter) where T : class { HttpRequestMessage request = createRequest(url, mthv, method); request.Content = new ObjectContent<T>(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.

abpatel avatar Sep 13 '13 04:09 abpatel

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

mccalltd avatar Sep 13 '13 04:09 mccalltd

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

abpatel avatar Sep 13 '13 04:09 abpatel

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.

mccalltd avatar Sep 13 '13 04:09 mccalltd

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:

abpatel avatar Sep 13 '13 05:09 abpatel

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)"

paulfryer avatar Oct 28 '14 23:10 paulfryer

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?

mdmoura avatar Oct 28 '14 23:10 mdmoura