A route named 'MS_attributerouteWebApi' is already in the route collection - c#

I recently added Microsoft.AspNet.WebApi.WebHost to a MVC WebAPI project which would allow me to use the [Route("api/some-action")] attribute on my action. I solved some errors using this article but can't solve the third error below. Added solved errors below to get feedback if I did anything wrong.
First Error: No action was found on the controller 'X' that matches the name 'some-action'
Solution: Added config.MapHttpAttributeRoutes(); to WebApiConfig.cs Register method.
Second Error: System.InvalidOperationException The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.
Solution: Added GlobalConfiguration.Configure(WebApiConfig.Register); to Global.asax.cs Application_Start
Third Error: System.ArgumentException: A route named 'MS_attributerouteWebApi' is already in the route collection. Route names must be unique.
Solution = ?
I've already tried cleaning and deleting all DLLs from bin folder according to this post.

I had a similar problem and it was related to a copy paste error on my part where I added a copy of this line in my WebApiConfig.cs file:
config.MapHttpAttributeRoutes();
make sure you only have one of these.

In the Global.asax, check how many times WebApiConfig.Register function has been called.

Solved! Removed the line WebApiConfig.Register(GlobalConfiguration.Configuration); from Global.asax.cs Application_Start.

I have solved by cleaning the deployment directory before copy the new files. Probably there was some old file that try to register the same root multiple times.

I had the same issue and I discovered that in WebApiConfig.cs
and after I added configuration for API version
I have those two lines
config.MapHttpAttributeRoutes(constraintResolver);
config.MapHttpAttributeRoutes();
I removed the second line
the final code is
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
var constraintResolver = new DefaultInlineConstraintResolver()
{
ConstraintMap =
{
["apiVersion"] = typeof( ApiVersionRouteConstraint )
}
};
config.MapHttpAttributeRoutes(constraintResolver);
config.AddApiVersioning();
// Web API configuration and services
// Web API routes
// config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}

