asp.net mvc url routing: how to get particular link URL - asp.net-mvc

Given the following routing:
routes.MapRoute(
"RouteName", // Route name
"ViewFoo/{FooId}",
new { controller = "Foo", action = "View"}
);
corresponding to the following action method:
public ActionResult View(string fooId = null)
{
...blah...
}
Precisely how would I call Url.Action() to get the string '/ViewFoo/4'? Or do I need to modify the routing somehow?

Url.Action("View", "Foo", new { FooId = 4 })

Related

Default Route with parameters

I have created a controller and I don't want my default Action or View to be named Index. I created Action in TopicsController as below
[ActionName("Index")]
public ActionResult Topics()
{
var topic = new Topic();
return View("Topics", topic.GetTopics());
}
and it mached to URL xyz.com/Topics.
I tried to apply same philosophy to another controller, named, ModulesController but now I have got parameter.
[ActionName("Index")]
public ActionResult Modules(string id)
{
var topic = new Topic();
return View("Modules", topic.GetTopics());
}
but now it is saying
The resource cannot be found.
what I can do so that this action matches URL like xyz.com/Modules/aaaa?
To access the Url xyz.com/Modules/aaaa change the Action name for the Modules action to aaaa like this:
[ActionName("aaaa")]
public ActionResult Modules(string id)
{
var topic = new Topic();
return View("Modules", topic.GetTopics());
}
FYI - It would be better to avoid naming each action with the ActionName filter. At some point it would become difficult to manage. Instead manage the routes in the RouteConfig like this:
routes.MapRoute(
name: "Modules",
url: "{controller}/{action}/{id}",
defaults: new { controller="Modules", action="Modules", id=UrlParameter.Optional }
);
The following Urls will work for the above route:
xyz.com/Modules/aaaa
xyz.com/Modules/aaaa/123
xyz.com/Modules/aaaa?id=123
Update:
If you want 'aaaa' to be the parameter and want to access the action with xyz.com/Modules/aaaa (where 'aaaa' will be bound as the value to the Id variable) then add the following Route to the route table:
routes.MapRoute(
name: "Modules",
url: "Modules/{id}",
defaults: new { controller="Modules", action="Modules", id=UrlParameter.Optional }
);
Note the value of the Url above.

How to get the add the query string to actionLink?

The below link gives be the following url: http://localhost:11111/files/Details/3
#Html.ActionLink("Details", "Details", "mycontroller", new { id = item.id },null)
But I'm trying to have a url parameter like this http://localhost:11111/files/Details?id=3 or http://localhost:11111/files/Details.aspx?id=3
How do I get the actionlink to show the url like details?i=3
Here is my controller View:
public ActionResult Details(int? id)
{
...
return View();
}
Why would you like to see the parameter's name in the link?
Asp.Net MVC uses user-friendly URLs.
If you have created a project in Visual Studio using the MVC template, probally your routes, by default, are configured to interpret the parameter after the controller/action/ like the id.
So the id parameter's value in your action will be automatically replaced, by model binding, with the id number present in you URL.
The routing codes can be found under the RegisterRoutes method in the Global.asax file of our project.
I see a cookie already in the RegisterRoutes method.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults);
Using the MapRoute method above, we defined a new route.
Sample ;
public class HaberController : Controller
{
public ActionResult Listele()
{
// Listing codes will be written
return View("Listele");
}
public ActionResult Detay(string HaberId)
{
// Detail codes will be written
return View("Detay");
}
}
We go to our Global.asax file and edit it as follows.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"HaberListeleme",
"Haber",
new { controller = "Haber", action = "Listele" }
);
routes.MapRoute(
"HaberDetay",
"Haber/{id}",
new { controller = "Haber", action = "Detay" }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
}
If we do the routing as follows:
routes.MapRoute(
"HaberDetay",
"Haber/{*Id}",
new { controller = "Haber", action = "Detay" }
);
So if we write * by putting the character next to our parameter name, it will be sent to the related parameter of the Detail method in the Controller, no matter what it says after the News / url tab.
For example:
http://www.doguhanaydeniz.com/Haber/Turkiye/Guncel/34389
If a URL is requested as Turkey / current / 34389 will be sent as a parameter.

cant find Route when action has 2 params - Asp.Net MVC

