ActionLink not working as expected in MVC 4 - asp.net-mvc

My html code is as follows
<ul>
#foreach (Department department in #Model)
{
<li>
#Html.ActionLink(department.Name, "Index", "Employee", new { id = department.DeptId }, null)
</li>
}
</ul>
After this when i hover on the link rendered on browser it shows http://localhost/demo/department/index
but when i change the index to Details in the actionLink parameter , then when i hover the link it shows http://localhost/demo/Employee/Details?id=2
Why in the first case instead of this http://localhost/demo/Employee/Index?id=2 , http://localhost/demo/department/index is coming.
I am very new to mvc. Please bear if this question is silly.
Please help me.
UPDATE
My route file is
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{name}/{id}",
defaults: new { controller = "Home", action = "Index", name = UrlParameter.Optional, id = UrlParameter.Optional }
);
routes.MapRoute(
name: "GetCountries",
url: "{controller}/GetCountries",
defaults: new { controller = "Home", action = "GetCountries" }
);
routes.MapRoute(
name: "GetEmployeeDetailsOnId",
url: "Employee/Details",
defaults: new { controller = "Employee", action = "Details" }
);
}
Solution
routes.MapRoute(
name: "GetEmployeeDetails",
url: "Employee/Index/{deptId}",
defaults: new { controller = "Employee", action = "Index", deptId = UrlParameter.Optional }
);
Added this in route and its working.

In the first case your parameters to ActionLink are
ActionName = "Details"
ControllerName = "Employee"
In the second case your parameters to ActionLink are
ActionName = "Index"
ControllerName = "Employee"
These parameters are then matched against your routes one by one.
In the first case there is a match against your third route (url: "Employee/Details")
In the second case there is a match against your first route (url: "{controller}/{action}/{name}/{id}")
For more information about how parameters are matched against routes, please see the link provided by #renjith in the comments: HTML.ActionLink method

Related

ASP.NET MVC Routing not working well

I am kinda blocked with some routing issues in my ASP.NET MVC application.
Let us assume I have 2 controllers which are:
TaskList Controller
Task Controller
I'm not sure if this is overkill or not but I am aiming to have URL's as follows:
For TaskList Controller:
localhost:xxxx/tasklist/Create
localhost:xxxx/tasklist/
localhost:xxxx/tasklist/Details/1
localhost:xxxx/tasklist/Edit/1
For Task Controller:
localhost:xxxx/tasklist/1/Task/Create
localhost:xxxx/tasklist/1/Task
localhost:xxxx/tasklist/1/Task/Details/11
localhost:xxxx/tasklist/1/Task/Edit/11
I have set up my routing as follows:
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
routes.MapRoute(
name: "TaskListRoute",
url: "TaskList/{action}/{tasklistid}",
defaults: new { controller = "TaskList", action = "Index", tasklistid = UrlParameter.Optional }
);
routes.MapRoute(
name: "TaskRoute",
url: "TaskList/{tasklistid}/{controller}/{action}/{taskid}",
defaults: new { tasklistid = UrlParameter.Optional, controller = "Task", action = "Index", taskid = UrlParameter.Optional }
);
Upon debugging the application, I am able to browse the TaskList controller with no problems but the moment I hit the following url on the Task Controller, I get a "Resource cannot be found" error:
http://localhost:xxxx/tasklist/1/Task
I have to type in the word "Index" like below in order for that page to work...
http://localhost:xxxx/tasklist/1/Task/Index
The method signature behind the above url is...
public class TaskController : Controller
{
// GET: Task
public ActionResult Index(int tasklistid)
{
//Some code here....
}
}
Any ideas where I wrong? Appreciate any advice.
Thanks in advance.
So after taking Nkosi's comment and NightOwl888's article into consideration all I had to do was modify the routing to look like the following:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "TaskRoute",
url: "TaskList/{tasklistid}/Task/{action}/{taskid}",
defaults: new { controller = "Task", action = "Index", taskid = UrlParameter.Optional }
);
routes.MapRoute(
name: "TaskListRoute",
url: "TaskList/{action}/{tasklistid}",
defaults: new { controller = "TaskList", action = "Index", tasklistid = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index" }
);
}
Basically did the following:
Adjust routing to be in following order:
TaskRoute
TaskListRoute
Default
In the TaskRoute, replaced '{controller}' with a literal like 'Task'
which is actually the name of the controller.
I hope this was the right thing to do.
Cheers

Change url asp.net mvc 5