For anybody stumbling across this as I did, this error will happen if you rename the Assembly name (project properties). In my case I was renaming a project, and went into the properties to change the assembly name (which VS2013 won't do for you).
Because the assembly name is different, a Clean or Rebuild will not remove the "old" assembly if it is in the \bin folder. You have to delete the assembly from the \bin folder, then rebuild & run.

Probably you have same register more than one.
Try to delete below codes from Global.asax:
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
and write this ones instead of them :
GlobalConfiguration.Configuration.EnsureInitialized();
BundleConfig.RegisterBundles(BundleTable.Bundles);
I am not sure about reason; but it worked for me in my same case.

I was also experiencing a similar problem (not the MS_attributerouteWebApi route in particular, but a different named route). After verifying only one config.MapHttpAttributeRoutes() existed, began realizing that MapHttpAttributeRoutes will register all project assemblies including externally referenced ones. After finding out that I had a referenced assembly that was registering its own routes, I found a way to exclude or "skip over" routes by overriding the DefaultDirectRouteProvider:
/// <summary>
/// Allows for exclusion from attribute routing of controllers based on name
/// </summary>
public class ExcludeByControllerNameRouteProvider : DefaultDirectRouteProvider {
private string _exclude;
/// <summary>
/// Pass in the string value that you want to exclude, matches on "ControllerType.FullName" and "ControllerType.BaseType.FullName"
/// </summary>
/// <param name="exclude"></param>
public ExcludeByControllerNameRouteProvider(string exclude) {
_exclude = exclude;
}
protected override IReadOnlyList<RouteEntry> GetActionDirectRoutes(
HttpActionDescriptor actionDescriptor,
IReadOnlyList<IDirectRouteFactory> factories,
IInlineConstraintResolver constraintResolver)
{
var actionRoutes = new List<RouteEntry>();
var currentController = actionDescriptor.ControllerDescriptor.ControllerType;
if (!currentController.FullName.Contains(_exclude) && !currentController.BaseType.FullName.Contains(_exclude))
{
var result = base.GetActionDirectRoutes(actionDescriptor, factories, constraintResolver);
actionRoutes = new List<RouteEntry>(result);
}
return actionRoutes.AsReadOnly();
}
}
This allows for you to pass a Controller name or Base Type name in to exclude in your WebApiConfig.cs like:
config.MapHttpAttributeRoutes(new ExcludeByControllerNameRouteProvider("Controller.Name"));
Whether or not directly related, hoping this snippet can help!

I was experiencing the same problem. The solution I found was that I needed visual basic support for mono. When I executed "yum install mono-basic" and restarted my computer the error went away.

In my case error was : "A route named 'MS_attributerouteWebApi' is already in the route collection. Route names must be unique.
Parameter name: name"
Code was:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.MapHttpAttributeRoutes(); // this line had issue
var constraintResolver = new DefaultInlineConstraintResolver();
constraintResolver.ConstraintMap.Add("nonzero", typeof(NonZeroConstraint));
config.MapHttpAttributeRoutes(constraintResolver);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Solution :
I just removed - config.MapHttpAttributeRoutes();
line from above method and it got resolved.

Related

Web Api 2 Routing Issue: "No action was found on the controller..."

I am having the issue of getting a 404 on my web api routing. Although there are many posts about this issue, they mainly seem to be about changing the order of the routes so that the MVC routes don't override the api routes.
I have tried all of the solution I have come across yet nothing seems to fix my issue.
Here is my controller:
[RoutePrefix("api/paving-designer")]
public class PavingDesignerController : ApiController
{
[HttpGet]
[Route("get-forms/{userId}")]
public IHttpActionResult GetForms(Guid userId)
{
ICollection<PavingDesignerFlatForm> forms = _helper.GetForms(userId);
if (forms != null)
{
return Ok(forms);
}
else
{
return NotFound();
}
}
}
And this is my Web Api Config
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new
{
id = RouteParameter.Optional
});
}
}
and this is my global asax
private void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
// RouteConfig.RegisterRoutes(RouteTable.Routes);
// Initialize Castle & install application components
_bootstrapper = CastleInitialiser.Initialise();
}
As you can see I have even tried to comment out the mvc routes to see if that made a difference
If I browse to http://localhost/api/paving-designer/get-forms/c6c489a7-46c6-420e-9e39-56797c8094cf
I get the following error:
No type was found that matches the controller named 'paving-designer'.
I have tried changing the route prefix to the following but to no avail
/api/paving-designer
/paving-designer
paving-designer
And if I browse to http://localhost/api/pavingdesigner/get-forms/c6c489a7-46c6-420e-9e39-56797c8094cf
I get the following error:
Multiple types were found that match the controller named 'pavingdesigner'. This can happen if the route that services this request ('api/{controller}/{action}/{id}') found multiple controllers defined with the same name but differing namespaces
I don't see how I can have multiple controllers as this is the only one I have.
Can anyone see where I am going wrong?
You are using both routing types.
Using attribute routing defined next route:
/api/paving-designer/get-forms/{userId}
Using default routing there is other route:
/api/{controller}/{action}/{id}
These routes are have the same template.
But using the first of them - ControllerSelector can not find paving-designerController.
Using the second - there is no action named get-forms. There are GetForms
If you remove one of them - it should work.
Ok in my particular case, the error was being caused as my IoC was registering the controller twice.
This was causing the duplicate entries, which in turn made the attribute routing fail.

Owin/Katana System.EntryPointNotFoundException Assembly located elsewhere

