auto add route parameter to url - asp.net-mvc

i have 2 urls on one page: http://host/home/list and http://host/home/list/1. if i click on second url then first url renders with param 1, so url1 equals ulr2 (url1 = http://host/home/list/1 and url2=http://host/home/list/1)
i use such code
<%= Html.ActionLink("link", "DesignerFiles", "Home", null, null)%> url1
<%= Html.ActionLink("link", "DesignerFiles", "Home", new { id = 1} , null)%> url2
what the problem?

I had a simliar issue with sub level and tertiary navigation elements. IE - a link that should go to /Home/About from the /Home/About/People would append /People to the first link. I used the following method to get this to work correctly:
<%= Html.ActionLink("Link", "About", "Home", new with {.section = nothing}, nothing%>
<%=Html.ActionLink("Link2", "About", "Home", new with {.section = "People"}, nothing%>
That seemed to force the ActionLink to not include the additional parameter that was in the current context of my view. Side note, I changed the dafault {controller}/{action}/{id} to {controller}/{action}/{section} - which is why you see section in my route values.

Related

ActionLinks reverting to querystring params when matching a route that does not contain that param

I'm trying to achieve this goal of changing my apps routes to look like this:
hxxp://host/MyController/Widgets/3/AddWhatsit
The view for this route would help a user add a Whatsit to Widget 3.
Similarly, I would expect the route to create a new Widget to be:
hxxp://host/MyController/Widgets/Create
I've created separate routes to try and facilitate this. They are:
routes.MapRoute("DefaultAction",
"{controller}/{action}",
new {controller = "Home", action = "Index"});
routes.MapRoute("Default",
"{controller}/{id}/{action}",
new {controller = "Home", action = "Index", id = UrlParameter.Optional});
The problem I'm having is that when I browse to the Index page for Widgets (/MyController/Widgets, matching the "DefaultAction" route) Any ActionLinks that would introduce a new url parameter that's not part of that route gets turned into a querystring value. So, for example, the edit link for Widget 3 would render as:
Widget/Edit?id=3
instead of (what I would prefer):
Widget/3/Edit
I guess I understand that I'm messing things up by not putting my (optional) id param at the end of the route.
Should I suck it up and just leave id at the end of the route?
It is possible to achieve this. To get anchor link looking like /Home/1/Index, set routes like:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Custom",
url: "{controller}/{id}/{action}"
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
And then, in the View:
#Html.ActionLink("Here", "Index", "Home", new { id = 5 }, null)
And you get link rendered like this:
Here
Quirk is to constrain custom route. I removed defaults in this case, they do not make sense. And order of routes, of course.
I believe you need to change the order of your routes. Remember, that MVC looks down the route list and picks the First matching route. Your second route with the ID parameter is more specific and as such, should come first in your routing table.
Even though you have specified an ID parameter in your ActionLink, you have also specified a controller and an action. Therefore, the first route is being chosen by the RoutingEngine.
Lastly, remove the optional parameter for the ID attribute. Since you want that route to be chosen when you have an Id, then you do not want that to be an optional parameter, you want it to be required to match that route.
routes.MapRoute("Default","{controller}/{id}/{action}",
new {controller = "Home", action = "Index"});
routes.MapRoute("DefaultAction", "{controller}/{action}",
new {controller = "Home", action = "Index"});

asp.net mvc - Using multiple URLs to the same action

I have a controller called TaskListsController with an action called Edit.
The Edit action accepts a nullable int parameter. If it receives null, it adds a TaskList. If it receives an int, it edits the TaskList with the same ID. The logic is almost identical in each case.
I would like to configure my routing in such a way that the URL 'TaskLists/Add' maps to the Edit action with null as the parameter, and the URL 'TaskLists/Edit/{id}' maps to Edit and passes it the ID in the URL.
I can get this to work from the point of view of entering URLs in the browser and having them routed to the action correctly, but where it's falling down is where the system generates URLs from Html.ActionLink.
I am generating 'Add' links using:
Html.ActionLink("Add task list", "Edit", "TaskLists")
And I'm generating 'Edit' links using:
Html.ActionLink(taskList.Name, "Edit", new { Id = taskList.Id })
..where taskList is an instance of the TaskList class.
If I use this routing:
routes.MapRoute(
"TaskLists/Add", // Route name
"TaskLists/Add", // URL with parameters
new { controller = "TaskLists", action = "Edit" });
routes.MapRoute(
"TaskLists/Edit/{id}", // Route name
"TaskLists/Edit/{id}", // URL with parameters
new { controller = "TaskLists", action = "Edit", id = UrlParameter.Optional });
...the 'Add' link is generated correctly ('TaskLists/Add') but the 'Edit' link comes out 'TaskLists/Add?Id=1'.
If I put the routing commands the other way around:
routes.MapRoute(
"TaskLists/Edit/{id}", // Route name
"TaskLists/Edit/{id}", // URL with parameters
new { controller = "TaskLists", action = "Edit", id = UrlParameter.Optional });
routes.MapRoute(
"TaskLists/Add", // Route name
"TaskLists/Add", // URL with parameters
new { controller = "TaskLists", action = "Edit" });
...then the 'Edit' links are generated correctly ('TaskLists/Edit/x'), but the 'Add' links comes out 'TaskLists/Edit'.
Is there a way I can have my cake and eat it?
Using named routes (Html.RouteLink("linkText", "routeName")) could be a cleaner way of defining this, as then you're dealing with a clean route in the view also. This would also mean that you will hit the correct route every time without worry.
Update the Name parameter on your routes accordingly, then add the following to your view:
Html.RouteLink("Add task list", "NewTaskList")
and
Html.RouteLink(taskList.Name, "EditTaskList", new { Id = taskList.Id })

MVC3 routing issue with nullable parameter

I have an odd issue. I have a controller action which takes a couple of optional parameters
Function Index(sectionID As Integer?, title As String) As ActionResult
Return View()
End Function
I then have added a specific route for this action method so that we get pretty urls for this page
routes.MapRoute( _
"By_Section", _
"home/{sectionID}/{title}", _
New With {.controller = "Home", .action = "Index", .sectionID = Nothing},
New With {.sectionID = "\d+"}
)
This all works. However, when I am on a page where the sectionID is set (for example http://localhost/home/index/1/test), the following piece of code produces an odd output.
<%= Url.Action("Index", "Home")%>
Instead of showing http://localhost/home/index as you might expect, it shows http://localhost/home/index/1/test. So it appears it is picking up the sectionID and title from the current url and automatically inserting them into the Url.
How can I prevent this from happening?
Thanks
James
Yes, this is expected behaviour, the routing system will reuse parameter values from the current request if you haven't provided a new value explicitly. The best option when rendering links is to specify explicit values for all of your routing parameters.
<%= Url.Action("Index", "Home", new { sectionID = (int?)null }) %>

How to pass query string parameter in ActionLink in MVC

I am having following action link:
<%= Html.ActionLink("Check this", "Edit", "test",
new { id = id }, new { style = "display:block" })%>
How do I include data=name as query string. Some thing like this:
link?data=name
4th parameter of Html.ActionLink can have any number of properties:
<%= Html.ActionLink("Check this", "Edit", "test",
new { id = id, data=name }, new { style = "display:block" })%>
These properties are inserted into URL based on routing, but if the property name cannot be matched into any route it is added as URL GET parameter.
So if you have standard route {controller}/{action}/{id}, you will get the URL:
test/Edit/[id]?data=[name]
from the above code.
Pass Query String By this way
#Html.ActionLink("Delete Record", "Home", "Delete", new { id=Id},null)
By above code you will get the url like(Suppose Id=1): /Home/Delete/1
and if you want to add more parameters to query string then:
#Html.ActionLink("Delete Record", "Home", "Delete", new { id=Id, Name=name},null)
By above code you will get the url like(Suppose Id=1 and Name=India) :
/Home/Delete/1?Name=India
I got tired of banging my head against a wall with the html.actionlink. Works great when you just want to route it against straightforward routing calls, but absolutely refuses to cooperate when you want to add a simple querystring at the end.
I don't an ID at then end, I want to be able to add some kind of actual Querystring with the "?".
So anywhere I needed a Querystring I switched to using the url.action inside the anchor tag.
<a href='#url.action("Action","route")?Parameter=Value' >Text for Link Name</a>
At least it works and I can stop getting headaches over something that should have been a very simple task. Someone needs to get their heads out of their butts and make the ActionLink work properly for Querystrings in the MVC routing.
I know this is kind of old question but.
In case the below code doesn't generate the <a href="/?param=value" />.
<%= Html.ActionLink("Text", "Action", "Controller", new { param=value }, null)%>
I would advice checking whether you action has at least one [Route] attribute (I used [Route("/")] for example).
Hope it helps.

ASP.NET MVC Url.Action routing error

I've been using this some while now, but I can't seem to figure out, where could be mistake in this simple code:
<a href="<%= Url.Action("Page", new { page=(Model.PageIndex + 1) }) %>" >a</a>
With this routing table:
routes.MapRoute(
"Paging",
"Home/Page/{page}",
new { controller = "Home", action = "Index" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
And of course this method
public ActionResult Index(int? page)
I am getting instead of expected address http://localhost:58296/Home/Page/1 the one http://localhost:58296/Home/Page?page=1
When using
<%= Html.RouteLink("a", "Paging", new { page=(Model.PageIndex+1) }) %>
it works.. Please, where is my mistake? I want image link, so if there is a way to insert it into Html.RouteLink, I would appriciate that info too.
Thanks in advance.
There's a bunch of items to cover here for you to fully understand what's happening. Sorry, this will be a bit long.
routes.MapRoute(
"Paging",
"Home/Page/{page}",
new { controller = "Home", action = "Index" }
);
First, this is the route you want to hit. You do not include the action route parameter, '{action}', in the route path. The only action this route can possibly take is the value you have specified as the default action value "Index".
<a href="<%= Url.Action("Page", new { page=(Model.PageIndex + 1) }) %>" >a</a>
Second, in your link you are setting an action of Page. The route you are expecting does not accept action as a parameter and the only action it is aware of is Index. When Url.Action looks for possible routes in your route table, it will skip the route you want because that route does not accept an action of Page. The default route is valid though because you are implicitly supplying a controller, Home, explicitly supplying an action, Page, allowing the framework to supply a default for id, string.Empty, and any other parameters are tacked on as query parameters, page.
When you changed the Url.Action to "Index", the Url.Action method inspected the routes table and found the route with the action of Index specified for the Home controller with a parameter of page and everything is happier.
Hope that helps and isn't too confusing.
I don't know why, but
<%= Url.Action("Index", new { page=(Model.PageIndex + 1) }) %>
works and it displays and directs to /Home/Page/1 . If someone could explain it to me, I would be gratful.

Resources