Cannot Access Web API Controller - asp.net

I have a Web API with 2 Controllers: ValuesController and MyController
I initially created ValuesController and I access it using MyUrl/api/values, this works fine.
I then added another controller MyController and in the comments that were generated by Visual Studio, it says that I access it using api/. When I try api/MyController, it doesn't work, I get a page that reads No HTTP resource was found that matches the request URI '/api/MyController'.
My WebApiConfig looks like this:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
How do I access the GET in my new controller? Do I need to modify the WebApiConfig?
Thanks in advance for any help.

If the controller-class is actually named "MyController", then the URL that points to it should be:
/api/My
not:
/api/MyController

Related

Default route when using ASP.NET MVC attribute routing

I'm using attribute routing with Web API, and everything works as expected if I request the URL /myapi/list with the following controller:
[RoutePrefix("myapi")]
public class MyController : ApiController
{
[HttpGet]
[Route("list")]
public async Task<string> Get()
{
// Return result
}
}
However, I would like my Get() method to be the default, i.e. when requesting the URL /myapi (without the /list part).
But if I remove the "list" part of the Route attribute like so...
[RoutePrefix("myapi")]
public class MyController : ApiController
{
[HttpGet]
[Route] // Default route
public async Task<string> Get()
{
// Return result
}
}
...I get a 403.14 error saying
"The Web server is configured to not list the contents of this
directory."
Any ideas of what might be causing this?
Thanks!
Edit: If I request the API controller using the default route pattern like /api/myapi, it maps to the Get() method as expected.
Default route is registered after the attribute routes:
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Use
[Route("")]
for the default route
[RoutePrefix("myapi")]
public class MyController : ApiController
{
//GET myapi
[HttpGet]
[Route("")] // Default route
public async Task<string> Get() { ... }
}
Reference: Attribute Routing in ASP.NET Web API 2 : Route Prefixes
As pointed out by haim770 in the comments: the problem was that I had a physical folder with the same name as the route prefix.
Renaming either the folder or the route prefix solved the problem.
I guess an alternative would have been to tweak the route/handler order to ensure attribute routes take precedence over physical paths.

Working with WebApi in a Web Forms application

I am trying to add WebApi in my Web Forms application (Visual Studio 2015, .NET 4.6). I added App_Start folder and WebApiConfig.cs in it as following (pretty much copied from an MVC app):
public class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
// Adding routes for WebApi controllers
RouteTable.Routes.MapHttpRoute(
name: "SearchApi",
routeTemplate: "api/search",
defaults: new { controller = "SearchController" }
);
}
}
Then, I created a folder Controllers/WebApi and added SearchController.cs:
namespace IdeaMaverick.Web.Controllers.WebApi
{
public class SearchController : ApiController
{
public IEnumerable<string> Get()
{
return new [] { "value1", "value2" };
}
}
}
But when I hit http://example.com/api/search in the browser, I get this error:
{"message":"No HTTP resource was found that matches the request URI
'http://www.example.com/api/search'.","messageDetail":"No type
was found that matches the controller named 'SearchController'."}
I'm obviously missing something but I can't figure out what.
I found the issue - in defaults for the route I had to specify the controller name omitting "Controller", so it has to be like
defaults: new { controller = "Search" }

Asp.net web api routing to be like mvc site

How can I add a route so that my controllers will work similar to a mvc web appliation.
Because the default way that they have configured the routes will end up with you having so many controllers.
I just want to have a controller called Auth,
and then in my web API be able to call api/auth/login or api/auth/logout etc.
Because with the default routing I will have to create a controller for login and one for logout.
So then I would have my Controller like so:
public class AuthController : ApiController
{
[HttpPost]
public IEnumerable<string> Login()
{
return new string[] { "value1", "value2" };
}
[HttpGet]
public HttpMessageHandler Logout()
{
return new HttpMessageHandler.
}
}
The default Web API route uses the http method to determine the action to select. For example POST api/auth would look for an action named Post on AuthController.
If you want to use RPC style routing (like MVC) you need to change the default route to:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Now POST api/auth/login will look for an action named Login on AuthController.

Routing in ASP .NET Web API

I created a web service using WEB API.
I'm using this routing configuration
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
And my solution include two controller (ProductController and DetailController)
So when I want to call a WS that refers to the GetDetails method(is located inside DetailController) I have to use a URL like this:
http://localhost/api/Details/GetDetails/?id=4
Is there a way for use, for the same request, this URL instead:
http://localhost/api/Product/GetDetails/?id=4
letting the GetDetails method inside the DetailController?
Actually your urls should be:
http://localhost/api/Details/4
http://localhost/api/Products/4
and your controllers:
public class DetailsController: ApiController
{
public HttpResponseMessage Get(int id)
{
...
}
}
and:
public class ProductsController: ApiController
{
public HttpResponseMessage Get(int id)
{
...
}
}
Now that's RESTful.

How to catch undefined api method calls in ASP.NET MVC4 Web API

ASP.NET / Mono MVC4 Web API v.1 application.
How to catch calls to undefined api methods.
Calling http://localhost:52216/erp/api/undefinedmethod returns error to browser:
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http:// localhost:52216/erp/api/undefinedmethod'.
</Message>
<MessageDetail>
No type was found that matches the controller named 'undefinedmethod'.
</MessageDetail>
</Error>
How to catch this error for logging to database?
I tried code from question
How do I log ALL exceptions globally for a C# MVC4 WebAPI app?
but Application_Error and exception filter code is still not executed, error is returned to
browser.
How to catch this error ?
If url is without api like
'http://localhost:52216/erp/undefinedmethod'
Application_Error is executed properly.
WebAPI configuration from VS2013 WebAPI project template is used:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Update
I tried changed answer.
API controllers are using Forms authorication and are decorated with standard [Authorize]
attribute.
If authorization fails, standard xml api error message
<Error>
<Message>Authorization has been denied for this request.</Message>
</Error>
occurs. How to catch this error also ?
Imran Baloch wrote an article on exactly how to achieve this. Basically you need to create your own HttpControllerSelector and HttpActionSelector. You can find the article here.
EDIT:
If your application uses routes other than those registered in the WebApiConfig you will need to make some changes to the routing. Instead of defining the Error404 route at the end of the Register method, define a new method (RegisterNotFound) to register the route:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
public static void RegisterNotFound(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "Error404",
routeTemplate: "{*url}",
defaults: new { controller = "Error", action = "Handle404" }
);
}
}
And then in the Global.asax register call this method last:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
WebApiConfig.RegisterNotFound(GlobalConfiguration.Configuration);
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),
new HttpNotFoundAwareDefaultHttpControllerSelector(GlobalConfiguration.Configuration));
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpActionSelector),
new HttpNotFoundAwareControllerActionSelector());
}

Resources