First off I have read as many articles as I can find on this topic and installed several "route debug" plugins. I am more familiar with Java/Spring so I really have no idea how to debug this thing, using vs 2012. (I cannot anyway to make IISExpress print any debug much less the kind of the debug output I am used to with Spring/Tomcat.)
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Legal",
action = "Index",
id = UrlParameter.Optional }
);
}
}
Now, I am able to hit the Index page via the default controller. However, I am trying to hit the URL /WebApi/Metadata/ based on the following controller:
[BreezeController]
public class WebApiController : ApiController {
private readonly EFContextProvider<BankruptcyDbContext> _contextProvider =
new EFContextProvider<BankruptcyDbContext>();
[HttpGet]
public string Metadata() {
return _contextProvider.Metadata();
}
}
The "Route Debugger" says that my requests for /WebApi/Metadata, /WebApi/Metadata/, /WebApi/Metadata/0, and more should "match" but all I get is 404.
Edit1: I finally found the trace logs and got a little more detail:
The controller for path '/WebApi/Metadata' was not found or does not implement IController
Be sure you are using the current latest version of Visual Studio 2012 with Update 2 etc..
You should not only have a RouteConfig.cs file in App_Start, but also there is a WebApiConfig.cs file
So While Normal MVC routes use the RouteConfig class
public class RouteConfig
{
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 }
);
}
}
The Web API is using the WebApiConfig , which is stubbed out with the out of the box code suggested above in the static class WebApiConfig:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
You would need to register routes using the MapHttpRoute extension for ApiController based routes. Example:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
BTW, what is BreezeController and why is it decorated on WebApiController?
Related
Did a lot of reading around this but no existing fixes work for me.
I am trying to hit an api endpoint from a apiClient project but I keep getting the error message: No action was found on the controller 'UserApi' that matches the request.
I'm able to debug into the api controller but it just won't hit the method.
Client:
public async Task<bool> UserExists(UserDto dto)
{
var postUrl = $"{BaseUri}UserApi/user-exists";
var json = await PostAsync(new Uri(postUrl), dto);
return JsonConvert.DeserializeObject<bool>(json);
}
Api controller:
[Route("api/UserApi")]
public class UserApiController : ApiController
{
public UserApiController()
{
}
[HttpPost]
[Route("user-exists")]
public async Task<bool> UserExists([FromBody]UserDto dto)
{
return true;
}
Route config:
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 }
);
routes.MapHttpRoute(
name: "ApiAction",
routeTemplate: "api/{controller}/{action}/{dto}",
defaults: new { dto = UrlParameter.Optional }
);
}
The bottom routing configuration is the one I'm trying to use. Any help is appreciated
the first comment on the original post solved half my issue - I was trying to configure routing two different ways. I removed all my code from RegisterRoutes and used
config.MapHttpAttributeRoutes();
in WebApiConfig.
I also needed to use the RoutePrefix attribute on the api controller instead of just Route - which is to be used on the controller methods. working now
1.In Global.asax.cs just comment
//RouteConfig.RegisterRoutes(RouteTable.Routes);
As you are using web api no need of this route configuration
2.In WebApiConfig.cs use below line only
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
[RoutePrefix("subscriptions")]
public class SubscriptionsController : ApiController
{
private SubscriptionsService _subscriptionsService;
public SubscriptionsController()
{
_subscriptionsService = new SubscriptionsService();
}
[Route("{email}")]
[HttpGet]
public IHttpActionResult Get(string email)
{
but when I try
http://localhost:51561/api/subscriptions/myEmail
No HTTP resource was found that matches the request URI
'http://localhost:51561/api/subscriptions/myEmail'.
any idea why?
I also set everything in WebApiCOnfig
public static class WebApiConfig
{
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 }
);
}
}
You have tried a wrong URL.
Correct URL should be,
http://localhost:51561/subscriptions/myEmail
OR
If you need API prefix, then you need to change the route prefix of the controller as below,
[RoutePrefix("API/subscriptions")]
then this URL will work,
http://localhost:51561/api/subscriptions/myEmail
Note that , here you are using two routing, default routing and attribute routing. if you need to continue with attribute routing , you can comment out the default routing.
//config.Routes.MapHttpRoute(
// name: "DefaultApi",
// routeTemplate: "api/{controller}/{id}",
// defaults: new { id = RouteParameter.Optional }
I Suppose you are creating some webApi service ? Did you register this route in global.asax.cs ? Something like this :
httpConfiguration.Routes.MapHttpRoute(
name: "MyWebApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { controller = "ControllerName", action = "ActionName", id = RouteParameter.Optional },
constraints: null
);
I have a Controller that have 2 method with same parameters But if I call it I got an error
Several actions that matched the request were found:
I think that I must change Map routing to accomplish that but I dont know how to do it
My methods :
public IHttpActionResult RecuperarMenu(short idInstalacion,string secretKey)
public IHttpActionResult RecuperarClasesColectivas(short idInstalacion, string secretKey)
My route map
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,
namespaces = new[] { "WebServicesRestAPI.Controllers" }
}
);
//routes.MapRoute(
// name: "Default",
// url: "{controller}/{action}/{id}",
// defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
//);
}
I guess the controller that contains your methods is a WebAPI controller (it is derived from the ApiController class). Correct?
Thus, being a WebAPI controller:
It is configured not by means of the MapRoute method, but by means of the HttpConfiguration.Routes.MapHttpRoute method (by default it is configured in the ~/App_Start/WebApiConfig.cs file):
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
The names within the controller should follow the GET/POST/PUT/DELETE pattern (or should be explicitly mapped by you).
If your methods correspond to the GET operation, they should differ by arguments (you have the same arguments if your methods).
I have these two routes defined:
routes.MapRoute(
name: "GetVoucherTypesForPartner",
url: "api/Partner/{partnerId}/VoucherType",
defaults: new { controller = "Partner", action = "GetVoucherTypesForPartner"}
);
routes.MapRoute(
name: "Default",
url: "api/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional}
);
In my PartnerProfile controller, I have 2 methods:
public Partner Get(string id)
{ }
public IEnumerable<string> GetVoucherTypesForPartner(string id)
{ }
If I hit the url ~/api/Partner/1234 then, as expected, the Get method is called.
However, if I hit the url ~/api/Partner/1234/VoucherType then the same Get method is called. I am expecting my GetVoucherTypesForPartner to be called instead.
I'm pretty sure something in my route setup is wrong...
You seem to have mapped standard MVC routes, not Web API routes. There's a big difference. The standard routes are used by controllers deriving from the Controller class, but if you are using the ASP.NET Web API and your controllers are deriving from the ApiController type then you should define HTTP routes.
You should do that in your ~/App_Start/WebApiConfig.cs and not inside your ~/App_Start/RouteConfig.cs.
So go ahead:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "GetVoucherTypesForPartner",
routeTemplate: "api/Partner/{partnerId}/VoucherType",
defaults: new { controller = "Partner", action = "GetVoucherTypesForPartner" }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
and then:
public class PartnerController : ApiController
{
public Partner Get(string id)
{
...
}
public IEnumerable<string> GetVoucherTypesForPartner(string partnerId)
{
...
}
}
Things to notice:
We have defined HTTP routes not standard MVC routes
The parameter that the GetVoucherTypesForPartner action takes must be called partnerId instead of id in order to respect your route definition and avoid any confusions
I've created a new WebAPI MVC project, the API controllers have the path http://localhost:1234/api and they work from this route, but the RegisterRoutes class doesn't contain a default routing, it contains the following:
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 }
);
}
Where's the routing for the API?
Cheers
Dave
The Visual Studio project templates creates a default route which looks like:
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
You can find this in the WebApiConfig.cs file, which is placed in the App_Start directory
http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api
It lives in a different class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace HelloWorldApi
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type.
// To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
// For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
//config.EnableQuerySupport();
// To disable tracing in your application, please comment out or remove the following line of code
// For more information, refer to: http://www.asp.net/web-api
config.EnableSystemDiagnosticsTracing();
}
}
}