asp.net webapi 2 attribute routing not working - asp.net-web-api

I have visual studio 2012 installed with mvc4 using .net framework 4.5. Now I want to use webapi2 with attribute writing and i want my hlep page show all the endpoints properly.
In my solution i added a new mvc4 base emtpy project and using nuget i upgraded to mvc5 and then i have installed webapi2 packages. lastly i have installed help package for webapi2.
now when i use routeprefix I cant see any content on help page and when i try to access my webapi endpoint in browsers it throws following error.
http://expressiis.com/api/v1/
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://expressiis.com/api/v1/'.
</Message>
<MessageDetail>
No type was found that matches the controller named 'v1'.
</MessageDetail>
</Error>
namespace WebApi.Controllers
{
[RoutePrefix("api/v1")]
public class SubscribersController : ApiController
{
// GET api/<controller>
[Route("")]
[HttpGet]
public IQueryable<string> Get()
{
return new string[] { "value1", "value2" }.AsQueryable();
}
}
}

Based on your information, it looks like you are not calling the httpConfig.MapHttpAttributeRoutes() (Make sure to call this before any traditional routing registrations)
Since you haven't called MapHttpAttributeRoutes, your request seems to be matching a traditional route, for example, like api/{controller}. This will not work because routes matching traditional routes will never see controllers/actions decorated with attribute routes.

A problem I ran into was related to the ordering in Application_Start(). Note the order of Web API configuraton below:
This does NOT work
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfiguration.Configure(WebApiConfig.Register);
}
This does work
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}

I had this problem too and after a long search I realized that I was using System.Web.Mvc.RouteAttribute instead of System.Web.Http.RouteAttribute
After correcting this and using config.MapHttpAttributeRoutes() everything worked fine.

This was not your case (as is apparent from your sample code), but please do remember to end the Controller class name with Controller.
Else it won't be picked up by config.MapHttpAttributeRoutes();.

This question already has a selected answer. But I had a different solution for myself and think it would be helpful to reply if the selected answer doesn't help.
For me it was a silly mistake. I had two controllers but only one was working. The solutions was that my controller class was named improperly!
My working controller-
public class FooController : ApiController { }
My non-working controller-
public class BarControllers : ApiController { }
Be sure your controller class ends in Controller. The trailing s got me!

Make sure you don't have two controllers with the same name! I was moving some controllers from one assembly I was throwing away into the website... whilst the website no longer had references to the old assembly other assemblies did which meant it was copied in to the WebSite bin folder. The route discovery process then seemed to fail silently when it came across two occurrences of the same controller!

In my case, VS create my controller with the name
TestController1
I dont know why he put this number "one" in the end of name, but remove and will work.

