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

This question may seems duplicate but this is slightly different.
In all other question in SO I had noticed that they have multiple routes registered. but in my case I have just one route.
I am creating asp.net webapi (framework 4.5) and have just one route in RegisterRoutes() method -
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "DefaultApi",
url: "rest/{controller}/{id}",
defaults: new { id = UrlParameter.Optional }
);
}
Then why is it throwing error?
A route named 'DefaultApi' is already in the route collection. Route names must be unique. Parameter name: name

I had a similar issue with adding a route DefaultApi. Though the exact 'additional details' message in my ArgumentException stack trace was:
A route named 'MS_attributerouteWebApi' is already in the route collection.
Route names must be unique.
I ofcourse made sure I was adding the DefaultApi route only once, but in the end noticed that in Global.asax's Application_Start method I was calling the WebApiConfig.Register(..) twice, though in the following - not immediately obvious - way:
WebApiConfig.Register(GlobalConfiguration.Configuration);
GlobalConfiguration.Configure(WebApiConfig.Register);
Another serious case of 'copypasterites'! I simply removed the WebApiConfig.Register(..) line and that fixed my issue.
(I am using WEB API 2.0/.NET 5)

CAUSE: renaming namespaces without removing associated bin and output files.
SOLUTION: manually delete the bin and obj folders from the output directory. (cleaning the solution is not enough, some problematic residual files remain causing this problem.)
... that was my experience anyway.

Fine, I resolved it based on the reply by user3038092. Instead of adding it in the route collection, I added it in HttpConfiguration
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "rest/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
And it worked.

If you are using MVC4 or MVC5 application.
Then put your Route Configuration in
WebApiConfig.cs and
also check route name should be unique in both files i.e RouteConfig.cs and WebApiConfig.cs

I see that you call the controller but you do not give the controller name like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "DefaultApi",
url: "rest/{controller}/{id}",
defaults: new { controller="Home",action="Index",id = UrlParameter.Optional }
);
}
that means you regist HomeContrller for the Index view,

Related

Default controller giving me a "No HTTP resource was found that matches the request URI" -"No type was found that matches the controller named 'tab'

I'm trying to access an app on my localhost connected to IIS with the following endpoint I'm trying to hit https://api.url.com/api/tab. I have a TabController.cs in my Controllers folder. I also have a Views/Tab/Index.cshtml file and am wondering why I'm getting the following two errors:
<Error>
<Message>No HTTP resource was found that matches the request URI 'https://api.url.com/api/tab'.</Message>
<MessageDetail>No type was found that matches the controller named 'tab'.</MessageDetail>
</Error>
I have the same folder structure for a controller named Footer, and I'm able to access https://api.url.com/api/footer successfully. I've included my WebApiConfig.cs and RouteConfig.cs code below:
WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
RouteConfig.cs
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
I've a feeling it's something quite obvious I'm missing as I'm a bit new to .NET and the MVC structure. So any point in the right direction would be greatly appreciated.
You trying to access the MVC Controller (inherited from the System.Web.Mvc.Controller) as if it's the Web API Controller (inherited from the System.Web.Http.ApiController). As you know API controllers have their own routing configuration, which is completely separate from the rest of
the application. Therefore, to access an action method from the regular MVC controller don't use api prefix in the URL. Just enter https://api.url.com/tab to call the default action method in the tab controller.

MVC & WebAPI "Multiple types were found that match the controller named..."