routes.MapRoute(
name: "MyRoute",
url: "{Product}/{name}-{id}",
defaults: new { controller = "Home", action = "Product", name = UrlParameter.Optional , id = UrlParameter.Optional }
);
my routemap and i want my url in product action be like = http://localhost:13804/Wares/Product/name-id
but now is like =
http://localhost:13804/Wares/Product/4?name=name
When defining a route pattern the token { and } are used to indicate a parameter of the action method. Since you do not have a parameter called Product in your action method, there is no point in having {Product} in the route template.
Since your want url like yourSiteName/Ware/Product/name-id where name and id are dynamic parameter values, you should add the static part (/Ware/Product/) to the route template.
This should work.
routes.MapRoute(
name: "MyRoute",
url: "Ware/Product/{name}-{id}",
defaults: new { controller = "Ware", action = "Product",
name = UrlParameter.Optional, id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
Assuming your Product action method accepts these two params
public class WareController : Controller
{
public ActionResult Product(string name, int id)
{
return Content("received name : " + name +",id:"+ id);
}
}
You can generate the urls with the above pattern using the Html.ActionLink helper now
#Html.ActionLink("test", "Product", "Ware", new { id = 55, name = "some" }, null)
I know its late but you can use built-in Attribute Routing in MVC5. Hope it helps someone else. You don't need to use
routes.MapRoute(
name: "MyRoute",
url: "{Product}/{name}-{id}",
defaults: new { controller = "Home", action = "Product", name = UrlParameter.Optional , id = UrlParameter.Optional }
);
Instead you can use the method below.
First enable attribute routing in RouteConfig.cs
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
}
Then in WaresController
[Route("Wares/Product/{name}/{id}")]
public ActionResult Product(string name,int id)
{
return View();
}
Then to navigate write code like this in View.cshtml file
Navigate
After following above steps your URL will look like
http://localhost:13804/Wares/Product/productname/5

MVC Routing Issue when trying www.example.com/id

Let say I have a website www.example.com
the default routing looks like
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
);
Ok that works fine but let's say I want my site when I go to www.example.com/id to go to www.example.com/login/index/id
How would I configure/add routing for this, without breaking my other pages where I am actually trying to go to www.example.com/controller?
EDIT: Unfortunately id is a string so I do not have any concrete constraints that I can think of that would work. Think of maybe instead of the id I should have said companyname or sitename so the URL would look like www.example.com/companyname .
The only solution that I have come up with so far is adding a maproute for each one of my controllers like this
routes.MapRoute(
name: "Home",
url: "Home/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Settings",
url: "Settings/{action}/{id}",
defaults: new { controller = "Settings", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "companyname",
url: "{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
);
This will work but I have many controllers and if I add one in the future and forget to adjust the routes it will fail. Also, this is unlikely but if a companyname happens to the be same as one of my controller names it would also fail.
In controller you may redirect to another Controller/action:
public ActionResult yourAction()
{
return RedirectToAction("nameAction","nameController");
}
Did you tried adding this mapping first:
routes.MapRoute( name: "Custom", url: "{id}", defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional } );
That should work but keep in mind that routes are evaluated secuentially, so you will have to organize mappings in order to reach out all pages in your site.
For example, routes like www.example.com/Product could be redirected to /Login by mistake.
EDIT: You can add constraints, so if id is an int value, you can try with the following:
routes.MapRoute("Custom", "{id}",
new { controller = "Login", action = "Index" },
new { id = #"\d+" }
EDIT 2: Having ids as string values, the only solution I see is to manually add each controller as you said, or to add something like this:
routes.MapRoute(
name: "Default",
url: "app/{controller}/{action}/{id}",
defaults: new { controller = "Login", action = "Index", id = UrlParameter.Optional }
);
This way you don't need to update each route in the future.
Please try below routing
routes.MapRoute(name: "companylogin", url: "companylogin/{id}", defaults: new
{
controller = "Login",
action = "Index",
id = UrlParameter.Optional
});
routes.MapRoute(name: "default", url: "{controller}/{action}/{id}", defaults: new
{
controller = "Login",
action = "Index",
id = UrlParameter.Optional
});
Remove other controller specific routing. Now you can navigate to login using
url : - www.example.com/companylogin/{id} and all other url redirect default route.

How to give multiple routes in route.config file

public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Letter",
url: "{Home}/{Letter}/{ListId}",
defaults: new { controller = "Home", action = "Letter", ListId=1}
);
routes.MapRoute(
name: "words",
url: "{Home}/{words}/{WListId}",
defaults: new { controller = "Home", action = "words", WListId ="w1" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id= UrlParameter.Optional }
);
}
cshtml:
#Html.ActionLink("Home", "Index", "Home")
#Html.ActionLink("Letter", "Letter/1", "Home")
#Html.ActionLink("Words", "words/w1", "Home")
I am doing this in route.config and .cshtml respectively but every time it redirects me to the letter page even when i click on "words" or "home". When I click words or home it changes the url but does not change the view. Can any one suggest how to give multiples route in route.config file? What's wrong with this code ?
I'm completely revamping this because I think I now see what you are trying to do.
An ActionLink works as a helper to render an anchor element. So using
#Html.ActionLink("Link", "Action", "Controller")
helper, your page renders something in the form of:
Link
What you want then, is to write the proper controller and action values - you don't need routes for this. So in order to produce a link for Home/words/1, you can use the ActionLink helper (with the default route only) like this:
#Html.ActionLink("Words", "Words", "Home", new { WListId = "w1" })
This will produce:
/Home/Words/w1
and in your HomeController.cs, your action must look like:
public ActionResult Words(string WListId)
{
// whatever you want to do with WListId
return View();
}
and your View must be named Words.cshtml
The same goes for Letter as well. For this, all you need is the one Default Route that's already there.
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id=UrlParameter.Optional });

Map route in MVC to match a dot in URL

Is there a way to define route like this
routes.MapRoute(
name: "Language",
url: "{controller}/{action}.{culture}",
defaults: new { controller = "Home", action = "Index", culture = UrlParameter.Optional }
);
And be able to handle url like http://www.domain.com/Test/Create.us-US?
Yes, you can do it, but add route for url like http://www.domain.com/Test/Create without dot at the end
routes.MapRoute(
name: "Language",
url: "{controller}/{action}",
defaults: new { controller = "Home", action = "Index", culture = "us-US" }
);
No you can create route without with dot but you use the special caracter to the root. When we declare the method at the controler at that time you can specify the Action name define in the route
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "DashboardV1_bm", id = UrlParameter.Optional }
);
[HttpPost, ActionName("DashboardV1_bm")]
[ValidateAntiForgeryToken]
public ActionResult DashboardV1(int id)
{
Shift shift = db.Shifts.Find(id);
db.Shifts.Remove(shift);
db.SaveChanges();
this.AddToastMessage("Delete", "Record is successfully deleted !", ToastType.Success);
return RedirectToAction("Index");
}
For more information, please visit my blog:
http://programmingcode.in/create-routemap-to-access-new-created-view-page-in-mvc-dot-net/

Resources