Somehow I can't find someone having the same problem.
We have a plugin based project, on the main folder we have the Plugin Starter, the Bootstrapper, and some dependencies.
The plugins are in the "Plugins" folder and within, are some other folders.
My Startup.cs file is as following:
public class Startup
{
public void Configuration(IAppBuilder appBuilder)
{
appBuilder.Use(async (env, next) =>
{
new object().Info(string.Concat("Http method: ", env.Request.Method, ", path: ", env.Request.Path));
await next();
new object().Info(string.Concat("Response code: ", env.Response.StatusCode));
});
RunWebApiConfiguration(appBuilder);
}
private static void RunWebApiConfiguration(IAppBuilder appBuilder)
{
var httpConfiguration = new HttpConfiguration();
httpConfiguration.Routes.MapHttpRoute(
name: "WebApi"
, routeTemplate: "{controller}/{id}"
, defaults: new { id = RouteParameter.Optional }
);
appBuilder.UseWebApi(httpConfiguration);
}
}
The call is made as following:
WebApp.Start<Startup>("http://localhost/MyRestApi");
if I load the Assembly on the same folder, no problem, but if I load it where it "belongs", I can't get Owin to find it.
Anyone had ever ran into this or have any idea? I might think of something like a configuration line in the App.config, but I don't find this as a solution.
UPDATE 1:
I get the System working again when I copy the Rest Service assembly on the main directory but then it is loaded two times, which is a big problem.
When I send a Rest request, I get the following message:
{"Message":"An error has occurred.","ExceptionMessage":"Multiple types were found that match the controller named 'ExternalOrder'. This can happen if the route that services this request ('{controller}/{id}') found multiple controllers defined with the same name but differing namespaces, which is not supported.\r\n\r\nThe request for 'ExternalOrder' has found the following matching controllers:\r\nInternalOrderValidationPlugin.Controllers.ExternalOrderController\r\nInternalOrderValidationPlugin.Controllers.ExternalOrderController","ExceptionType":"System.InvalidOperationException","StackTrace":" at System.Web.Http.Dispatcher.DefaultHttpControllerSelector.SelectController(HttpRequestMessage request)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"}
Ok, after wandering around on the internet, I found a solution, and namely Dependency Injection.
Here in this post "How to use DI container when OwinStartup" you can find a lot of possibilities, but the one that I implemented and solved my problem, was this blog post:
https://damienbod.wordpress.com/2013/10/01/self-host-webapi-with-owin-and-unity/
I hope this can help anyone else.

WebApi 2 Route Attribute not working unless using parameter

I have a controller List
[Route("api/cache/list")]
[HttpGet]
public IEnumerable<string> List()
{
...
}
But i get a 404 if i try to go to localhost:12121/api/cache/list. My webapi config looks like this:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
//config.SuppressDefaultHostAuthentication();
//config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Formatters.Remove(config.Formatters.XmlFormatter);
//config.Routes.MapHttpRoute(
// name: "DefaultApi",
// routeTemplate: "api/{controller}/{id}",
// defaults: new { id = RouteParameter.Optional }
//);
}
}
On the other hand if i change that controller to
[Route("api/cache/list/{id}")]
[HttpGet]
public IEnumerable<string> List(int id =0)
{
...
}
It will work. Ive tried doing it without the id as a parameter, still doenst work. What am I doing wrong here?
Extra Info:
I do have a strange setup. My WebApiConfig.cs and global.cs are in a different project. The project which has my controller will then reference the project with the WebApiConfig.cs
Rather than giving the param a default value, try making your id param nullable:
public IEnumerable<string> List(int? id)
Then check for null in code. This also helps differentiate a passed zero from an omitted param value.
I wasnt able to figure out how to fix the problem exactly but I did find a way around my problem.
First I correctly identified that when my routing was in a single assembly the exact same code worked fine. When the routing for my project in a different assembly makes it difficult for config.MapHttpAttributeRoutes(); to correctly identify attribute routes.
On the other hand using a RoutePrefix seemed to fix my issue.
Im not going to set this as my answer because I feel it doesn't truly address the problem, but I felt it would be informational to anyone who comes along this question.

Web Api Controller in other project, route attribute not working

