Hoping for some help after reading into MVC routing and not coming up with the answer myself.
I have the following routes registered:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
null,
"YourFeedback/Article/{resourceId}",
new { controller = "YourFeedback", action = "Index", contentTypeId = new Guid(ConfigurationManager.AppSettings["ArticleLibraryId"]) });
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
I have the following ActionLink in an aspx view:
<%=Html.ActionLink("Your Feedback", "Article", "YourFeedback", new
{
resourceId = Model.ContentId.ResourceId
}, new { #class = "yourFeedback" })%>
My understanding of MVC routing is that this would render a anchor link with href of "/YourFeedback/Article/101" where 101 comes from Model.ContentId.ResourceId.
Yet the anchor link href is rendered as "YourFeedback/Article/resourceId=101".
Any ideas where I'm going wrong?
Thanks in advance.
This is because your actionlink will match the second route and not the first. The reason is that you have some strange default values in your first route. You have set the controller to "YourFeedback" and the action to "Index". That means that you will have to set that in your actionlink as well if you want to match that route.
To match the route you will have to use this actionlink:
<%=Html.ActionLink("Your Feedback", "Index", "YourFeedback", new
{
resourceId = Model.ContentId.ResourceId
}, new { #class = "yourFeedback" })%>
Or change the route.
Related
routes.MapRoute(
"GetProductBySubcategory", // Route name
"{category}/{SubCategoryName}", // URL with parameters
new { controller = "Product", action = "GetProductBySubCategoryName"
});
Here is my route that is working fine.
But when is am using the url Like localhost:12345/Admin/Login then it use the route url and redirect to GetProductBySubCategoryName action.
actually i am using #Url.RouteUrl() method to call the route. which is working good. But when other url like Account/Register means which have only two keys redirect to action given in the route.
I am using other routes
All routes that i am using is as follow:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"GetProductByCategory",
"{category}",
new { controller = "Product", action = "GetProductByCategoryName" }
);
routes.MapRoute(
"GetProductBySubcategory",
"{category}/{SubCategoryName}",
new { controller = "Product", action = "GetProductBySubCategoryName" }
);
routes.MapRoute(
"ProductByNameRoute",
"{category}/{subcategory}/{style}/{productName}",
new { controller = "Product", action = "ProductDetails" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
this is my route.config file.
i am not able to call sign in link, login link the all goes to route url.
acctually i want to route url like if i click on getproductbycategory url will domain/category and if i click on getproductbysubcategory url will be domain/category/subcategory.
Please help me to find the solution.
If you are working on MVC 5 you can easily achieve this by attribute routing, without modifying the route table.
Attribute Routing in MVC 5
I am using the standard MVC template in VS 2013.
With the default set up, http://website/ will be routed to website/Home/Index.
How do I route all "actions" directly under website root url, eg http://website/xxx, to show the same content as http://website/Home/xxx? For example, how do I make http://website/About to execute the About action in the Home controller? If possible, the solution shouldn't be a Http redirect to http://website/Home/About because I don't want to show the "ugly" Home/ in the url.
I couldn't find an answer to this that covered all issues one would face with a public facing website without being a pain to upkeep while still maintaining flexibility.
I ended up coming up with the following. It allows for use of multiple controllers, doesn't require any upkeep, and makes all URLs lowercase.
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
//set up constraints automatically using reflection - shouldn't be an issue as it only runs on appstart
var homeConstraints = #"^(?:" + string.Join("|", (typeof(Controllers.HomeController)).GetMethods(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.DeclaredOnly).Select(x => (x.Name == "Index" ? "" : x.Name))) + #")$";
//makes all urls lowercase, which is preferable for a public facing website
routes.LowercaseUrls = true;
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
//maps routes with a single action to only those methods specified within the home controller thanks to contraints
routes.MapRoute(
"HomeController",
"{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new { action = homeConstraints }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
you can try out like the following one
routes.MapRoute(
name: "MyAppHome",
url: "{action}/{wa}",
defaults: new { controller = "Home", action = "Index", wa = UrlParameter.Optional, area = "Admin" },
namespaces: new string[] { "MyApp.Controllers" }
).DataTokens = new RouteValueDictionary(new { area = "Admin" });
Here, you may notice that the Home controller is hardcoded and is no longer to be supplied in the request. you can also make use of the RouteDebugger to play with routes.
HTH
I have a below setup in the controller for Public facing web page
Company -> About -> Partners ( which i want to be accessed as Company/About/Partners )
Action Method
public about(string category)
{
ViewBag.Category = category;
return View();
}
Generation of the link is done as below which is giving me the wrong URL
#Html.ActionLink("Partners & Investors", "About", "Company",new { Category = "Partners" },null)
Wrong Url
Company/About?Category=Partners%20and%20Investors
So the question is how does one generate the correct url that i wanted. What should i do ?
Urls will be generated automatically when you create new route and put it on correct position.
Add
Something like this:
routes.MapRoute(
"Category",
"Company/About/{category}",
new { controller = "Company", action = "About", category = "default" }
);
// default
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Also look at this link: Advanced Routing
My current Routing rules are
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Admin", // Route name
"Admin/{controller}/{action}/{id}", // URL with parameters
new { controller = "Admin", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
I have several controllers that can only be accessed by the Admin. Currently I have a menu at:
/Admin/Index
Which lists a bunch of action links. Right now clicking any of those links redirects like this example:
/News/Index
But I need it to be like:
/Admin/News/Index
This current setup sort of works, but links on my homepage are being caught by the wrong rule and are going to, for example /Admin/Article/1 when they should be just /Article/1
I've searched StackOverflow for the answer, and found some that come close - but I still don't understand routing well enough to make use of their answers. Any assistance is appreciated.
EDIT
Here are a collection of links from the homepage that are being caught by the routing rules incorrectly
<div id="menucontainer">
<ul id="menu">
<li><%: Html.ActionLink(" ", "About", "Home", null, new { ID = "AboutMHN" })%></li>
<li><%: Html.ActionLink(" ", "Products", "Home", null, new { ID = "Products" })%></li>
<li><%: Html.ActionLink(" ", "HubLocator", "Home", null, new { ID = "HubLocator" })%></li>
<li><%: Html.ActionLink(" ", "ResellerProgram", "Home", null, new { ID = "ResellerProgram" })%></li>
<li><%: Html.ActionLink(" ", "ResellerLogin", "Home", null, new { ID = "ResellerLogin" })%></li>
<li><%: Html.ActionLink(" ", "ContactUs", "Home", null, new { ID = "ContactUs" })%></li>
</ul>
</div>
Also, my Admin controller just has an index action. I have controllers for all of the other 'Admin' pages, for example my NewsController has actions for index, create, edit, delete, for listing all the news articles, and performing crud operations. Am I structuring this incorrectly?
My AdminController.cs
[Authorize(Roles = "Administrator")]
public class AdminController : Controller
{
//
// GET: /Admin/
public ActionResult Index()
{
return View();
}
}
The Admin/Index this returns contains a menu with ActionLinks just like
<li><%: Html.ActionLink("News Articles", "Index", "News") %></li>
My NewsController.cs has Actions for performing CRUD operations. I would like the url to be
Admin/News/Edit/5
Instead of
News/Edit/5
Flip the two:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Admin", // Route name
"Admin/{controller}/{action}/{id}", // URL with parameters
new { controller = "Admin", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
If that doesn't work, add the code for the News menu links to your question.
The mapping is from top to bottom, the first route that can apply will be used. In your case you have Admin route under Default. Since Default can be used it will, therefore you should place Admin route above Default. The problem with that is that all will use that route. You need to be a bit more specific, perhaps you should remove {controller} so that only Admin actions will use that route. Need more info to better advise.
I needed to use Areas.
See: http://elegantcode.com/2010/03/13/asp-net-mvc-2-areas/
I created a new Area called Admin, renamed my AdminController.cs to MenuController.cs and placed all of the required controllers and views inside of the Admin area folder. Inside the Admin area folder there is a file called AdminAreaRegistration.cs which contains
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Admin";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { controller= "Menu", action = "Index", id = UrlParameter.Optional }
);
}
}
I had to add in the controller = "Menu" so that when you navigate to /Admin it will take you to /Admin/Menu/Index by default. Now any of my controllers in the area folder are accessible like /Admin/News/Edit/5 and so forth. Thanks for your attempts, I should have been more clear that I am an absolute MVC noob and didn't know about Areas to begin with.
for example you have custom route like this:
CustomerOrder/{action}/{id}/customerid={customerid}
the url became like this:
CustomerOrder/Create/customerid=1
how can you get the customerid and use it in the view?
<%= Html.MenuItem("Back to List", "Index", new { customerID = ???????? })%>
The equals sign is going to confuse url parsers since it has special meaning.
If you were to change your route to:
routes.MapRoute("CustomerOrder", "CustomerOrder/{action}/{id}",
new { controller = "Order", id = "" });
Then the following view code
<%= Html.MenuItem("Back to List", "Index", new { customerID = 5 })%>
Would create a link to:
CustomerOrder/Index/?customerid=5
which would work just fine.
Note
Given your current routing configuration, you would get the exact same results by deleting your CustomerOrder route since it is broken and you get the desired results from the default route.
Heres the code in Global.ASAX
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("CustomerOrders", "CustomerOrder/{action}/{id}/customerid={customerid}",
new { customerid= "{customerid}", controller = "CustomerOrder", action = "Index", id = "" });
routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" });
}
I'm new to MVC but I'm thinking the controller gets a customerid parameter and that could be passed to the View (via ViewData), no?