I was referencing this question to try and get this done, but it only works for my index method and I am not sure why.
My project has one area in it (if that is relevent) and I have about 5 different views that I want to hide /home/ in the url.
Code:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"JobResults", // Route name
"JobSearch/{title}-{id}", // URL with parameters
new { controller = "JobSearch", action = "Job" }, // Parameter defaults
new[] { "inkScroll.Web.Controllers" }
);
routes.MapRoute("home", "{action}",
new { controller = "Home", action = "index" });
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new
{
controller = "^(account|common|base|jobsearch)$", //every controller goes in here
action = "Index",
id = UrlParameter.Optional
},
new[] { "inkScroll.Web.Controllers" }
);
I am solving the same problem with the help of Attribute based Routing feature of ASP.NET MVC 5. Say, I have an action named ContactUs in my Home Controller as follows:
public ActionResult ContactUs()
{
return View();
}
I used to get Url for ContactUs as /Home/ContactUs. But, I wanted it to be simply /ContactUs. So, I am decorting the ContactUs action with Route Attribute as follows:
[Route("ContactUs")]
public ActionResult ContactUs()
{
}
So, this is working perfectly for me. Therefore, if you are using ASP.NET MVC 5, I would say, utilize this excellent feature of MVC5. It will not only save you from separating Route Logic and Actions, but also, it solves many problems very easily.
If ASP.NET MVC5 is not an option for you, or if you dont want to use Route Attribute on Action Methods, then, perhaps the following route can work: ( I did not test it though)
routes.MapRoute("Default", "",
new { controller = "Home", action = "index" });
This page contains helpful resource about Attribute Routing: http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx
Catch all wildcard route as the last one would work
routes.MapRoute("home2", "{*path}",
new { controller = "Home", action = "index" });
Related
I am using C# MVC.
I have an action which looks like this.
public class CustomController : Controller
{
public ActionResult CustomPage(int customPageId)
{
var model = new CustomPageViewModel()
{
customPageId = customPageId
};
return View(model);
}
}
I want to be able to hit this action but to use a different route. For example I want Home/Index to actually hit this action, but to report in the URL that its Home/Index.
My custom pages are stored in the database which tell it what route to have, how can I create routes for my pages programatically and have MVC perform the required actions?
As this is a CMS based system, I don't want to have to create a Home/Index controller and action, as the user may choose any route they wish.
Thanks, Tom
FYI: I have sort of figured this out. Unfortunately Routes are defined when the application starts, so I have to force a restart if I want to setup a new route while the app is running...
Here is the code I have used to setup my routes incase it helps anybody else.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
var pageList = new PageService().Get();
foreach (var page in pageList)
{
var targetRoute = string.Format("{1}/{2}", page.PageArea, page.PageController, page.PageAction);
if (!string.IsNullOrWhiteSpace(page.PageArea))
targetRoute = string.Format("{0}/{1}/{2}", page.PageArea, page.PageController, page.PageAction);
routes.MapRoute(
string.Format("PageBuilder_{0}", page.PageId),
targetRoute,
new { area = "Builder", controller = "Build", action = "Index", pageId = page.PageId }
);
}
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
I have an angular application, which i have split into 2, because of functionality. For here, we will call the apps Default and Admin.
In my ASP.NET MVC Website, i have this route defined, which will catch all URLs and load the Home/Index.cshtml view.
// Mvc routes
app.UseMvc(builder =>
{
// default goes to Home, and angular will deal with client side routing
builder.MapRoute(
name: "default",
template: "{*url}",
defaults: new { controller = "home", action = "index" });
});
Now if the user goes to a URL that contains the word admin (eg. www.mysite.com/admin or www.mysite.com/admin/something) then i would like to return my Admin/Index.cshtml view.
To accompolish this, i have added my AdminController as so
[Authorize]
public class AdminController : Controller
{
[Route("~/Admin/{id?}")]
public IActionResult Index()
{
return View();
}
}
But if i try and load a url with more than 2 parameters, such as www.mysite.com/admin/page/12 my Home/Index.cshtml is being returned.
How can i get my Admin view to be returned if the word Admin is after the domain name, no matter how many parameters are in the URL??
Change your code like below:
routes.MapRoute(
name: "spa-fallback-admin",
template: "admin/{*url}",
defaults: new { controller = "Admin", action = "Index" });
routes.MapRoute(
name: "spa-fallback",
template: "{*url}",
defaults: new { controller = "Home", action = "Index" });
[Route("~/Admin/{id?}")] just can't catch www.mysite.com/admin/page/12, so it moves on to default route. You should either pass your parameters via query string, or add different actions for each parameter combination.
[Route("~/Admin/")]
public IActionResult Index(int? id, int page){}
So you can use www.mysite.com/admin/?id=1&page=12
So, I am trying to submit a form on a List Page(http://example.com:3480/List) which is actually a Search implementation. So far I have done this:
index.cshtml
#using(Html.BeginForm("Search","ListController"))
{
<input id=query type=text name=query />
<input id=btnsearch type=submit value=Search />
}
ListController.cs
[HttpPost]
public ActionResult Search(FormCollection collection)
{
Response.Write("We are here");
// Get Post Params Here
string var1 = collection["query"];
Response.Write(var1);
return View();
}
Global.asax
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Details",
"Details/{id}/{orderid}",
new { controller = "Details", action = "Index", id = UrlParameter.Optional, orderid = UrlParameter.Optional }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional} // Parameter defaults
);
}
Upon Clicking it goes to http://example.com:3480/ListController/Search which seems fine.
Now I guess I need to define route in Global.aspx but not sure. What I want is to show result in same View file instead of creating a new one.
At this moment I am unable to get into Search method after POSTing form
Assuming you are currently just using the default route, the reason you are not reaching the action method is that the "Controller" suffix on your route is implicit - it shouldn't be part of your URL.
#using(Html.BeginForm("Search","List"))
Additionally, regarding:
What I want is to show result in same View file instead of creating a new one.
You can easily return a specific view from any controller action by specifying the name of the view in the call to the View method:
return View("Index");
I'm quite stuck I might say dispite all other posts found on the site.
My solution has two areas Front and Back, and I don't want to use the default root controllers and views provided by default.
My FrontAreaRegistration.cs is like :
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Front",
"Front/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
, new[] { "Show.Areas.Front.Controllers" }
);
}
My BackAreaRegistration.cs is like :
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Back_default",
"Back/{controller}/{action}/{id}",
new { controller = "Account", action = "LogOn", id = UrlParameter.Optional }
, new[] { "Show.Areas.Back.Controllers" }
);
}
And Global.asax like :
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
Getting folowing exception :
Multiple types were found that match the controller named 'Home'. This
can happen if the route that services this request
('{controller}/{action}/{id}') does not specify namespaces to search
for a controller that matches the request. If this is the case,
register this route by calling an overload of the 'MapRoute' method
that takes a 'namespaces' parameter.
The request for 'Home' has found the following matching controllers:
Show.Areas.Front.Controllers.HomeController
Show.Areas.Back.Controllers.HomeController
Problem is I can't reach the Home controller from Front area. Even if correct namespace added to context.MapRoute method overload ...
Any help will be appreciated.
The error is raised because you don't specify Area name in your request. Because of that "Default" route (from Global.asax) is matched for request and tries to search "Index" action of "Home" controller. As far as there two matches (for both areas) exceptions is thrown.
There are few ways to fix this. One possible is to modify Global.asax:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new[] { "Show.Areas.Front.Controllers" }
).DataTokens.Add("Area", "Front");
But in this case "Default" route will work for Front area only.
The following rout registration works for my asp.net MVC application
routes.MapRoute("TrackingChannels", "TrackingChannels/{action}",
new { controller = "TrackingChannels", action = "Index" });
When I change it to catch this url,
I get resource not found error
for localhost:85\dis\TrackingChannels
routes.MapRoute("TrackingChannels", "Dis/TrackingChannels/{action}",
new { controller = "TrackingChannels", action = "Index" });
How can I fix this?
Alright, I need to go out so I'll post this now as I don't know how long I'll be.
I setup a default MVC 3 project and changed the routing to match your case.
Global.asax:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"TrackingChannels",
"Dis/TrackingChannels/{action}",
new { controller = "TrackingChannels", action = "Index" }
);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Added a TrackingChannelsController:
public class TrackingChannelsController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Test()
{
return View();
}
}
I deliberately added the Test action to see if /dis/trackingchannels/{action} would also work. Then I added a couple of views which resulted in the following project structure:
Finally, here's the results of specifying the URLs in the browser:
First with /dis/trackingchannels:
Second with /dis/trackingchannels/test:
The only thing I can say without seeing your project is to double check the URL is matching the correct route. To do that you can use Phil Haack's RouteDebugger.