In my case, I was missing full custom path in attributes. I was writing only custom action name without 'api/'. So that was my mistake. My scenario was,
WebApiConfig template code:
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
my incorrect way of route
[RoutePrefix("myapps")] // wrong code
public class AppsController : BaseRestAPIController
{
[HttpPost]
[Route("getapps")]
public ResponseData GetAppList()
{
Correct way
[RoutePrefix("api/myapps")] // correct way. full path start from 'api/'
public class AppsController : BaseRestAPIController
{
[HttpPost]
[Route("getapps")]
[Route("api/myapps/getapps")] // you can use full path here, if you dont want controller level route
public ResponseData GetAppList()
{

In my case following line was creating problem, just commented it and everything start working
config.MapHttpAttributeRoutes();
Comment it in WebApiConfig.cs file

Related

The route template separator character '/' cannot appear consecutively when adding action to default route

I have a Web API 2 project hosted through an OWIN middleware. Everything worked perfectly fine and I am able to call my APIs as expected. But, my WebApiConfig defines the default route as follows:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Accordingly, I have to call my APIs using URLs similar to: /api/values/dosomething
This worked for me until I decided to document my API. For that, I first tried using the WebAPI Help Page package which did not work. Then I thought I should try Swashbuckle Swagger and see if that helps me avoid the problem altogether, but unfortunately, in both cases I got the same error:
The route template separator character '/' cannot appear
consecutively. It must be separated by either a parameter or a literal
value. Parameter name: routeTemplate
After trying a few things, it turned out that when change the route template and remove the {action} part, the error is gone. But, I cannot really do that because the whole project assumes that URLs include the action method name in them.
So anyway, I would like to know the following:
Why is this happening in the first place?
Is there a way to modify this behavior?
Thanks in advance!
I fetch the same problem. Below is my working code.
[RoutePrefix("api/User")]
public class UserController : ApiController
{
[Route("login")]
public IHttpActionResult Get()
{ }
}
when I change Route before methods from
[Route("login")]
public IHttpActionResult Get()
{ }
to
[Route("/login")]
public IHttpActionResult Get()
{ }
I got same error.
It will generate if you add an extra / before any methods of your controller(if it is not called at first time).
I am not sure about your condition. I share my situation if anyone gets help.

WebAPI not finding my controller in App_Data folder

public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
in global.asax.cs i do:
WebApiConfig.Register(System.Web.Http.GlobalConfiguration.Configuration);
Break point confirms that the route is being registered.
In the App_Data folder i place a folder WebApi and put in a BlogPosts.cs with the following content:
public class BlogPosts : ApiController
{
public string Get()
{
return "Hello World";
}
}
What more do I have to do to get the website to use the WebAPI ?
http://localhost:49396/api/BlogPosts gives me:
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://localhost:49396/api/BlogPosts'.
</Message>
<MessageDetail>
No type was found that matches the controller named 'BlogPosts'.
</MessageDetail>
</Error>
Therefore the WebAPI have been registed correct but it just dont find the ApiController in App_Data folder. I properly am missing something. (Its not a MVC4 project, but a website that i try to add a api to).
App_Data is not normally used for this type of scenario. It could very well be that you BlogPosts.cs file is not set to Compile but something like Content. So, in solution explorer click on BlogPosts.cs, go to properties and change Build Action settings to Compile.
Another problem is that your BlogPosts is missing Controller suffix. Rename your class to BlogPostsController.
It would probably be better if you create a special folder where you would keep your Web API controllers, like ApiControllers.

Cannot view my new MVC 4 application

I just created a new basic MVC 4 application in VS 2010. I just clicked the play button to test it came up in the web browser and I'm getting the following page:
I think I need to change my virtual path to something but I don't know what.
EDIT: Can't see what it says properly in the picture:
Server Error in '/' Application.
--------------------------------------------------------------------------------
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /
If you created an Empty Project you will need to create a HomeController with an Index Action. You will also need to create a View in ~/Views/Home/ called Index.
The other project templates create this for you but the Empty Project does not.
public class HomeController : Controller
{
public ActionResult Index()
{
return View()
}
}
No one person gave me the full answer. So this is an amalgamation of #MattiVirkkunen and #BrettAlfred
Add this within RouteConfig.cs
routes.MapRoute(
name: "Default",
url: "",
defaults: new { controller = "Home", action = "Home" }
);
Add this within HomeController.cs
public ActionResult Login()
{
return View();
}
Kya Neeta MVC me neyi ho Kya?? I am too :)
I think u have created a start-up page in your applicaition.
Type Http: //localhost:8080/Home/Index in your url
http: //localhost:/ControllerName/ActionName
if that does not work please create a new MVC application from scratch.

Delete Action not working MVC 3

Route I have defined is:
map.Route(new Route("Cars/{id}/Delete",
new RouteValueDictionary(new { controller = "Car", action = "Delete"}),
new MvcRouteHandler()));
In my view I've got:
Delete
Which when run tries to send a request to http://oursite/Car/122/Delete
My delete action in this Car controller looks like this:
public ActionResult Delete(int id)
{
//code is here
}
I noticed a couple things:
If I run this same code locally via my PC, the delete works flawlessly and is able to get to my action method. I'm running this over IIS 7 / Win 7
On our dev server, it's setup obviously via IIS7 but this route fails and says it can't find the route on our route table. But this is the SAME route table class I am using locally...so why would I get this:
No route in the route table matches the supplied values.
But why would that not work on a dev server? I see the setup identical in IIS for the most part as far as I can see when I compare my local setup to the server's.
I noticed that also whether localhost or server, if I try and put an [HttpDelete] attribute on my delete action, it doesn't find my action method and I get an error saying it can't find that method. So not sure why when I take that off, the delete works (localhost only)
Use a helper to generate your link:
#Html.ActionLink("Delete", "Delete", "Car");
The first parameter is your link text, the second is your Action method name, and the third is your Controller name.
See this MSDN Reference on ActionLink().
Could you please share code for the View. How do you build the 'a' tag in the view?
Regarding the [HttpDelete] attribute, it means that the method needs the HTTP 'DELETE' request. The 'a' tag always has a GET request.
Please refer this link
I think you answered your own question. There is no route in the route table that matches your supplied values. You could write that route to do that by writing this in your Global.asax.cs file:
public class Global : System.Web.HttpApplication
{
protected void Application_Start()
{
// Specify routes
RouteTable.Routes.Add(new Route
{
Url = "[controller]/[id]/[action]",
Default = new { controller = "Car" },
RouterHandler = typeof(MvcRouteHandler)
});
}
}
Or, you can use existing routes (my personal recommendation) to use the Delete function in your Car controller. To do that, try switching your code to this:
Delete
First name that route
map.Route("DeleteCar",new Route("Cars/{id}/Delete",
new RouteValueDictionary(new { controller = "Car", action = "Delete"}),
new MvcRouteHandler()));
Then
Delete
Unless that link goes to a warning screen, I strongly suggest that a delete should be a POST or even a DELETE(I think it can be set via ajax)
There's likely a difference in the URL paths between localhost and oursite. The path "/Car/#Model.Id/Delete" is hard-coded, not resolved and may not work in all environments. As suggested in other answers, use an MVC helper like #Html.ActionLink or #Url.RouteUrl to resolve the path for the local environment.

MVC3, ASP.NET 4 - The resource cannot be found.

I have VS2010, MVC3 and ASP.NET 4.0 with a simple test mvc application. The problem is that I am still keep getting error:
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /Pizzas/Pizza
Here is my simple controller :
public class PizzasController : Controller
{
public ActionResult Pizza()
{
var pizzas = new Pizza();
return View("Pizza", pizza);
}
}
Here is a part of my global.asax:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{Scripts}/{*pathInfo}");
routes.MapRoute(
"Pizza_1",
"Pizzas/Pizza",
new { controller = "Pizzas", action = "Pizza"}
);
routes.MapRoute(
"Pizzas_2", // Route name
"{controller}/{action}", // URL with parameters
new { controller = "Pizzas", action = "Pizza" } // Parameter defaults
);
}
I am trying to call this action from a pizza.cshtml by this way:
#Html.ActionLink("Test", "Pizza", "Pizzas");
When the both routes are uncomented, then execution goes to Pizza_2 route and it passes without problems. But if I commented out Pizza_2, then it goes to Pizza_1 and the error occurs without getting to the action method.
The application runs on ASP.NET development server (not IIS).
I noticed that it works with Pizza_2 route only when there is no full url specified:
http://localhost:2893
but if type the full url like this:
http://localhost:2893/Pizzas/Pizza
the error again occurs.
Remove
routes.IgnoreRoute("{Scripts}/{*pathInfo}");
According to http://msdn.microsoft.com/en-us/library/cc668201.aspx#url_patterns {Scripts} is parsed as parameter.
If you want to do passthrough for scripts, you should use
routes.IgnoreRoute("Scripts/{*pathInfo}");
I had the same issue but when i was looking at the warning list of the project i found out that i had a reference to the OracleDataAcces.dll. When rebuilding the project that dll was not able to be deleted due to the security problem. Then i right clicked the bin folder it was given only read only access then i deselected that and rebuilt again.
After that the page loaded without any issue. Hope this may resolve it.

Resources