I have a service in my website that loads content blocks from an external provider, from which users are are able to click links and navigate.
My routing needs to be able to handle these by calling my home controller with the request path.
For example, the url they will use to navigate will be
www../shop/hire/category/subcategory/subsubcategory/....
and if they're after a specific product:
www../shop/hire/category/subcategory/subsubcategory...?product=ABC
the constant in that, would be /shop/hire/ with the categories changing based on where you are, and the product if they have found what they are actually after.
The problem I've got, is when a link with a path like that is clicked in my application, rather than using the HomeController so I can parse the request, and call the service with the appropriate URL, I just get a 404.
I've tried adding the route:
routes.MapRoute(
name: "Category",
url: "shop/hire/{categories}/{product}",
defaults: new { controller = "Home", action = "Index", categories = UrlParameter.Optional, product = UrlParameter.Optional }
);
but this doesn't seem to have had any effect.
Try using a catch all route
routes.MapRoute(
name: "Category",
url: "shop/hire/{*categories}",
defaults: new { controller = "Home", action = "Index" }
);
and in your action you can parse the value to get your categories and product
public ActionResult Index(string catagories) { ... }
Related
I am writing a URL Shortener application.
When someone enters root.com/whatever, they are redirected to a configured URL.
I managed to create a global route which will catch the paths after the root ("whatever" above) and execute the corresponding redirection successfully.
My problem and question is this:
The admin interface is at root.com/admin and when I try to access that, I get the global controller. How do I make an exception to the global controller for "admin"?
Here is what I have in my route config right now:
routes.MapRoute(
name: "Admin",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Admin", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Global",
url: "{suffix}",
defaults: new { controller = "Home", action = "Index", suffix = UrlParameter.Optional }
);
For the first route, I also tried:
routes.MapRoute(
name: "Admin",
url: "admin/{action}/{id}",
defaults: new { controller = "Admin", action = "Index", id = UrlParameter.Optional }
);
And I also tried putting it second in the file.
I don't know if this will help you, but take a look at this stack overflow posting: ASP.Net MVC: Routing issue which throwing exception
This person reduced the more specific route and it worked for him.
I'm currently using HashRouter and it works really well. However I would like to be able to use the # on sub routes as well for linking to paragraphs. For example /details#Summary. As a benefit I will also get cleaner URLs and if needed I can get some SEO.
Works and gives correct results on refresh/direct link.
<HashRouter>
<App />
</HashRouter>
Works but gives 404 on refresh/direct link.
<BrowserRouter>
<App />
</BrowserRouter>
I understand that the problem here is my routing in .Net and I need to change it. What do I need to do? I have a default route but it does not get hit.
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
First remove the standard routes.MapRoute that is shown above and then add this:
routes.MapRoute("Client", "{*anything}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional });
Now any route will render your default action.
Optional:
If you have a controller with attribute routing, example:
[RoutePrefix("Home")]
public HomeController : Controller {
//GET Home/Index
[HttpGet]
[Route("Index")]
public ActionResult Index() {
return View();
}
}
You also need to add:
routes.MapMvcAttributeRoutes();
The thing is that when you change that, asp.net keeps trying to match a route from for details.
What you need to do is create a route that matches all paths, so that it returns the default one, eg: home/index
This is the route I use:
routes.MapRoute(
"Default",
"{*url}",
new { controller = "Home", action = "Index" });
That will give control to the browser to math the paths after '/'
I have a section of code in my view that displays an image and a URL on click of it. The URL is to a page on the site and directs it to that action method. I have the parameter as part of the URL, but in the Action method the parameter shows null.Hence I am redirected to the appropriate page but none of my functionalities inside the action method works.
Here is my code.
View:
<a class="lnkImage" href="#item.ImageURL" target="_blank"><img id="PrivateimgPreview" src="#item.ActualImage"/></a>
The value of #item.Image URL which I am getting from the database is http://localhost/TestProject/Home/DemoPage/b9f074fc-f86c-4866-a7b3-33e43025293f
And my action method in Home controller is
public ActionResult DemoPage(string blockId)
{
//Some code here
return(View);
}
This is my mapping route in Route.config
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
What am I missing?
I think that you need to either change 'blockId' to just 'id' or add the following route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{blockId}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
I would think it makes more sense to just rename your parameter in the signature rather than creating a nearly identical route for this action method.
We have several controllers we would like grouped in a subfolder (Admin) on our site. We would have the main pages be at the root level. But for these pages we would like to have our site path be something like this:
www.domain.com/Admin/{controller}/{action}/{id}
I've set the RouteConfig.cs file like this:
routes.MapRoute
(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Submission", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute
(
name: "Admin",
url: "Admin/{controller}/{action}/{id}",
defaults: new { controller = "SystemSecurity", action = "Index", id = UrlParameter.Optional }
);
I've set up one of the controllers like this:
[RoutePrefix("Admin/SystemSecurity")]
public class SystemSecurityController : Controller
{
private MkpContext _db = new MkpContext();
// GET: SystemSecurity
public ActionResult Index()
{
var roles = _db.Role.Select(r => r);
return View(roles.ToList());
}
}
In our solution the path to the controller is: \Controllers\Admin\SystemSecurityController.cs
The path to the view is: \Views\Admin\SystemSecurity\Index.cshtml
But we get the 'Resource cannot be found' error message.
I've also tried it with no RoutePrefix, and also with RoutePrefix("Admin").
If I put the view here: \Views\SystemSecurity\Index.cshtml
and navigate with this path: www.domain.com/SystemSecurity/Index
the page loads, so I know the controller and page are working.
What am I doing wrong?
I found out about MVC Areas. (http://www.philliphaydon.com/2011/07/mvc-areas-routes-order-of-routes-matter/)
By adding an Area to my project (Right click on Project's name, then Add - Area) I am able to better group my code.
Many of the pages I found either don't mention Areas or when the do, it's in passing, but they don't explain them. Hopefully this will help somebody else.
Currently I'am working on an MVC project in which I try to get a kind of dynamic routing working. My idea would be that i left the original route in the global.asax.cs, so this one will take care of every controller I make. For example the Contact and Account controllers.
Above controllers will have url's like
/Contact/
/Account/Logoff/ etc.
The second route I want to add is the one that is a kind of default route when there are no controllers found. In that case I assume this will be a route to a page or pagedetails.
Url's for example will be :
/BBQ/
/BBQ/Accesoires/
I have three routes added in the global.asax.cs which I think are correct. (Also in the correct order). Below I have added the routes:
routes.MapRoute(
"DefaultRoute", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Page", action = "Index", id = UrlParameter.Optional });
routes.MapRoute(
"DefaultPageRoute",
"{category}",
new { controller = "Page", action = "Index", category = UrlParameter.Optional });
routes.MapRoute(
"SecondLevelPageRoute",
"{category}/{subCategory}",
new { controller = "Page", action = "PageDetails", category = UrlParameter.Optional, subCategory = UrlParameter.Optional });
with this setup the calls to the controllers work fine, but to the pages like /BBQ/ it gives below error:
Server Error in '/' Application.
The resource cannot be found.
If I comment the first route and go the the /BBQ/ url it works like a charm. What am I overseeing in this routetable?
You put the default route first, so it is trying to go to a route defined by {controller = "BBQ", Action = "Index" }
That route should be the very last route. However, you need more detail in your routes. Just having a category route will cause problems.
For example, if this route is first
routes.MapRoute(
"DefaultPageRoute",
"{category}",
new { controller = "Page", action = "Index", category = UrlParameter.Optional });
Then a call to the URL /Contact/ will assume that you want to go to Page/Index/Contact not /Contact/Index/{id}. I would use a more specific route that signifies that you are browsing a category like:
routes.MapRoute(
"DefaultPageRoute",
"Category/{category}",
new { controller = "Page", action = "Index", category = UrlParameter.Optional });
So you will need to use a url www.mysite.com/Category/BBQ to view what you want, but I don't think that's all bad.