I am working on an asp.net project and suddenly, seemingly out of the blue, the API has stopped working specifically for routes that use the /api/{controller}/{id} route.
Using, for example /api/Events?param1=x¶m2=y works fine. It's just when using the optional parameter {id} that it seems to fall back to the regular web route: /{controller}/{action}/{id}
Here are the relevant configs:
WebApiConfig.cs:
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Formatters.JsonFormatter.SupportedMediaTypes
.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html"));
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 }
);
}
and Global.asax:
protected void Application_Start()
{
Telerik.Reporting.Services.WebApi.ReportsControllerConfiguration.RegisterRoutes(System.Web.Http.GlobalConfiguration.Configuration);
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AutoMapperConfig.RegisterMaps();
}
An example of one of the actions that isn't working:
// GET: api/Events/5
[HttpGet]
public EventReadDTO Get(int id)
{
using (var session = DBSessionFactory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
return session.Query<Event>()
.Where(e => e.Id == id)
.ToList()
.Select(x => Mapper.Map<EventReadDTO>(x))
.FirstOrDefault();
}
}
}
This may be worthwhile for anyone using Telerik Reporting.
It seems that the line placed in Global.asax by the telerik reporting "wizard" causes a route to be registered that interferes with the default route created by ASP.NET MVC API.
The offending line is:
Telerik.Reporting.Services.WebApi.ReportsControllerConfiguration.RegisterRoutes(System.Web.Http.GlobalConfiguration.Configuration);
In order to solve my problem, I move the line from the top of Global.asax to just after the last route configuration takes place:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
Telerik.Reporting.Services.WebApi.ReportsControllerConfiguration.RegisterRoutes(System.Web.Http.GlobalConfiguration.Configuration);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AutoMapperConfig.RegisterMaps();
}
This has solved the problem!
Related
Very weird problen (weird- cause it worked before).
I am calling the web api Get function on X controller, like this(from PostMan):
But the break point, never hits:
public HttpResponseMessage Get(){}
This is "Global.asax"
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
}
WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute("API Default", "api/{controller}/{id}",
new { id = RouteParameter.Optional });
config.MapHttpAttributeRoutes();
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html"));
config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
}
I already tried solutions in Stackoverflow, but none worked for me.
Can someone direct me to the answer?
the address, without the api/controler, its is working.
now its working , what i did is,
in WebApiConfig.cs, I changed the register method like this:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
this was the old register method:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute("API Default", "api/{controller}/{id}",
new { id = RouteParameter.Optional });
}
and the custom method attribute(without **):
**[ActionName("AllDepartmentNames")]**
[HttpGet]
public HttpResponseMessage AllDepartmentNames()
{...}
I have checked links related to mvc5, webapi2 but not being able to figure out my mistake.
My Problem:
/api/EBanking/CheckLogin is not excuting code of checkLogin method in ebankingcontroller
Links checked:
Custom Routing not working in MVC5
WebAPI2 and MVC5 route config
QueryString with MVC 5 AttributeRouting in Web API 2
App_start Code:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
AutoMapperCentralAppConfig.Configure();
}
RouteConfig.cs
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
WebApiConfig.cs
public static string UrlPrefixRelative { get { return "~/api"; } }
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "ActionBased",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
APi Controller:
[RoutePrefix("api/EBanking")]
public class EBankingController : ApiController
{
public EBankingController()
{
//some other code, it runs
}
[HttpGet, HttpPost]
[Route("CheckLogin")]
public IEnumerable<usr06user_role> CheckLogin(string UserName, string Password)
{
//main code which doesn;t runs
}
public IEnumerable<usr06user_role> GetAll()
{
//test code which runs when we call: /api/ebanking/
}
result screenshot:
In your WebApiConfig.cs add another route for action based routing like this:
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "ActionBased",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
This "api/{controller}/{action}/{id}" will allow calls to api/ebanking/checklogin
Alternatively you can even add full route in attribute such as:
[Route("api/EBanking/CheckLogin")]
public IEnumerable<usr06user_role> CheckLogin(string UserName, string Password)
{
//main code which doesn;t runs
}
I have created an mvc application with SSO. I have added an Api controller, but whenever i try to get data from it, i get error.
URI= https://localhost:44305/api/graph/get
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: /api/graph/get
Here is my Route config
public class RouteConfig
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//routes.MapRoute(
// name: "Default",
// url: "{controller}/{action}/{id}",
// defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
routes.MapRoute(
name: "Default",
url: "api/{controller}/{action}/{id}",
defaults: new { controller = "Graph", action = "Get", id = UrlParameter.Optional }
);
}
}
This is my web api controller
public JsonResult<List<Claim>> Get()
{
var principal = (User as ClaimsPrincipal);
List<Claim> claimsList = new List<Claim>();
foreach (var claim in principal.Claims)
{
claimsList.Add(claim);
}
return Json<List<Claim>>(claimsList);
}
Not getting any build error. Any help is appreciated
Hy Guys.Thanks for all your help. I have figured out the solution. The answer is that in Global.asax.cs,
GlobalConfiguration.Configure(WebApiConfig.Register)
has to be called before
RouteConfig.RegisterRoutes(RouteTable.Routes).
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
);
}
}
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultDataApi",
routeTemplate: "Api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
FluentValidationModelValidatorProvider.Configure();
}
}
You should have 2 config files:
RoutesConfig.cs and WebApiConfig.cs
RoutesConfig should look like this:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
Log.Instance().Debug("Registering Routes");
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
}
WebApiConfig.cs should look like this:
public static class WebApiConfig
{
public static void Configure(HttpConfiguration config)
{
ConfigureRouting(config);
ConfigureFormatters(config);
}
private static void ConfigureFormatters(HttpConfiguration config)
{
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new NiceEnumConverter());
}
private static void ConfigureRouting(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional, #namespace = "api" });
}
}
Within global.asax.cs you should have something like this:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
// Register them in this order
GlobalConfiguration.Configure(WebApiConfig.Configure); //registers WebApi routes
RouteConfig.RegisterRoutes(RouteTable.Routes); //register MVC routes
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
Your controller does look a little strange why not let the default serialiser take care for things for you:
public IEnumerable<Claim> Get()
{
var principal = (User as ClaimsPrincipal);
List<Claim> claimsList = new List<Claim>();
foreach (var claim in principal.Claims)
{
claimsList.Add(claim);
}
return claimsList;
}
EDIT: removed redundant code
Assuming the name of your controller is GraphController, I think the url you should be using is /api/graph/get.
If it's named something different, you'll need to adjust the url accordingly.
Also, there's a separate .cs file in MVC projects you should use to manage WebAPI routes - WebApiConfig.cs
Hi I am just starting to mess with WebApi to setup a REST api for my angular app.
I simply just added a "Web API 2 Controller with read/write actions"
I then just try to test it by just typing the url in the browser but I get a 404.
Everything is pretty much out of the box.
WebApiConfig.cs looks like
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
RouteConfig.cs is
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 }
);
}
}
Global.asax
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfiguration.Configure(WebApiConfig.Register);
InitializeDatabase("Data Source=.;Initial Catalog=msproto;Integrated Security=True;MultipleActiveResultSets=True;");
}
Is there something I have to add to the web config? If I add a normal controller "MVC 5 Controller with read/write actions" it will hit my breakpoints in the get requests.
Make sure the Web API routes are registered before the MVC routes in your Global.asax.
I have a webapi project and I don't want to return any html or razor views. I want the default controller and action to be an HTTP GET for one of my API controllers. My code is the following:
MVC route config:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteTable.Routes.MapRoute(
"Default",
"{controller}/{id}",
new { controller = "Enpoint", action = "Get", id = UrlParameter.Optional }
);
}
}
WebApi route config:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "ApiDefault",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Application_Start:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
Do you know how can I configure the router to redirect to by default:
GET /api/home