Asp.net MVC 3 routing area fail - asp.net-mvc

I have this routes:
My website route on WebSite/Global.asax.cs:
namespace WebSite
{
public class MvcApplication : HttpApplication
{
public static void RegisterRoutes(RouteCollection routes) {
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
...
routes.MapRoute(
"Default",
"Authenticated/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new[] { "WebSite.Controllers" }
);
...
}
void Application_Start()
{
...
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
...
}
}
}
My Admin Area route on WebSite/Areas/Admin/AdminAreaRegistration.cs:
namespace WebSite.Areas.Admin
{
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"qwerty/Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional },
new[] { "WebSite.Areas.Admin.Controllers" }
);
}
}
}
My URLs:
WebSite: http://www.mywebsite.com/Authenticated/Controller/Action...
Admin: http://www.mywebsite.com/qwerty/Admin/Controller/Action...
My problem:
With WebSite URL I can call Controllers/Actions from Admin Area, without use "qwerty/Admin", and this is not right. How can I fix this?
Thank you.

Just put this code after each MapRoute. It should work!
.DataTokens["UseNamespaceFallback"] = false;

Related

Convert ASP.NET MVC MvcRouteHandler to ASP.NET Core MVC

I have to port over the following ASP.NET MVC code to .NET Core and I'm stuck on how to do this.
This is my old ASP.NET MVC code:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
routes.MapRoute(
name: "Cultural",
url: "{culture}/{controller}/{action}",
defaults: new { controller = "Home", action = "Index", culture = AppGlobal.DefaultLocale }).RouteHandler = new Routers.CulturalRouteHandler();
}
}
public class CulturalRouteHandler: MvcRouteHandler
{
protected override IHttpHandler GetHttpHandler(System.Web.Routing.RequestContext requestContext)
{
var lang = requestContext.RouteData.Values["culture"].ToString();
var ci = new CultureInfo(lang);
// Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
Thread.CurrentThread.CurrentUICulture = ci;
return base.GetHttpHandler(requestContext);
}
}
I converted the routehandler to the following in .NET Core:
public class CulturalRouteHandler : IRouter
{
private readonly IRouter _defaultRouter;
public CulturalRouteHandler(IRouter defaultRouter)
{
_defaultRouter = defaultRouter;
}
public async Task RouteAsync(RouteContext context)
{
var lang = context.RouteData.Values["culture"].ToString();
var ci = new CultureInfo(lang);
CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
CultureInfo.CurrentUICulture = ci;
await _defaultRouter.RouteAsync(context);
}
public VirtualPathData GetVirtualPath(VirtualPathContext context)
{
return _defaultRouter.GetVirtualPath(context);
}
}
I'm stuck trying to hook into the route handler for the specific route now.
How would I go about hooking the IRouter into my code for program. cs below:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapControllerRoute(
name: "Cultural",
pattern: "{culture}/{controller}/{action}",
defaults: new { controller = "Home", action = "Index", culture = AppGlobal.DefaultLocale };
You change your RouteHandler implementation
public class MyRequestHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new MyHttpHandler(this, requestContext);
}
}

How to use Route attribute while working with areas in mvc?

