WebAPI MVC Areas with same controller name - asp.net-mvc

The structure of webapi is as follows:
App
-Area
-MyArea1
- ControllerA (Route('api/myarea1/controllera'))
-MyArea2
- ControllerA (Route('api/myarea2/controllera'))
Problem is that the route api/myarea1/controllera and api/myarea2/controllera are not being resolved. It comes are 404.
I read somewhere we need to implement IHttpControllerSelector but not sure what is the simplest way to implement this. If there is any other way it can be done?
Any idea.
Edit:
RouteConfig.cs
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 }
);
}
}
WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Edit 2:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapHttpRoute(
name : "MyArea1_default",
routeTemplate : "MyArea1{controller}/{action}/{id}",
defaults : new { action = "Index", id = UrlParameter.Optional }
);
}

If you want to use controllers with the same name, you need to specify the namespace for each route configuration.
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapHttpRoute(
name : "MyArea1_default",
routeTemplate : "MyArea1{controller}/{action}/{id}",
defaults : new { action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "Your.Controller.Namespace.Here" }
);
}
For your reference:
http://haacked.com/archive/2010/01/12/ambiguous-controller-names.aspx/

Related

Handling Bad URLs in ASP.NET MVC

I am working on ASP.NET MVC with Areas. I have three Areas. However, the default route is not an Area. When I ran the Application, I got this error:
The Routes are shown below:
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 },
namespaces: new string[] { "SmartSIMS.Web.Controllers" }
);
}
The Areas are:
Administration
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
name: "Administration_default",
url: "Administration/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "SmartSIMS.Web.Areas.Administration.Controllers" });
}
Students
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
name: "Students_default",
url: "Students/{controller}/{action}/{id}",
defaults: new { action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "SmartSIMS.Web.Areas.Students.Controllers" });
}
Teachers
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
name: "Teachers_default",
url: "Teachers/{controller}/{action}/{id}",
defaults: new { action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "SmartSIMS.Web.Areas.Teachers.Controllers" });
}
How do I resolve this error? Kindly assist.
Problem resolved. I turned RouteDebugger in the web.config to false.

How to use Web API with Areas and Same controller name in different area?

The following Error i faced :
Multiple types were found that match the controller
named 'test'. This can happen if the route that services this request
('JIB/api/{controller}/{action}') found multiple controllers defined
with the same name but differing namespaces, which is not supported.
The request for 'test' has found the following matching controllers:
WebApplication2.Areas.JIB.Controllers.TestController
WebApplication2.Areas.JCB.Controllers.TestController
System.InvalidOperationException
at
System.Web.Http.Dispatcher.DefaultHttpControllerSelector.SelectController(HttpRequestMessage
request) at
System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()
[Route("JIB/api/Test/test")]
[HttpGet]
public IHttpActionResult Test()
{
return Ok("JIBs");
}
--------------
[Route("JCB/api/Test/test")]
[HttpGet]
public IHttpActionResult Test()
{
return Ok("JCB");
}
---------------
Global.asax
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
protected void Application_Start()
{
JCBAreaRegistration.RegisterAllAreas();
// GlobalConfiguration.Configure(WebApiConfig.Register);
RegisterRoutes(RouteTable.Routes);
}
JCBAreaReges
context.Routes.MapHttpRoute(
name: "JCBApiAction",
routeTemplate: "JCB/api/{controller}/{action}"
);
context.Routes.MapHttpRoute(
name: "JCBApi",
routeTemplate: "JCB/api/{controller}"
);
//****************=======Default Route=========*******************
context.MapRoute(
"JCB_dashboard",
"JCB/{controller}/{action}/{id}",
new { Controller = "Dashboard", action = "Index", id = UrlParameter.Optional }
);
context.MapRoute(
"JCB_default",
"JCB/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
JIBAreaReges
context.Routes.MapHttpRoute(
name: "JIBApiAction",
routeTemplate: "JIB/api/{controller}/{action}"
);
context.Routes.MapHttpRoute(
name: "JIBApi",
routeTemplate: "JIB/api/{controller}"
);
//****************=======Default Route=========*******************
context.MapRoute(
"JIB_dashboard",
"JIB/{controller}/{action}/{id}",
new { Controller = "Dashboard", action = "Index", id = UrlParameter.Optional }
);
context.MapRoute(
"JIB_default",
"JIB/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);

web api not working in sub folder

My web API is working well but when i write same code in area folder it not working.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "FeatureA",
routeTemplate: "FeatureA/api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
You need to put your routing details in the "YourHubNameAreaRegistration" class that's in your Area folder. It goes in the RegisterArea method and should look something like this:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Hub_default",
"api/Hub/{action}/{id}",
new { controller = "Hub", action = "Index", id = UrlParameter.Optional }
);
}

