I have introduced mvc area concept with the durandal
My hierarchy would be
Area.Web
Areas
Blog
Controller
SocialController
Social
View
Task
Controller
View
Scripts
App
Blog
ViewModels
I have route to the area based on my url. For example, localhost/blog
My route woule be:
routes.MapRoute(
name: "blog",
url: "blog/{action}/{id}",
defaults: new { controller = "blog", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "Area.Web.Blog.Controllers" }
);
routes.MapRoute(
name: "Task",
url: "Task/{action}/{id}",
defaults: new { controller = "task", action = "Index", id = UrlParameter.Optional},
namespaces: new string[] { "Area.Web.Task.Controllers" }
);
When I try to navigate to localhost/blog, it call the correct controller and render the correctly. when the durandal route happen blog is excluded.So that my route url not able to fetch the controller.
app.setRoot('viewmodels/social/home', 'entrance');
The following route throws 404 exception, since it ignored the blog in the route url (localhost/social/home)
Please let me know, how to resolve this issue. Is it possible to include area name in all the route and app.set.
Firstly IMHO You should reconsider Your project architecture. For example, if you need to optimize this app with Weyland, both SPAs will end up in the same file what does not gives You required separation.
However, instead of having them both under the app folder, you can make separate folders, and give each SPA it's own main.js file.
In such case You would have following project structure:
Area.Web
AppBlog
Services
Views
ViewModels
main.js
AppTask
Services
Views
ViewModels
main.js
Areas
Blog
Controller
View
Task
Controller
View
Scripts
durandal
etc.
Content
etc.
Your View in Blog Area would use follwoing JS import:
<script src="~/Scripts/require.js" data-main="#Url.Content("~/AppBlog/main")"></script>
while Task Area would use
<script src="~/Scripts/require.js" data-main="#Url.Content("~/AppBlog/main")"></script>
In such setup Your routes would look similar to exactly the same as in Your code
EDIT
routes.MapRoute(
name: "blog",
url: "blog/{action}/{id}",
defaults: new { controller = "home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "Area.Web.Blog.Controllers" }
);
routes.MapRoute(
name: "Task",
url: "Task/{action}/{id}",
defaults: new { controller = "home", action = "Index", id = UrlParameter.Optional},
namespaces: new string[] { "Area.Web.Task.Controllers" }
);
Related
In previous versions of ASP.NET, and using MVC 5, I could set up a route like this in my AreaRegistraion:
context.MapRoute(
"pfrecent",
"Forums/Recent/{page}",
new { controller = ForumController.Name, action = "Recent", page = 1 },
new[] { "PopForums.Controllers" });
This would route /Forums/Recent to the forum controller and its recent action. However, I can't figure out how to make it work in ASP.Net 5/MVC 6. I've added [Area("Forums")] to the controller class, and used this route from the Startup class:
routes.MapRoute(
"pfrecent",
"Forums/Recent/{page}",
new { controller = ForumController.Name, action = "Recent", page = 1 });
routes.MapRoute(
name: "areaRoute",
template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
However, it resolves to /Forums/Forum/Recent?page=1. The intention is to continue using /Forums/Recent.
We are using this for enabling areas in MVC 6:
// Configure MVC routing
app.UseMvc(routes =>
{
// Areas support
routes.MapRoute(
name: "areaRoute",
template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
// Default routing
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
The first route is for areas, second is for main content.
On Startup.cs
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "Business",
template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
})
on Controller
[Area("Business")]
public class DemoController : Controller
{
public IActionResult Index()
{
return View();
}
}
Place this in your Startup.cs file at the TOP of the routes list:
routes.MapRoute(
name: "forumsAreaRoute",
template: "Forums/{action}/{page?}",
defaults: new {area = "Forums", controller = "Forum", action = "Recent", page = 1});
Your Forum controller should look like this:
[Area("Forums")]
public class ForumController : Controller
{
// GET: /<controller>/
public IActionResult Recent(int? page)
{
// Do action stuff here
}
}
This solution will satisfy a url of http://somedomain.com/Forums/Recent/1 and return the first page.
I hate answering my own questions, but after getting back to this, and looking at source and experimenting, I found that you have to specify the area in the route mapping, as well as the HtmlHelpers (I'm assuming this will be true for tag helpers as well, but I haven't gone that far yet in conversion.) So the route mapping has to look like this:
routes.MapRoute(
"pfrecent",
"Forums/Recent/{page?}",
new { controller = ForumController.Name, action = "Recent", page = 1, Area = "Forums" }
);
The important part is the Area property in the route value object. The HtmlHelper has to look like this, also naming the Area:
#Html.ActionLink(PopForums.Resources.Recent, "Recent", ForumController.Name, new { page = 1, Area = "Forums" }, null)
It causes the URL for the recent page to be /Forums/Recent as expected. As best I can tell, setting routes in a derived AreaRegistration class in MVC5 set the area value on the routes for you. Having [Area("Forums")] on your controller class (which I already had) seems to assume the previous role of area registration.
Mine is simple scenario but I am confused on how routing works.
I have three controllers SearchHome, Home and Account.
Here is route config.
routes.MapRoute("default", "{controller}/{action}/{name}",
new { controller = "SearchHome", action = "Home", name = UrlParameter.Optional }, new[] { "AppName" }
);
I do not want to show my controller name in URL. So, I take away controller in my above code and make it as below.
routes.MapRoute("default", "{action}/{name}",
new { controller = "SearchHome", action = "Home", name = UrlParameter.Optional }, new[] { "AppName" }
);
Controller Name is not showing for SearchHome controller views but Home and Account Views are showing up at all.
What am I doing wrong ? Can I write a seperate route for each controller ?
Here is the same issue but The answer is not working for me.
ASP.NET MVC - Removing controller name from URL
I'm experimenting setting up a multi-tenant solution in asp.net mvc 4 wherein you are able to specify tenant specific overrides to certain controllers if they require different functionality.
I'd like to have routes that are like
/{Controller}/{Action}/{Id}/
/{Tenant}/{Controller}/{Action}/{Id}
If the tenant isn't specified it should just match the first route.
I have tried
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
routes.MapRoute(
name: "Tenant",
url: "{tenant}/{controller}/{action}/{id}",
defaults: new { tenant = "", controller = "Home", action = "Index", id = UrlParameter.Optional });
This works correctly for
/ -> detected as the first route (correct!)
/Home -> detected as
first route (correct!)
/Home/Index -> detected as first route
(correct!)
/Client1/Home/Index - Client1 is detected as controller
name (incorrect)
If I switch the routes around then the tenant route works but the base one does not.
What am I missing here, is it possible to achieve this?
Note, I'd prefer to not have to specify a dummy tenant string in the route as I'll have to translate that back later on in a few places where I need to resolve tenant specific information.
You can use the library I wrote here. This lib allows you to define an alternative route, if the routes conflict. You must define the routes as follows:
var firstRoute = routes.MapReplaceableRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
var secoundRoute = routes.MapRoute(
name: "Tenant",
url: "{tenant}/{controller}/{action}/{id}",
defaults: new { tenant = "", controller = "Home", action = "Index", id =
UrlParameter.Optional }, lookupParameters: new string[] {"tenant"}, lookupService: new LookupService());
firstRoute.AlternativeRoute = secondRoute;
For lookupService, you just need an empty implementation of the IRouteValueLookupService.
I have an ASP.NET MVC 4 app. I'm trying to setup my routes in the RouteConfig.cs file. Essentially, I have two URLs I'm currently interested in. Those URLs are:
/App
/App/Auth
My file structure looks like the following:
/Views
App
Index.cshtml
Auth
Index.cshtml
Docs
Index.cshtml
Index.cshtml
In my RouteConfig.cs file, I have the following:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Index",
"Index",
new { controller = "Views", action = "Index" }
);
routes.MapRoute(
"Dashboard", // Route name
"{controller}/auth/{action}/{id}", // URL with parameters
new { controller = "App", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Oddly, when I visit /App/Auth it takes me to /App. For the life of me, I can't figure out why. Does anyone know how to do this? Thanks!
The app is doing exactly what you asked. Your first route goes to controller "App" and action "Index". Move the folder Auth to same level as App and then change your route to:
routes.MapRoute(
"Dashboard", // Route name
"app/auth/{action}/{id}", // URL with parameters
new { controller = "Auth", action = "Index", id = UrlParameter.Optional }
);
An even better solution, forget the Auth controller and just create a view auth.cshtml in the App folder and an action "Auth" in the App controller, and then you can delete the route altogether and /app/auth will get handled by the default route.
Change the route to this:
routes.MapRoute(
"Dashboard", // Route name
"App/auth/{action}/{id}", // URL with parameters
new { controller = "App", action = "Index", id = UrlParameter.Optional }
);
I have the following routes defined:
routes.MapRoute(
"Content Pages",
"{action}",
new { controller = "Pages", action = "Index" });
routes.MapRoute(
"Default",
"{controller}/{action}/{id}/{title}",
new { controller = "Home", action = "Index",
id = UrlParameter.Optional,
title = UrlParameter.Optional },
new string[] { "MyCompany.Web.Controllers" });
I have a controller named Pages that has some actions like "About", "FAQ" etc that I would like to access like this: mywebsite.com/About
This currently works, but now all of my other controllers end up specifying their default action in the url. My action link for Books renders as mywebsite.com/Books/Index.
How can I modify my routes so that I can achieve this?
I would have a more generic route for all your other controllers like this (but put it after the Page routes below)
routes.MapRoute(
"Content Pages",
"{controller}",
new { Home= "Home", action = "Index" });
and change your Pages one to be more specific for those two actions (assuming you have not got an About or Faq controller).
routes.MapRoute("About Page", "about", new { controller = "Pages", action = "About" });
routes.MapRoute("FAQ Page", "faq", new { controller = "Pages", action = "FAQ" });