I am working on a project which is having some areas defined in it. I want to use Route attribute to do routing in my project. So I used routes.MapMvcAttributeRoutes() in my route.config file. The following is my route.config file.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "Shopper.Controllers" }
);
}
}
After that I am having two areas in my project like productarea and productcategoryarea. I have global.asax file as below.
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
// AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
I want to give routes to some of the methods from productcategoryarea and productarea. but when i applies Route("productcategories") on one of methods of productcategoryarea it will show me 404 error.
This is my productcategoryregistration.cs file from productcategoryarea
public class ProductCategoryAreaAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "ProductCategoryArea";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"ProductCategoryArea_default",
"ProductCategoryArea/{controller}/{action}/{id}",
new {controller="ProductCategory", action = "ListOfProductCategory", id = UrlParameter.Optional }
);
}
}
This is my method on which i want to provide route attribute.
[Route("productcategories")]
public ActionResult ListOfProductCategory(ProductCategoryManager productcategorymanager, int page = 1, int pageSize = 4)
{
if (Session["UserName"].ToString() != null)
{
if (Session["UserName"].ToString() == "admin")
{
//returning list of product category
List<ProductCategory> listproductcategories = db.ProductCategories.ToList();
PagedList<ProductCategory> model = new PagedList<ProductCategory>(listproductcategories, page, pageSize);
return View(model);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
return RedirectToAction("Index", "Home");
}
}
So please help me to get out of it.

Access asp.net mvc controller ActionResult

i want to access action result in controller(my controlelr is HotelController action is Index)
(http://localhost:9001/Hotel/Index) it gives below error
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: /Hotel/Index
Hotel controller
public class HotelController : Base.BoxyController
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
ViewBag.Title = "SonDakka - Otel";
}
public ActionResult Index(string culture)
{
.........
BoxyController
public class BoxyController : MainController
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
..........
MainController
public class MainController : SiteController
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
......
SiteController
[ExitHttpsIfNotRequired]
public class SiteController : Controller
{
public Account Me { get; set; }
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
.......
and this is my global.asax
using System;
using System.Data.Entity;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using Tourism.Data;
using Tourism.Data.Mvc.Authorization;
using Tourism.Data.Mvc.Routing;
namespace Tourism
{
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
public static void RegisterRoutes(TourismContext db, RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
var cultures = db.Cultures.Select(c => c.Code).ToArray();
routes.MapRoute
(
"Ajax",
"{culture}/{controller}/{action}/{id}",
new { id = UrlParameter.Optional },
new { culture = new ArrayRouteConstraint(true, cultures), controller = new ArrayRouteConstraint(true, "Ajax") }
).RouteHandler = new GlobalizedRouteHandler();
routes.Add
(
"Page",
new GlobalizedPageRoute
(
"{culture}/{path}",
null,
new RouteValueDictionary { { "culture", new ArrayRouteConstraint(true, cultures) } },
new GlobalizedRouteHandler()
)
);
routes.Add
(
"Route",
new GlobalizedRoute
(
"{culture}/{path}/{slug}/{id}",
new RouteValueDictionary { { "culture", UrlParameter.Optional }, { "path", UrlParameter.Optional }, { "slug", UrlParameter.Optional }, { "id", UrlParameter.Optional } },
new RouteValueDictionary { { "culture", new ArrayRouteConstraint(false, cultures) } },
new GlobalizedRouteHandler()
)
);
}
protected void Application_Start()
{
Database.SetInitializer<TourismContext>(null);
using (var db = new TourismContext())
{
#if !DEBUG
if (!db.Database.CompatibleWithModel(true))
{
System.Web.HttpRuntime.UnloadAppDomain();
throw new Exception("Veritabanı değişikliği tespit edildi.");
}
#endif
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(db, RouteTable.Routes);
}
}
protected void Application_PostAuthenticateRequest()
{
if (Request.IsAuthenticated)
{
Context.User = System.Threading.Thread.CurrentPrincipal =
new AuthorizationPrincipal(Context.User.Identity);
}
}
}
}
Because this is due to Razor engine unable to find Thanks action in Hotel controller. You need to make a Thanks action with in Hotel controller like this:
public class HotelController : Base.BoxyController
{
public ActionResult Thanks(string culture)
{
return View();
}
}
And also make sure to create a view in Hotel folder with your html code.
Based on the route config you posted, your URL should be with culture, for example:
http://localhost:9001/en/Hotel/Index
Notice the en before Hotel. It could be any value that is valid in your database.

Map multiple indexed routes

I have a number of controllers in application:
ApiV1Controller
ApiV2Controller
ApiV3Controller
...
Is it possible to map routes for them with single MapRoute statement to URLs like /api/v1/{action}?
You could write a custom route. Let's suppose that you have the following controllers:
public class ApiV1Controller : Controller
{
public ActionResult Index()
{
return Content("v1");
}
}
public class ApiV2Controller : Controller
{
public ActionResult Index()
{
return Content("v2");
}
}
public class ApiV3Controller : Controller
{
public ActionResult Index()
{
return Content("v3");
}
}
Now write a custom route:
public class ApiRoute : Route
{
public ApiRoute()
: base("api/{version}/{action}", new RouteValueDictionary(new { action = "index" }), new MvcRouteHandler())
{
}
public override RouteData GetRouteData(HttpContextBase httpContext)
{
var rd = base.GetRouteData(httpContext);
if (rd == null)
{
return null;
}
rd.Values["controller"] = "Api" + rd.GetRequiredString("version");
return rd;
}
}
That could be registered in your Global.asax:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.Add("ApiRoute", new ApiRoute());
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
and that's pretty much it. Now you could play with urls:
/api/v1
/api/v2
/api/v3

Is Ninject MVC supposed to work with MVC 2 Preview?

I am running a MVC 2 Preview and this is my first time trying to use Ninject2 MVC
There error that I am continently getting is:
An error occurred when trying to create a controller of type 'MyMVC.Controllers.EventsController'. Make sure that the controller has a parameterless public constructor.
What I have in my Global.cs is this:
public class MvcApplication : NinjectHttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("elmah.axd");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
routes.MapRoute(
"Root",
"",
new { controller = "Home", action = "Index", id = "" }
);
}
protected override void OnApplicationStarted()
{
RegisterRoutes(RouteTable.Routes);
RegisterAllControllersIn(Assembly.GetExecutingAssembly());
}
protected override IKernel CreateKernel()
{
return new StandardKernel(new ServiceModule());
}
}
internal class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<IEventService>().To<EventService>();
Bind<IEventRepository>().To<EventRepository>();
}
}
And this is what my Controller looks like.
public class EventsController : Controller
{
private IEventService _eventService;
//
// GET: /Events/
public EventsController(IEventService eventService)
{
_eventService = eventService;
}
public ActionResult Index(string name)
{
return View(_eventService.GetEvent(name));
}
public ActionResult UpcomingEvents()
{
return View(_eventService.GetUpcomingEvents().Take(3).ToList());
}
}
I've not used Ninject, but I would assume you need to implement your own IControllerFactory. Until they update it to MVC 2. Then utilize that instead of RegisterAllControllersIn(..):
ControllerBuilder.Current.SetControllerFactory(new MyNinjectControllerFactory());
EDIT: Again, i'm not all that familiar with Ninject but this might work as a simple factory:
public class MyNinjectControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(Type controllerType)
{
return [Container].GetInstance(controllerType) as Controller;
}
}
At the risk of stating the obvious, you should try adding a parameterless constructor to your Events Controller.
public class EventsController : Controller
{
private IEventService _eventService;
//
// Parameterless constructor, so NInject will work
public EventsController() {}
//
// Regular constructor
public EventsController(IEventService eventService)
{
_eventService = eventService;
}

Resources