Let\'s say I have a class
public class ItemController:Controller
{
public ActionResult Login(int id)
{
return View(\"Hi\", id);
}
}
If you want to go all fancy-pants, here's how you can extend it to be able to do this:
@(Html.ActionLink<ArticlesController>(x => x.Details(), article.Title, new { id = article.ArticleID }))
You will need to put this in the System.Web.Mvc
namespace:
public static class MyProjectExtensions
{
public static MvcHtmlString ActionLink<TController>(this HtmlHelper htmlHelper, Expression<Action<TController>> expression, string linkText)
{
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);
var link = new TagBuilder("a");
string actionName = ExpressionHelper.GetExpressionText(expression);
string controllerName = typeof(TController).Name.Replace("Controller", "");
link.MergeAttribute("href", urlHelper.Action(actionName, controllerName));
link.SetInnerText(linkText);
return new MvcHtmlString(link.ToString());
}
public static MvcHtmlString ActionLink<TController, TAction>(this HtmlHelper htmlHelper, Expression<Action<TController, TAction>> expression, string linkText, object routeValues)
{
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);
var link = new TagBuilder("a");
string actionName = ExpressionHelper.GetExpressionText(expression);
string controllerName = typeof(TController).Name.Replace("Controller", "");
link.MergeAttribute("href", urlHelper.Action(actionName, controllerName, routeValues));
link.SetInnerText(linkText);
return new MvcHtmlString(link.ToString());
}
public static MvcHtmlString ActionLink<TController>(this HtmlHelper htmlHelper, Expression<Action<TController>> expression, string linkText, object routeValues, object htmlAttributes) where TController : Controller
{
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection);
var attributes = AnonymousObjectToKeyValue(htmlAttributes);
var link = new TagBuilder("a");
string actionName = ExpressionHelper.GetExpressionText(expression);
string controllerName = typeof(TController).Name.Replace("Controller", "");
link.MergeAttribute("href", urlHelper.Action(actionName, controllerName, routeValues));
link.MergeAttributes(attributes, true);
link.SetInnerText(linkText);
return new MvcHtmlString(link.ToString());
}
private static Dictionary<string, object> AnonymousObjectToKeyValue(object anonymousObject)
{
var dictionary = new Dictionary<string, object>();
if (anonymousObject == null) return dictionary;
foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(anonymousObject))
{
dictionary.Add(propertyDescriptor.Name, propertyDescriptor.GetValue(anonymousObject));
}
return dictionary;
}
}
This includes two overrides for Route Values
and HTML Attributes
, also, all of your views would need to add: @using YourProject.Controllers
or you can add it to your web.config <pages><namespaces>
This type use:
@Html.ActionLink("MainPage","Index","Home")
MainPage : Name of the text Index : Action View Home : HomeController
Base Use ActionLink
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>_Layout</title>
<link href="@Url.Content("~/Content/bootsrap.min.css")" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="container">
<div class="col-md-12">
<button class="btn btn-default" type="submit">@Html.ActionLink("AnaSayfa","Index","Home")</button>
<button class="btn btn-default" type="submit">@Html.ActionLink("Hakkımızda", "Hakkimizda", "Home")</button>
<button class="btn btn-default" type="submit">@Html.ActionLink("Iletişim", "Iletisim", "Home")</button>
</div>
@RenderBody()
<div class="col-md-12" style="height:200px;background-image:url(/img/footer.jpg)">
</div>
</div>
</body>
</html>
Html.ActionLink(article.Title, "Login/" + article.ArticleID, 'Item")
I think that Joseph flipped controller and action. First comes the action then the controller. This is somewhat strange, but the way the signature looks.
Just to clarify things, this is the version that works (adaption of Joseph's example):
Html.ActionLink(article.Title,
"Login", // <-- ActionMethod
"Item", // <-- Controller Name
new { id = article.ArticleID }, // <-- Route arguments.
null // <-- htmlArguments .. which are none
)
I think what you want is this:
Html.ActionLink(article.Title,
"Login", // <-- Controller Name.
"Item", // <-- ActionMethod
new { id = article.ArticleID }, // <-- Route arguments.
null // <-- htmlArguments .. which are none. You need this value
// otherwise you call the WRONG method ...
// (refer to comments, below).
)
This uses the following method ActionLink signature:
public static string ActionLink(this HtmlHelper htmlHelper,
string linkText,
string controllerName,
string actionName,
object values,
object htmlAttributes)
two arguments have been switched around
Html.ActionLink(article.Title,
"Item", // <-- ActionMethod
"Login", // <-- Controller Name.
new { id = article.ArticleID }, // <-- Route arguments.
null // <-- htmlArguments .. which are none. You need this value
// otherwise you call the WRONG method ...
// (refer to comments, below).
)
This uses the following method ActionLink signature:
public static string ActionLink(this HtmlHelper htmlHelper,
string linkText,
string actionName,
string controllerName,
object values,
object htmlAttributes)
arguments are in the same order as MVC2, however the id value is no longer required:
Html.ActionLink(article.Title,
"Item", // <-- ActionMethod
"Login", // <-- Controller Name.
new { article.ArticleID }, // <-- Route arguments.
null // <-- htmlArguments .. which are none. You need this value
// otherwise you call the WRONG method ...
// (refer to comments, below).
)
This avoids hard-coding any routing logic into the link.
<a href="/Item/Login/5">Title</a>
This will give you the following html output, assuming:
article.Title = "Title"
article.ArticleID = 5
. .
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
You might want to look at the RouteLink() method.That one lets you specify everything (except the link text and route name) via a dictionary.