I have a controller named Blog.
I have an action like this:
[Route("{code:int}/{title?}")]
public virtual ActionResult Index(int code, string title)
{
var postModel = _blogService.Get(code.ToUrlDecription());
return View(postModel);
}
I entered these urls, but all of them returned not found:
localhost:7708/Blog/index/12/post-title;
localhost:7708/Blog/index/12;
localhost:7708/Blog/12/post-title.
I tried to write a route like below, but the result was the same:
routes.MapRoute(
name: "showblogpost", url: "{controller}/{action}/{code}/{title}",
defaults: new {
controller = "Blog",
action = "Index",
title = UrlParameter.Optional
},
namespaces:new string[] { "Web.Controllers" }
);
One thing, you don't need to use both attribute [Route] on action and mapping route.
In your attribute [Route] you have specified only parameters, so route according to it should be localhost:7708/12
by route, specified in MapRoute it should be localhost:7708/showblogpost/12
What I suggest is - remove your attribute, name your route in MapRoute as you want to see in URL, and also you can remove "string title" parameter from action, as it's not used.

Asp.Net MVC 4 routing and link generation

In ASP.NET MVC 4 I wonder about the behavior, how links are generated for me.
Imagine a simple controller with 3 actions, each taking an integer parameter "requestId", for example:
public class HomeController : Controller
{
public ActionResult Index(int requestId)
{
return View();
}
public ActionResult About(int requestId)
{
return View();
}
public ActionResult Contact(int requestId)
{
return View();
}
}
and this registered route (before the default route):
routes.MapRoute(
name: "Testroute",
url: "home/{action}/{requestId}",
defaults: new { controller = "Home", action = "Index" }
);
I call my index-view using http://localhost:123/home/index/8
On this view, I render links for the other two actions:
#Html.ActionLink("LinkText1", "About")
#Html.ActionLink("LinkText2", "Contact")
Now I expect MVC to render this links including the current route-value for "requestId", like this:
http://localhost:123/home/about/8
http://localhost:123/home/contact/8
But i get these links (without the paramter):
http://localhost:123/home/about
http://localhost:123/home/contact
...but not for the index-action if i would specify one:
#Html.ActionLink("LinkText3", "Index")
What I want to avoid is to explicitly specify the parameters in this manner:
#Html.ActionLink("LinkText1", "Contact", new { requestId = ViewContext.RouteData.Values["requestId"] })
When I move the requestId parameter before the action paramter it works like I expect it, but I don't want to move it:
routes.MapRoute(
name: "Testroute",
url: "home/{requestId}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
Can someone explain me this behavior? How can I get this to work without specifying the parameter explicitly?
InController:
Replace the int to nullable int
For Routing:
set requestId as optional in routing
routes.MapRoute(
name: "Testroute",
url: "home/{action}/{requestId}",
defaults: new { controller = "Home", action = "Index" ,requestId=RouteParameter.Optional }
);

Enumerating ASP.NET MVC RouteTable route URLs

I'm trying to figure out how to enumerate the URLs of Routes in the RouteTable.
In my scenario, I have the following routes defined:
routes.MapRoute
("PadCreateNote", "create", new { controller = "Pad", action = "CreateNote" });
routes.MapRoute
("PadDeleteNote", "delete", new { controller = "Pad", action = "DeleteNote" });
routes.MapRoute
("PadUserIndex", "{username}", new { controller = "Pad", action = "Index" });
In other words, if my site is mysite.com, mysite.com/create invokes PadController.CreateNote(), and mysite.com/foobaris invokes PadController.Index().
I also have a class that strongly types usernames:
public class Username
{
public readonly string value;
public Username(string name)
{
if (String.IsNullOrWhiteSpace(name))
{
throw new ArgumentException
("Is null or contains only whitespace.", "name");
}
//... make sure 'name' isn't a route URL off root like 'create', 'delete'
this.value = name.Trim();
}
public override string ToString()
{
return this.value;
}
}
In the constructor for Username, I would like to check to make sure that name isn't a defined route. For example, if this is called:
var username = new Username("create");
Then an exception should be thrown. What do I need to replace //... make sure 'name' isn't a route URL off root with?
This doesn't fully answer what you are wanting to do by preventing users from registering protected words, but there is a way you can constrain your routes. We had /username url's in our site and we used a constraint like so.
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" }, // Parameter defaults
new
{
controller = new FromValuesListConstraint(true, "Account", "Home", "SignIn"
//...etc
)
}
);
routes.MapRoute(
"UserNameRouting",
"{id}",
new { controller = "Profile", action = "Index", id = "" });
You may just have to keep a list of reserved words, or, if you really want it automatic, you could possibly use reflection to get a list of the controllers in the namespace.
You can access the route collection with this. The issue with this approach is that it requires you to explicitly register all routes you want to be "protected". I still hold to my statement you'd be better off having a list of reserved keywords stored elsewhere.
System.Web.Routing.RouteCollection routeCollection = System.Web.Routing.RouteTable.Routes;
var routes = from r in routeCollection
let t = (System.Web.Routing.Route)r
where t.Url.Equals(name, StringComparison.OrdinalIgnoreCase)
select t;
bool isProtected = routes.Count() > 0;

Resources