Ajax.ActionLink and Html.ActionLink in MVC

In this post you will learn use of Ajax.ActionLink helper and Html.ActionLink. I will compare both to show you how it is different. Okay, let’s begin with Html.ActionLink.

Html.ActionLink

Html.ActionLink is used to create hyperlink on view page and user clicks it to navigate to new URL. It does not link to a view directly rather it links to a controller’s action. Here is some samples of Html.ActionLink:

If you want to navigate to same controller’s action method, use the one given below. Razor is smart enough to assumes first param as link text and second param as action method name, if 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 different controller’s action method, use the one given below. Even you can avoid typing ‘null’ for route value and htmlArguments. Here also, razor will assume first param as link text, second param as action method name, third param as controller name, if 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 same controller’s action method, use the one given below. Here razor will assume first param as link text, second param as action method, third param as route value. We can avoid typing ‘null’ for htmlArgument, 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 same controller’s action method, use the one given below. Here razor will assume first param as link text, second param as action method, third param as route value. Instead of typing ‘null’ or avoiding htmlAttribute, I am using ‘class’ attribute with ‘ui-btn’ as 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 which is application specific anonymous attribute:

<a class="ui-btn" data-val="abc" href="/Home/Edit/ANTON">Edit</a>

If you try to do as given below, you will get error:


Reason is, we can’t use any anonymous property/attribute having dash in their names. Use an underscore instead of 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, Html.ActionLink takes at least two parameters as Html.ActionLink(LinkText, ActionMethod).

Ajax.ActionLink

Ajax.ActionLink is much like Html.ActionLink counterpart, it also creates the hyperlink <a href=””>Click here</a> but when user clicks it and have the JavaScript enabled browser, Ajax.ActionLink sends the asynchronous request instead of navigating to new URL. With Ajax.ActionLink we specify what controller’s action method to invoke and also specify what to do with the response coming back from the action method.

Let’s create an Ajax.ActionLink helper which will send asynchronous request to action method and will update the DOM with result. Look at the demo GIF screen and then follow the steps from here to develop it.


You can see, I have selected some text and then clicked on links to prove it is really async link.

Step 1

At very first we need Ajax.ActionLink which 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 above code, you can see I have created two different Ajax.ActionLink, one will display the list of customers from Germany and another will display the list of customers from Mexico, all call will be asynchronously. We have not specified which controller to access so, by default it will look into 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 data-ajax prefix 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 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 wrongly, then when you click the link to view list of countries async result will be opened on new browser tab.

Also, make sure that 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 ‘Germany’ and ‘Mexico’ action methods that will return 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 PartialViewResult methods I have used linq query which will filter records on country and then passes the result to a partial view page ‘_Country.cshtml’. I have placed this file in ‘Shared’ folder so that any view can access it. Let’s move on to see 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.


Hope this helps.

Comments

  1. Is there any way by which we can set any button result as defult?

    ReplyDelete
  2. thanks million
    Abhimanyu Kumar Vatsa

    ReplyDelete
  3. Hi abimanyu, i want to show the selected url link in the browser url location, How to acheive this in ajax.link

    ReplyDelete
  4. For example, I add another options like Update using @Ajax.Actionlink. I create partial view for it and update data in controller. It updates the data. But when I tried to click again the Update button, it shows the last data, not the updated one. If you close the browser and reload again, it shows already. Why?

    ReplyDelete

Post a Comment

Popular posts from this blog

Migrating database from ASP.NET Identity to ASP.NET Core Identity

Customize User's Profile in ASP.NET Identity System

Lambda two tables and three tables inner join code samples