I have a solution with two projects. One Web Api bootstap project and the other is a class library.
The class library contains a ApiController with attribute routing.
I add a reference from web api project to the class library and expect this to just work.
The routing in the web api is configured:
config.MapHttpAttributeRoutes();
The controller is simple and looks like:
public class AlertApiController:ApiController
{
[Route("alert")]
[HttpGet]
public HttpResponseMessage GetAlert()
{
return Request.CreateResponse<string>(HttpStatusCode.OK, "alert");
}
}
But I get a 404 when going to the url "/alert".
What am I missing here? Why can't I use this controller? The assembly is definitely loaded so I don't think http://www.strathweb.com/2012/06/using-controllers-from-an-external-assembly-in-asp-net-web-api/ is the answer here.
Any ideas?
Try this. Create a class in your class library project that looks like this,
public static class MyApiConfig {
public static void Register(HttpConfiguration config) {
config.MapHttpAttributeRoutes();
}
}
And wherever you are currently calling the config.MapHttpAttributeRoutes(), instead call MyApiConfig.Register(config).
One possibility is you have 2 routes on different controllers with the same name.
I had 2 controllers both named "UploadController", each in a different namespace and each decorated with a different [RoutePrefix()]. When I tried to access either route I got a 404.
It started working when I changed the name of one of the controllers. It seems the Route Attribute is only keyed on the class name and ignores the namespace.
We were trying to solve a similar problem.
The routes within the external assembly were not registering correctly.
We found one additional detail when trying the solution shown on this page.
The call to the external assembly "MyApiConfig.Register" needed to come before the call to MapHttpRoute
HttpConfiguration config = new HttpConfiguration();
MyExternalNamespace.MyApiConfig.Register(config); //This needs to be before the call to "config.Routes.MapHttpRoute(..."
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);

ASP.NET MVC WebAPI 404 error

