custom error pages for non existent controllers in apiController - c#

I have created a MVC web API with MVC 5 controller for managing CRUD operations.
Here is the snippet of my API controller:
public class UserController : ApiController
{// GET api/<controller>
public IEnumerable<User> GetAllUsers()
{
UserRepository urepo = new UserRepository();
return urepo.UserList(0);
}
public User GetUserByID(int userID)
{
UserRepository urepo = new UserRepository();
var userDetails = urepo.UserList(userID);
return (from n in userDetails where n.UserId == userID select n).SingleOrDefault();
} }
and here is my WebAPIconfig file
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
When I access this controller from URL say localhost/api/User/GetAllUsers
it is returning all users as expected.
But if i try to access in other way say localhost/api/User which is not there , will throw file not found error and show default error page.
what i need is instead of this default error page custom error page need to be displayed.
How this can be achieved?

Let's say that you are developing a HTTP RESTful application using ASP.NET Web API framework. In this application you need to handle HTTP 404 errors in a centralized location.
This Blog might help you in finding what you need.
Handling HTTP 404 Error in ASP.NET Web API

Related

Unable to hit any attributed routes in new WebApi project - only 404s returned

I'm building a new Web API project from scratch and am unable to get any response other than 404 (Not Found).
The routes for each controller and method are declared in attributes.
Here is my Global.asax Application_Start method.
protected void Application_Start()
{
log4net.Config.XmlConfigurator.Configure();
Log.Info("Application_Start...");
GlobalConfiguration.Configure(IoCConfig.Register);
Collaboral.Common.DB.DatabaseUtil.SetRetryStratPol();
GlobalConfiguration.Configuration.EnsureInitialized();
}
That code calls the method IoCConfig.Register.
public static void Register(HttpConfiguration config)
{
config.DependencyResolver = new TinyIocWebApiDependencyResolver(RegisterDependencies());
config.EnableCors(new EnableCorsAttribute(origins: "*", headers: "*", methods: "*"));
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
foreach (var route in config.Routes)
{
Log.Info($"{nameof(Register)}: Route = \"{route.RouteTemplate}\"");
}
}
As can be seen, I'm logging the routes in the config.Routes collection, and I can see from the log file that this collection contains only the default route which I have manually mapped.
WebApiApplication | - Application_Start...|
IoCConfig | - Register: Route = ""|
IoCConfig | - Register: Route = "api/{controller}/{id}"|
And here is an example of how I've used the routing attributes.
namespace MyApi.Controllers
{
[BasicHttpAuthorize(RequireAuthentication = true)]
[RoutePrefix("v1/projects")]
public class ProjectsController : ApiController
{
[Route("{projectId:guid}/assocs")]
[HttpGet]
[Authorize(Roles = // ...)]
public IHttpActionResult GetAssociations(Guid projectId)
{
// ...
}
The URL I'm attempting is
http://localhost/myapi/v1/projects/bbe89597-28ae-40d5-8071-56dfb222f97b/assocs
Some additional points:
this WebApi project is replacing an older version which has been excluded from the solution. The routes are identical
the project is hosted as an application in IIS. I'm using the same application as the older API but the application's settings (in IIS) point to the local folder for the newer project
What am I missing?
Why you are using 'myapi' in your endpoint? your endpoint should be like
http://localhost/v1/projects/bbe89597-28ae-40d5-8071-56dfb222f97b/assocs
You can refer this link for more information.
https://learn.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

ASP.NET Web API Route Controller Not Found

I am trying to post to the following Web API:
http://localhost:8543/api/login/authenticate
LoginApi (Web API) is defined below:
[RoutePrefix("login")]
public class LoginApi : ApiController
{
[HttpPost]
[Route("authenticate")]
public string Authenticate(LoginViewModel loginViewModel)
{
return "Hello World";
}
}
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 }
);
}
Here is the error I get:
Request URL:http://localhost:8543/api/login/authenticate
Request Method:POST
Status Code:404 Not Found
Remote Address:[::1]:8543
Your controller name "LoginApi" needs to end in "Controller" in order for the framework to find it. For example: "LoginController"
Here is a good article which explains routing in ASP.NET Web API: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api
You are using login as your route prefix on your controller so trying to call
http://localhost:8543/api/login/authenticate
will not be found as this code
[RoutePrefix("login")]
public class LoginApi : ApiController
{
//eg:POST login/authenticate.
[HttpPost]
[Route("authenticate")]
public string Authenticate(LoginViewModel loginViewModel)
{
return "Hello World";
}
}
will only work for
http://localhost:8543/login/authenticate
You need to change your route prefix to
[RoutePrefix("api/login")]
public class LoginApi : ApiController
{
//eg:POST api/login/authenticate.
[HttpPost]
[Route("authenticate")]
public string Authenticate(LoginViewModel loginViewModel)
{
return "Hello World";
}
}
Notice you are using both attribute routing on the controller/action and convention routing with config.Routes.MapHttpRoute.
config.Routes.MapHttpRoute will map the routes as per your definition "api/{controller}/{id}".
While attribute routing, will map the routes based on how you've defined them: /login/authenticate.
Also, since you are using both attribute routing and convention routing, attribute routing takes presendence. I would stick to using one or the other. Having both adds a bit of confusion as to what route will be used to access an action method.

Listing page always returned a exception for asking provide id

I'm using ASP.NET MVC + WEB API 2, with self host.
This is my self host Startup.cs:
public class SelfHostStartup
{
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
var config = new HttpConfiguration();
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
ConfigureAuth(appBuilder);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = UrlParameter.Optional }
);
appBuilder.UseWebApi(config);
}
}
already specified the id is optional, but when accessing url:
http://localhost:9000/api/MyTransactionModels/
always prompt error:
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Threading.Tasks.Task`1[System.Web.Http.IHttpActionResult] GetMyTransactionModels(Int32)' in 'MyTest.Controllers.MyTransactionModelsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
this is the Controller:
public class MyTransactionModelsController : ApiController
{
private ApplicationDbContext db = new ApplicationDbContext();
// GET: api/MyTransactionModels
[Authorize]
public IQueryable<MyTransactionModel> GetMyTransactionModels()
{
return db.MyTransactionModels;
}
// GET: api/MyTransactionModels/5
[ResponseType(typeof(MyTransactionModel))]
public async Task<IHttpActionResult> GetMyTransactionModels(int id)
{
...
}
}
While testing result is correct with the detail page by url:
http://localhost:9000/api/MyTransactionModels/1
anyone could help?
Change UrlParameter.Optional to RouteParameter.Optional. The former is for standard ASP.NET MVC whereas the latter is for ASP.NET Web API. They behave differently.
Just tested with a newly created Web API project, I am getting the exact same error as you if I use UrlParameter.Optional, but not when it is switched to RouteParameter.Optional.
See this SO answer Should I use RouteParameter or UrlParameter for an Asp.NET web-api route?

Calling ASP.Net Web API From ASP.NET Website Webforms

For the last couple of hours i'm trying to execute web api action hosted in asp.net webforms website.
I know its wired but due to old project design i have to do this.each time i call the action in Controller i got
{"Message":"No HTTP resource was found that matches the request URI 'http://localhost:3049/api/chart/test?id=58'.","MessageDetail":"No action was found on the controller 'Chart' that matches the request."}
My Project structure as follows:-
My Classes code looks very simple:-
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.EnableCors();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new {id = RouteParameter.Optional }
);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
}
}
My Controller:-
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class ChartController : ApiController
{
[HttpGet]
public static string test(string id)
{
return id;
}
}
What i miss ?
Make your action method non-static. In Microsoft's documentation, they say this:
Which methods on the controller are considered "actions"? When selecting an action, the framework only looks at public instance methods on the controller.
Also, your routing is in the form of api/{controller}/{id} but the URL you're accessing is in the form of /api/controller/action?id=string. Notice the mismatch? You can change your action method to match your route.
[HttpGet]
public string Get(string id)
{
return id;
}
And then access it at /api/chart/58.
With the default routing structure in Web API, your route tells it what controller, the selected action method is based on the HTTP Method (GET, POST, PUT, DELETE, HEAD, OPTIONS, PATCH) and the parameters, and then other segments of the URL become the parameters.
Learn more detail about Web API Routing on MSDN.

MVC 4 Web Api 404

I have looked all over for some kind of soultion for this and it seems I have it setup correctly and followed all corrections in other questions.
When calling "http://localhost/en/api/cart/get" I get:
{"Message":"No HTTP resource was found that matches the request URI 'http://localhost/en/api/cart/get'.","MessageDetail":"No type was found that matches the controller named 'cart'."}
...when trying to access a ApiController setup in an EPiServer CMS/Commerce 7.5+ solution.
The Controller looks like this:
public class CartController : ApiController
{
[HttpGet]
public string Get()
{
return "OK";
}
}
In Global.asax.cs i have this:
protected void Application_Start()
{
RegisterApis(GlobalConfiguration.Configuration);
And the RegisterAPis looks like this:
public static void RegisterApis(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
"Api", // Route name
"api/{controller}/{action}/{id}", // URL with parameters
new { id = RouteParameter.Optional } // Parameter defaults
);
config.Routes.MapHttpRoute(
"LanguageAwareApi", // Route name
"{language}/api/{controller}/{action}/{id}", // URL with parameters
new { id = RouteParameter.Optional } // Parameter defaults
);
// We only support JSON
var appXmlType = GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
}
On the same machine I have the EPiServer Commerce starterkit running i IIS and the code for registering the api controllers is the same. That site runs fine and the api calls can be made correctly but on my site all I get is 404.
So I am probably missing some configuration but I can't for my life figure out what it is. The weird part is that on my site I'm running the EPiServer ServiceApi which creates the /episerverapi Web Api mapping and that works just fine.
Anyone got any clues on why I can't get my APiControllers to work?
In Web API the http verb help the framework to find the right action to be executed and return a result. For sample, in a case of a get method, you just call the controller by get http verb:
http://localhost/en/api/cart
It will bind a Get action method in the Cart controller class. It is valid for a Post, Put, Delete methods too. Keep the default route of asp.net web api
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Try calling just
http://localhost/en/api/cart
In WebAPI if the name of the method matches a HTTP verb then it calls that method when that verb is used on that controller.

Categories

Resources