MVC.NET Routing

I want to add a new route to my Web Api, which will read various ids and then filter a bunch of books.
So the final url should read something like http://localhost/api/books/1/1/1/1
Now I have added a route to my RouteConfig as follows :-
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "BookFilter",
url: "api/books/{author}/{title}/{genre}/{isbn}",
defaults: new { controller = "Books", action = "BookFilter" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
I also added the following in my BooksController:-
[HttpGet]
public IQueryable<BookDTO> BookFilter(int authorId, int titleId, int genreId, int isbn)
{
//filter books here
return db.Books.ProjectTo<BookDTO>();
}
However when I try to reach the page, I get a 404.
What do I need to do to reach my page?
Thanks for your help and time
Web API and MVC are independent frameworks which each have separate types. The likely reason your route is not working is that you are confusing the two. Specifically, for it to work as you configured, you would need an MVC controller (that is, a controller that inherits System.Web.Mvc.Controller).
So, assuming you want to go with Web API as your question would indicate, you first need to ensure the correct definition of your controller. It should inherit from System.Web.Http.ApiController.
public class BooksController : ApiController
{
[HttpGet]
public IHttpActionResult BookFilter(string author, string title, string genre, string isbn)
{
return Ok("Successful result");
}
}
Next, you need to put your routing in the WebApiConfig.cs file, not in the RouteConfig.cs file. Don't forget to remove your route from the RouteConfig.cs file.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "BookFilter",
routeTemplate: "api/books/{author}/{title}/{genre}/{isbn}",
defaults: new { controller = "Books", action = "BookFilter" });
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
You also need to ensure that the call to GlobalConfiguration.Configure(WebApiConfig.Register); is in your application startup path (by default in Global.asax).
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);
}
}
Make sure to use the same parameter name in your action (eg. change author to authorId):
Optionally, you can also specify default values for these parameters at your RouteConfig, as follows:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "BookFilter",
url: "api/books/{authorId}/{titleId}/{genreId}/{isbn}",
defaults: new { controller = "Books", action = "BookFilter", authorId= UrlParameter.Optional, titleId = UrlParameter.Optional, genreId = UrlParameter.Optional, isbn = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Controller:
[HttpGet]
public IQueryable<BookDTO> BookFilter(int authorId, int titleId, int genreId, int isbn)
{
//filter books here
return db.Books.ProjectTo<BookDTO>();
}

Controller action not found

I am using web api in my application. Web api 2 routing is working fine but the controller action routing is not found.
this is my global cs
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();
}
}
Route Config
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}",
defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
);
}
}
Web api config
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 }
);
}
}
Controller
public class LoginController : Controller
{
public ActionResult Index()
{
return View("~/Views/Default/Login.cshtml");
}
public ActionResult LogOut()
{
var ctx = Request.GetOwinContext();
var authManager = ctx.Authentication;
authManager.SignOut("ApplicationCookie");
return RedirectToAction("index", "home");
}
}
Change your Route config as
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "Focus/{controller}/{action}",
defaults: new { controller = "Default", action = "Index", id = UrlParameter.Optional }
);
}
}
Since "Focus" is defined in iis, it might or might not work with it. Please try, i don't have envoirment to test it right now.
Your url http://localhost/Focus/Login/Logout doesn't match the pattern of routeTemplate "Api/{controller}/{id}" in WebApiConfig. Try to match your url to the pattern.
Thank you deusExCore I solve the problem
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 }
);
}
}

Resources