I have a routing problem with MVC and WebAPI controllers.
The error is:
Multiple types were found that match the controller named 'Log'. 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, which is not supported.
The request for 'Log' has found the following matching controllers:
MyNamespace.Controllers.LogController
MyNamespace.Controllers.WebAPI.LogController
My routing is simple:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
I have tried adding an additional route for WebAPI like:
routes.MapHttpRoute(
name: "API",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Along with adding a namespace for the MVC route:
namespaces: new[] { "MyNamespace.Controllers" }
But I still receive the same error. I cannot see a way to specify the namespace for the WebAPI route.
There is a well-upvoted duplicate but that is specifically about MVC controllers. The answers talk about adding a namespace as above, which has not helped here. In my case the routing to the MVC controller works fine, and it is only the WebAPI controller where I have the problem.
The strange thing is, all my other WebAPI controllers have the same name as MVC controllers but this is the only one where I run into the error.
If you changed the name of the project, you must delete the files in the bin folder with the old project name.

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

WebApi doesn't get published?

I currently have two controllers. One is MVC and the other is a WebApi controller.
I've published these two with ease on the IIS server with the following settings:
WebApiConfig:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
RouteConfig:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "MVCControllerName", action = "MVCControllerName", id = UrlParameter.Optional }
);
Now I've added another WebApi controller, but when published, the webserver says:
No HTTP resource was found that matches the request URI
http://example.com/folder/api/Other?id=45&text=bla
Implementation of the OtherController:
public void Get(int id, string text)
{
// something simply gets commited to the DB
}
Also, something weird is happening when publishing... I've deleted the first WebApi controller from the solution, but for some reason when publishing I can STILL call that WebApi through HTTP GET request! Even though it's gone!
OTOH, it works fine in the debug mode..
What's going on here?
EDIT: It seems the problem is not in my code, but in VS' publishing feature. It has always worked until now. I had to manually copy the files to the server, which isn't the point of so-called "one-click publishing". Other similar SO questions seem to indicate it is a VS bug that is still not fixed in SP2.

Routes for specific controllers

In my Web API scenario, this (default) route works well for almost all my controllers.
config.Routes.MapHttpRoute(
name: "DefaultRoute",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
and for a couple of my controllers, I want to have them mapped by their action name, like this:
config.Routes.MapHttpRoute(
name: "ActionRoute",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Background:
Most of my controllers are to be mapped by default to GEE, POST, PUT and DELETE.
However, I reserve some "admin" controllers that perform operations, such as data initialization, cleanup and testing stuff. These controllers may have multiple methods that are excetude via GET, hence the second route.
If I use either of these routes, they work well, however, if I set both, I get one of two failures:
Default route first:
api/books/ -> OK
api/books/someGuidId -> OK
api/admin/someAdminAction -> 500 Internal Server Error (multiple actions found)
api/test/sometestAction -> 500 Internal Server Error (multiple actions found)
Action route first:
api/books/ -> OK
api/books/someGuidId -> 404 Not Found (no action that matches "someGuidId")
api/admin/someAdminAction -> OK
api/test/sometestAction -> OK
My question is: how can I have these routes working out at the same time?
[EDIT]
api/books/someGuidId is not an important call, I can live without it (via GET) however, POST, PUT and DELETE to same url will fail, wich is not acceptable.
The order of the routs matter, so You should set more specific routs first:
config.Routes.MapHttpRoute(
name: "ActionRoute",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultRoute",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Edit:
Default route first:
api/books/
This url matchs the first pattern: api/{controller}/{id}.
Framework looks for books controller with GET (PUT,POST,DELETE) method, and finds it. This method is invoked with default id value.
api/admin/someAdminAction
This url also matchs the first pattern. (BTW, It doesn't matter how You name Your parameters in the route definition: id or superParamName, When Framework compares URL with routs it will look only for patterns and can not distinguish by param names.
The Framework will try to invoke GET (PUT,POST,DELETE) method of admin controller with someAdminAction id (Which, I suppose, is not a valid id value:)
Similar thing You get when You define Action route first:
api/books/
Matchs api/{controller}/{id}, id can be omitted, cause it was set to "optional".
api/books/someGuidId
Matchs api/{controller}/{action}/{id}, so, when Framework looks for someGuidId action method in book controller and it doesn't find it, it throws an exception. 404 Not Found (no action that matches "someGuidId")
Edit 2: I think, in case You will always pass id param for "Actions" and place "Actions" route first, You will not get any collisions. Try this.
If You need id param be optional in both cases, You can just remove it from both routs and pass it in a normal way via ?(question mark).
One of this would fix Your routing problem.

Categories

Resources