RouteUrl + RouteLink while keeping current query string values - c#

In ASP.net MVC I am using Url.RouteUrl & Html.RouteLink to create some links in my page.
Considering the following default route:
routes.MapRoute(
null,
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Using Url.RouteUrl(new { controller = "Products", action = "List", sort = "newest" }) will produce the URL /Products/List?sort=newest.
So far this is exactly what I want. What I'm not sure how to accomplish is the following. If I am currently on /Products/List?sort=newest. and I need to provide the user with a URL to change the number of products listed per page:
`/Products/List?sort=newest&pagesize=30`
How can I use Url.RouteUrl to generate the following URL so that:
If I am currently on a page that has sort=newest, it retains this value: /Products/List?sort=newest&pagesize=30
If I am currently on a page that doesn't have sort, it omits it: /Products/List?pagesize=30
For an example of what I mean, you can look at stackoverflow. If I look at questions and change to view featured questions, and then click on the page size at the bottom it will retain the sorting but then append the page size to the URL.

Url.RouteUrl(
new {
controller = "Products",
action = "List",
sort = Request["sort"],
pagesize = "30"
}
)
If this is invoked from /Products/List it will produce /Products/List?pagesize=30. And if it is invoked from /Products/List?sort=newest it will produce /Products/List?sort=newest&pagesize=30.

Related

How do I get a pretty URL when creating a link in a Razor View?

I'm asking how to do a link with #Url.Action in a Razor view to make a link like
Controller/Action/123
I already made #Url.Action("Action","Controller", new { #ViewBag.ID }) but it makes me a link like
Controller/Action?ID=123
How do I make a URL without the querystring in the razor view?
Try:
#Url.Action("actionname", "controllername", new { id = ViewBag.Id})
I think the problem is just that you haven't specified that the value in your route parameters collection is the "id". Of course, I'm assuming that you're using the default route configuration in RegisterRoutes.
Tip: you can also use Html.ActionLink() which saves you the trouble of creating an <a> tag yourself:
#Html.ActionLink("linkText", "actionName", "controllerName", new { id = ViewBag.ID }, null);
This will generate an <a> tag with the linkText and the same url as Url.Action() which you can see in Jeff's answer.
Note: don't forget to add null as the last parameter, otherwise it will use the wrong overload and use the anonymous type as htmlAttributes.
Use Url.RouteUrl(String, Object) and notUrl.Action()
Use the default route name.. which must be Default
so your code should be :
#Url.RouteUrl("Default", new {controller = "SomeControler", action = "SomeAction" , id = #ViewBag.ID })
Doing that will give you url as follows : SomeController/SomeAction/5 (assuming ID was 5)
This happens because of the by default the project mvc template contains a Default route as follows :
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
You can create more fancy urls if you wish or if you need more parameters, by adding more routes into routing table
here's the description : http://msdn.microsoft.com/en-us/library/dd505215(v=vs.108).aspx
#Url.Action("Action/" + #ViewBag.ID,"Controller")

#Html.Action MVC 4 with QueryString Parameters

I have a question related to the Html.Action in MVC 4
I want to pass some Querystring Variables with it to the Details view
The code I have now is
System.Text.StringBuilder MobileData = new System.Text.StringBuilder();
MobileData.AppendFormat("<a style=\"text-align:left;\" data-role=\"button\" onclick=\"window.location='" + #Url.Action("Taken_Detail", new { id = tk.ID }) + "';\" data- ajax=\"true\" data-icon=\"alert\"><span class=\"AgenItems\">{1:dd-MM-yyyy}</span>", tk.ID, tk.Datum);
The problem is he would redirect me to localhost/PROJECTNAME/Home/Taken_Detail/2
what I want is Home/Taken_Detail?id=2
what am I missing here I am just starting to learn MVC 4, Every tip is welcome.
This is because your routes contain the id parameter. Remove it from the routes and Url.Action will change the URL and add your parameter to the query string.
Example:
routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
The id parameter will be put after the last slash if you specify it with Url.Action.
If you remove it:
routes.MapRoute("Default", "{controller}/{action}",
new { controller = "Home", action = "Index" });
The resulting URL will have a query string containing the id.

The C# MVC 3 Routing want to add hard code word also in url

The C# MVC 3 Routing i have a controller name Category.
There are 2 Sub Method of the Controller
1)Index
2)Detail
now my detail routing URl coming like this "Category/name" ok but i also want to Add "category/Name-for-all" hard code "-for-all"
want to add this hard code how ?
routes.MapRoute(
"categorie", // Route name
"Category/{id}/{no}", // URL with parameters
new { controller = "Category", action = "details", id = "id",no=UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"categories", // Route name
"Category/{id}/{action}", // URL with parameters
new { controller = "Category", action = "action", id = "id" } // Parameter defaults
);
html page
<div class="grid_3" >
<a class="companyanchor" href="/category/#Model.name/">#Model.Name</a>
</div>
Its hard to understand your question, as I understand you asking about hard coded part of url? Something like this:
routes.MapRoute(null,
"{category}/Page{page}", // Matches /Football/Page567
new { controller = "Product", action = "List" }, // Defaults
new { page = #"\d+" } // Constraints: page must be numerical
);
I have not worked with MVC recently, but isn't this the answer?
routes.MapRoute("categories", // Route name
"Category/{id}"-for-all/{action}", // URL with parameters
new { controller = "Category", action = "action", id = "id" } // Parameter defaults
);
... not sure where "Name" comes from in your example.

ASP.NET MVC Routing using ID or action name

I have an ASP.Net application which has an area called 'Customers'. This area has a controller with the same name with a single method called Index.
I have the following route defined:
context.MapRoute(null,
"Customers/{controller}/{action}",
new { controller = "customers", action = "Index" }
);
This allows my to navigate to use the following URL to navigate to the index method on my Customers controller.
MyDomain/Customers
In my customer area I also have another controller called products. This has a number of methods that allow me to work with product entities (mostly auto-generated by Visual Studio at the moment).
With my current route I can navigate to the products controller using URL's like this:
MyDomain/Customers/Products (shows the index page of the products
controller) MyDomain/Customers/Products/Create (Shows a page to add
new products). MyDomain/Customers/Products/Details?id=1234 (Show the
product with the id of 1234)
Now what I want to be able to do is navigate to the details page with a much more user friendly URL such as:
MyDomain/Customers/Products/1234
I have defined a new route that look like this:
context.MapRoute(null,
"Customers/Products/{id}",
new { controller = "Products", action = "Details" }
);
The route is defined before the first route I demonstrated.
This allows me to navigate to the products page as I want, however I can no longer navigate to other methods on my products controller.
E.G. The following URL
MyDomain/Customers/Products/Create
Gives me the following error:
The parameters dictionary contains a null entry for parameter 'id' of
non-nullable type 'System.Int32' for method 'System.Web.Mvc.ViewResult
Details(Int32)'
If I change the order of the routes then I can navigate to all the methods on my products controller but my details URL reverts to the old format of having a query parameter.
If I update the route to look like this:
context.MapRoute(null,
"Customers/Products/{id}",
new { controller = "Products", action = "Details", id = UrlParameter.Optional }
);
Then I still get the same problem.
Can anyone tell me how to structure my routes to get the result I want? In summary:
If I navigate to the Customers area I want my URL to look like 'MyDomain/Customers'
If I navigate to the product details page I want my URL to look like "MyDomain/Customers/Products/1234".
If I navigate to any other product page I want my URL to look like 'MyDomain/Customers/Products/Create'
If the ID is always going to be an int then you can add a constraint to the route like this:
context.MapRoute(null,
"Customers/Products/{id}",
new {controller = "Products", action = "Details", id = UrlParameter.Optional},
new {id = #"\d+"} // Constraint to only allow numbers
);
Try something like this:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Products_Details",
"Customers/Products/{id}",
new { controller="Products", action="Details" },
new { id = #"\d+" }
);
context.MapRoute(
"Customers_default",
"Customers/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
Update: added constraint on route.
Explanation: The first route maps to your details page and forces the user to provide an id that has the format of numbers (the last parameter in the first MapRoute). If the id doesn't have the format \d+ it will not match the route and the default will be used. This will give you the following routes:
Customers\Products (index)
Customers\Products\1234 (details of 1234)
Customers\Products\Create (create page for products)
Customers\Products\Edit\1234 (edit page for 1234)
try this
context.MapRoute(
"Customers_Products",
"Customers/Products/{productId}",
new { controller = "Products", action = "Details", productId= UrlParameter.Optional }
);
context.MapRoute(null,
"Customers/{controller}/{action}",
new { controller = "customers", action = "Index" }
);
If you want to keep your existing routes, try doing this:
context.MapRoute(null,
"Customers/Products/{id}", // id is optional, so Customers/Products might reasonably return all products
new { controller = "Products", action = "Details", id = UrlParameter.Optional },
new {id = #"\d+"} // must be numeric if present
);
context.MapRoute(null,
"Customers/Products/{action}/{id}", // Id is optional, so this needs an action.
new { controller = "Products", action = "Details", id = UrlParameter.Optional }
// maybe the id is not numeric for all actions? I don't know so I won't constrain it.
);
context.MapRoute(null,
"Customers/{controller}/{action}", // Default Customers route
new { controller = "customers", action = "Index" }
);
The first two deal with a URL like /Customers/Products/... with one or two other parts and the last one deals with anything else starting with /Customers/

c# MVC routing with constants

I'm trying to generate an actionlink on a page that has the following route:
/{controller}/{type}/{sub}
The link needs to go to:
/{controller}/{type}/{sub}/new
How do I specify the "/new" portion of the url in an object or RouteValueDictionary so that I can pass it to the HTML.ActionLink?
StackOverflow won't let me answer my question for another 8hrs... so:
Thanks Justin.
Your suggestion worked, but for the sake of completeness, I discovered the method using the Html.ActionLink method:
You just need to specify the ActionName of the method that resolves that route. The framework appears to automatically work out that you want it on the same path as the current page.
So, if your route is:
routes.MapRoute(
"New", // Route name
"{controller}/{type}/{sub}"/new, // URL with parameters
new {controller = "DefaultController", action = "Create", id = UrlParameter.Optional});
The link is:
Html.ActionLink("Create New Page", "Create")
Approving Justin's method as it worked for me
As far as I know, the default implementations of ActionLink do not support this, so you have the following options:
Build it manually in this case (I am not in front of Visual Studio, so the syntax might be off a little)
<a href="#Url.Action(
"Controller", "Method", new { type = "type", sub = "sub" }));/new">
link text</a>
Or, you could create a new helper method to encapsulate something like this, if it happens often enough.
routes.MapRoute(
"New", // Route name
"{controller}/{type}/{sub}"/{new}, // URL with parameters
new {controller = "DefaultController", action = "Index", id = UrlParameter.Optional});
routes.MapRoute(
"Default", // Route name
"{controller}/{type}/{sub}", // URL with parameters
new {controller = "DefaultController", action = "Index"});
should be something like that
I would create the route as AD.Net suggests above and then use the Html.RouteLink extension helper to create the link, this way, if you ever decide to change the url/link it's automatically picked up by the routing engine
routes.MapRoute(
"New", // Route name
"{controller}/{type}/{sub}"/{new}, // URL with parameters
new {controller = "DefaultController", action = "Index", id = UrlParameter.Optional});
Html.RouteLink("Create New Page", "New")

Categories