I have an asp.net web forms application running under v4.0 integrated mode.
I tried to add an apicontroller in the App_Code folder.
In the Global.asax, I added the following code
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
When I tried to navigate to the controller at http://localhost/api/Value, I get the 404 error.
The extensionless url is configured in the handler section. I have forms and anonymous authentication enabled for the website.
ExtensionLess url is configured for '*.'
When I hit the url for controller, the request is handled by StaticHandler instead of ExtensionlessUrlHandler-Integrated-4.0.
I have no clue now why the system will throw the error as shown in the image below.
I was experiencing this problem.
I tried editing my WebApiConfig.cs to meet a number of recommendations here and code samples elsewhere. Some worked, but it didn't explain to why the route was not working when WebApiConfig.cs was coded exactly as per the MS template WebApi project.
My actual problem was that in manually adding WebApi to my project, I had not followed the stock order of configuration calls from Global.asax
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
// This is where it "should" be
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
// The WebApi routes cannot be initialized here.
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
I could make guesses about why this is, but I didn't investigate further. It wasn't intuitive to say the least.
The problem is in your routing configuration. Mvc routing is different from WebApi routing.
Add reference to System.Web.Http.dll, System.Web.Http.Webhost.dll and System.Net.Http.dll and then configure your API routing as follows:
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
Ensure the following things
1.) Ensure that your IIS is configured with .NET 4.5 or 4.0 if your web api is 4.5 install 4.5 in IIS
run this command in command prompt with administrator privilege
C:\Windows\Microsoft.NET\Framework\v4.0.30319>aspnet_regiis.exe -i
2.) Change your routing to
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
and make request with Demo/Get (where demo is your controller name)
if the 1,2 are not working try 3
3.) Add following configuration in web.config file
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
Also, make sure your controller ends in the name "Controller" as in "PizzaPieController".
I tried all of the above and had the same problem. It turned out that the App pool created in IIS defaulted to .net 2.0. When I changed it to 4.0 then it worked again
Thanks Shannon, works great =>
My order in my Global.asax was :
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
instead of the good one :
RouteConfig.RegisterRoutes(RouteTable.Routes);
GlobalConfiguration.Configure(WebApiConfig.Register);
Also try to delete your entire api bin folder's content. Mine was containing old dlls (due to a big namespace renaming) exposing conflicting controllers. Those dll weren't deleted by Visual Studio's Clean functionality.
(However, I find asp.net web api seriously lacks routing and debugging information at the debugging level).
If you create the controller in App_Code how does the routing table know where it is? You have specified the route as "api/{controller/..." but that's not where the controller is located. Try moving it into the correct folder.
After hours of spending time on this , i found the solution to this in my case.
It was the order of registering the Routes in RouteConfig .
We should be registering the HttpRoute in the Route table before the Default controller route . It should be as follows. Route Config Route table configuration
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Thanks to Shannon, ceinpap, and Shri Guru, the following modification works for me:
WebApiConfig.cs:
public static void Register(HttpConfiguration config)
{
...
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Global.asax.cs:
protected void Application_Start()
{
...
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
...
}
For the URL you've trying (http://localhost/api/Value) make sure there's a public type named ValueController which derives from ApiController and has a public method with some of these characteristics:
Method name starts with Get (e.g. GetValues or simply Get).
There's an HttpGet attribute applied to the method.
In case you're trying the code from the default Web API project template, the name of the controller is ValuesController, not ValueController so the URL will be http://localhost/api/values.
If non of the above helps, you may want to enable tracing which can give you a useful insight on where in the pipeline the error occurs (as well as why).
Hope this helps.
None of solutions above solved my problem... My error was that I copied the bin files directly to production server, and then, I don't work. The 404 was gone when I publish the project to disk and copied the "published" folder to server. It's a little obvious, but, can help some one.
I copied a RouteAttribute based controller dll into the bin folder, but it wasn't getting recognized as a valid controller and I was getting the 404 error on the client.
After much debugging, I found my problem. It was because the version of System.Web.Http.dll that the controller was referencing was different from the version of System.Web.Http.dll that the main project (the one containing global.asax.cs) was referencing.
Asp.Net finds the controller by reflection using code like this
internal static bool IsControllerType(Type t)
{
return
t != null &&
t.IsClass &&
t.IsVisible &&
!t.IsAbstract &&
typeof(IHttpController).IsAssignableFrom(t) &&
HasValidControllerName(t);
}
Since IHttpController is different for each version of System.Web.Http.dll, the controller and the main project have to have the same reference.
We had this as well, changing .NET version from 4.5 to 4.5.1 or newer solved the issue
The sequence of registering the route, was the issue in my Application_Start().
the sequence which worked for me was
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
earlier it was
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
GlobalConfiguration.Configure(WebApiConfig.Register);
Try just using the Value part of the controller name, like this:
http://localhost/api/Value
Note: By convention, the routing engine will take a value passed as a controller name and append the word Controller to it. By putting ValueController in the URI, you were having the routing engine look for a class named ValueControllerController, which it did not find.
Your route configuration looks good. Double check the handlers section in web.config, for integrated mode this is the proper way to use ExtensionLessUrlHandler:
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
More on this topic:
http://blogs.msdn.com/b/tmarq/archive/2010/05/26/how-extensionless-urls-are-handled-by-asp-net-v4.aspx
Time for me to add my silly oversight to the list here: I mistyped my webapi default route path.
Original:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/id",
defaults: new { id = RouteParameter.Optional}
);
Fixed: (observe the curly braces around "id")
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional}
);
I appreciate this is a very old question but I thought I would add another answer for future users.
I found this to happen just now in a project I was working on only after it was deployed to CI/Staging. The solution was to toggle the compilation debug="true" value back and forth while deploying each version to each environment once, and it would fix itself for me.
In my case I forgot to make it derive from ApiController.
So it would look like
public class ValuesController : ApiController

Categories

Resources