In this article, you will learn the use of the Ajax.ActionLink helper and Html.ActionLink. I will compare both to show you how they differ. Okay, let's begin with Html.ActionLink.
Html.ActionLink
Html.ActionLink creates a hyperlink on a view page and the user clicks it to navigate to a new URL. It does not link to a view directly, rather it links to a controller's action. Here are some samples of Html.ActionLink.
If you want to navigate to the same controller's action method, use the one given below. Razor is smart enough to assume the first param is link text and the second param is the action method name, if it finds only two parameters.
@Html.ActionLink("Click here", // <-- Link text
"Index" // <-- Action Method Name
)
It's rendered HTML: <a href="/">Click here</a>
If you want to navigate to a different controller's action method, use the one given below. You can even avoid typing "null" for the route value and htmlArguments. Here also, razor will assume the first param as link text, the second param as the action method name and the third param as the controller name, if it finds three parameters.
@Html.ActionLink("Click here", // <-- Link text
"About", // <-- Action Method Name
"Home", // <-- Controller Name
null, // <-- Route value
null // <-- htmlArguments
)
It's rendered HTML: <a href="/Home/About">Click here</a>
If you want to navigate to the same controller's action method then use the one given below. Here razor will assume the first param is link text, second param is an action method and the third param is the route value. We can avoid typing "null" for the htmlArgument; that works fine.
@Html.ActionLink("Edit", // <-- Link text
"Edit", // <-- Action Method Name
new { id=item.CustomerID }, // <-- Route value
null // <-- htmlArguments
)
It's rendered HTML: <a href="/Home/Edit/187">Edit</a>
If you want to navigate to the same controller's action method then use the one given below. Here razor will assume the first param is link text, second param is the action method and the third param is the route value. Instead of typing "null" or avoiding the htmlAttribute, I am using the "class" attribute with "ui-btn" as the name.
@Html.ActionLink("Edit", // <-- Link text
"Edit", // <-- Action Method Name
new { id=item.CustomerID }, // <-- Route value
new {@class="ui-btn"} // <-- htmlArguments
)
It's rendered HTML: <a class="ui-btn" href="/Home/Edit/187">Edit</a>
What if one wants rendered HTML to be as given below that is an application-specific anonymous attribute:
<a class="ui-btn" data-val="abc" href="/Home/Edit/ANTON">Edit</a>
If you try to do it as given below, you will get the error:
The reason is that we can't use an anonymous property/attribute having a dash in the name. Use an underscore instead of a dash and MVC will automatically replace the underscore with a dash in the rendered HTML, here it is:
@Html.ActionLink("Edit", // <-- Link text
"Edit", // <-- Action Method Name
new { id=item.CustomerID }, // <-- Route arguments
new {@class="ui-btn", data_val="abc"} // <-- htmlArguments
)
That's how we work around in MVC for any anonymous property.
Note: You can notice that Html.ActionLink takes at least two parameters as Html.ActionLink(LinkText, ActionMethod).
Ajax.ActionLink
Ajax.ActionLink is much like the Html.ActionLink counterpart, it also creates the hyperlink <a href="">Click here</a> but when the user clicks it and has a JavaScript enabled browser, Ajax.ActionLink sends the asynchronous request instead of navigating to the new URL. With the Ajax.ActionLink we specify what controller's action method is to be invoked and also specify what to do with the response coming back from the action method.
Let's create an Ajax.ActionLink helper that will send an asynchronous request to the action method and will update the DOM with the result.
Step 1
At first we need an Ajax.ActionLink that will send the async request, so here we go:
<h2>Customers</h2>
@Ajax.ActionLink("Customer from Germany", // <-- Text to display
"Germany", // <-- Action Method Name
new AjaxOptions
{
UpdateTargetId="CustomerList", // <-- DOM element ID to update
InsertionMode = InsertionMode.Replace, // <-- Replace the content of DOM element
HttpMethod = "GET" // <-- HTTP method
})
@Ajax.ActionLink("Customer from Mexico", // <-- Text to display
"Mexico", // <-- Action Method Name
new AjaxOptions
{
UpdateTargetId="CustomerList", // <-- DOM element ID to update
InsertionMode = InsertionMode.Replace, // <-- Replace the content of DOM element
HttpMethod = "GET" // <-- HTTP method
})
<div id="CustomerList"></div>
@section scripts{
@Scripts.Render("~/Scripts/jquery.unobtrusive-ajax.min.js")
}
In the code above, you can see that I have created two Ajax.ActionLinks, one to display the list of customers from Germany and another to display the list of customers from Mexico, all will be called asynchronously. We have not specified which controller to access, so by default it will look in the same controller. Here is the generated HTML by both Ajax.ActionLink.
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#CustomerList" href="/Home/Germany">Customer from Germany</a>
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="replace" data-ajax-update="#CustomerList" href="/Home/Mexico">Customer from Mexico</a>
The unobtrusive jQuery uses the data-ajax prefix for JavaScript to invoke action methods on the server rather than intrusively emitting inline client scripts.
When we will click the link it will make a GET HTTP method call and the returned result will be updated to a DOM element by Id "CustomerList".
Always remember to place a reference of the jquery.unobtrusive-ajax.js library file after jquery-{version}.js file references, we can use bundling also. If you don't include the jquery.unobtrusive-ajax.js or do it incorrectly, then when you click the link to the view list of countries, an async result will be opened on the new browser tab.
Also, ensure that the unobtrusive JavaScript is enabled in your web.config (it should be by default).
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
Step 2
Now, let's go ahead and implement the "Germany" and "Mexico" action methods that will return a PartialView.
NorthwindEntities db = new NorthwindEntities();
public PartialViewResult Germany()
{
var result = from r in db.Customers
where r.Country == "Germany"
select r;
return PartialView("_Country", result);
}
public PartialViewResult Mexico()
{
var result = from r in db.Customers
where r.Country == "Mexico"
select r;
return PartialView("_Country", result);
}
So, in both of the PartialViewResult methods I have used a LINQ query that will filter records on country and then pass the results to a partial view page "_Country.cshtml". I have placed this file in the "Shared" folder so that any view can access it. Let's move on to see the partial view page "_Country.cshtml".
Step 3
I made this view page strongly typed by using @model and then iterated through the model data to create a nice tabular format.
@model IEnumerable<MvcActionLink.Models.Customer>
<table>
<tr>
<th>
@Html.DisplayNameFor(model => model.ContactName)
</th>
<th>
@Html.DisplayNameFor(model => model.Address)
</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.ContactName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Address)
</td>
</tr>
}
</table>
Now, you all set to run the application.