This article is dedicated to creating a link with a picture using the Ajax.ActionLink helper method, or rather the Extension to the Ajax.ActionImageLink method, which we will create.
First, a summary of Ajax, ASP .NET MVC 3, and their sharing.
AJAX (Asynchronous Javascript and XML - “asynchronous JavaScript and XML”) is an approach to building interactive user interfaces for web applications, which consists in “background” browser data exchange with a web server. As a result, when updating data, the web page does not reload completely, and web applications become faster and more convenient.
ASP .NET MVC is a web application creation framework that implements a Model-view-controller (
MVC )
pattern based on
ASP .NET technology.
')
There are
several Action methods for using AJAX in ASP .NET MVC 3, but we are interested in
Ajax.ActionLink , so more about it:
Ajax.ActionLink
Ajax.ActionLink - a method that returns a link generated depending on the parameters passed, a click on which will send an asynchronous request to the server and determine the further behavior of the page.
There are a total of 12 options for overloading this method — the input parameters that can be passed to use it are discussed below:
- this AjaxHelper ajaxHelper is a class that provides support for displaying HTML in AJAX scripts;
- string linkText - link text;
- string actionName - the name of the controller's Server Action method where the processing request will be received;
- string controllerName - the name of the controller where the request will be received in search of the Action method to process;
- string protocol - the protocol by which the request will be sent (for example, “http” or “https”);
- string hostName - domain name (for example, “habrahabr.ru”);
- string fragment - the name of the fragment, which will be added after # at the end of the URL;
- RouteValueDictionary / object routeValues - parameters passed to the server in the URL string;
- AjaxOptions ajaxOptions - options for performing an asynchronous request
- string Confirm - a message that will appear before sending data to the server with a request to confirm user actions;
- string HttpMethod - the method by which to send data to the server (“POST”, “GET”);
- InsertionMode InsertionMode is a property that indicates how to update the DOM of the HTML page with the received data ("InsertAfter", "InsertBefore", or "Replace");
- string LoadingElementId - id of the HTML element that is displayed while an asynchronous request is being executed (from OnBegin to OnComplete), for example, it could be ajaxLoader.gif;
- string OnBegin - the name of the javascript function that will be executed before sending the request;
- string OnComplete - the name of the javascript function that will be executed after the data has been received from the server, but the page has not yet been updated;
- string OnFailure is the name of the javascript function that will be executed in case of a page refresh error. For example, you can intercept an error code that the server returns;
- string OnSuccess - the name of the javascript function that will be executed after successfully receiving data from the server and updating the page;
- string UpdateTargetId - id of the HTML element that will be updated by the received data from the server (for example, HTML markup or a string, update the div or display the message in a span);
- string Url - URL address to which to send the request;
- IDictionary <string, Object> htmlAttributes is a key-value collection in which you can specify attributes to be added to the generated HTML markup (for example, new { class = "add"}).
To use the Ajax features in the MVC 3 project, we need to include the following files, which, by default, are located in the / Scripts folder:
- jquery-1.4.4.js
- jquery.unobtrusive-ajax.min.js
Formulation of the problem
It is required to create a link in the form of an image (in our case, an asterisk), clicking on which will cause an asynchronous request to the server, and after receiving the answer, it will be updated (changing the image, the tooltip):
Considering the opportunities Microsoft provides us with the ActionLink ActionLink Ajax helper, we conclude that
without a bike, they are not enough, so we need our own helper. Let's get started
1. Create an empty ASP .NET MVC 3 project
In the View engine specify Razor.
2. Add a HomeController and a view for the Index method
Select ~ / Views / Shared / _Layout.cshtml as master page for our presentation
And so, now we need to create an Extension method for our Ajax helper.
3. Create the Extension method Ajax.ActionImageLink
Add a
core folder to the project root and a new
static class
Extensions.cs in it
Read more about creating extensible methods
here .
We proceed directly to creating an expanding method. And so, for the basis of our link with the image we take the HTML markup and styles of habrahabr.ru, then the contents of the container will be represented by two states:
<div class="favourite"> <a class="add" title=" " href="#"></a> </div> <div class="favourite"> <a class="remove" title=" " href="#"></a> </div>
Cutting off all unnecessary, we come to the fact that the container (the object to be changed is UpdateTargetId) will be a div, and our method will have to return HTML markup in the form of a link with a changing class and title.
*
Then the author thought for the first time, and realized that all this is solved without expanding methods by means of the following code :
@Ajax.ActionLink(" ", "Hello", "World", null, new AjaxOptions() { }, new { @title= Model.inFavourite? " " : " ", @class = Model.inFavourite? "add" : "remove" })
but deciding that it would be too easy, and having noticed a little, he complicated his task . *
Cutting off all unnecessary ... Adding too much, we come to the fact that the container (UpdateTargetId object to change) will be a div, and our method will have to return HTML markup in the form of a link containing the image with the changing title and path to the image.
<div id="favourite"> <a href="/Home/AddOrRemoveFavourite"> <img src="/Content/images/star-off.png" title=" " /> </a> </div> <div id="favourite"> <a href="/Home/AddOrRemoveFavourite"> <img src="/Content/images/star-on.png" title=" " /> </a> </div>
Note:
You can use different methods to add / remove entries to your favorites, but in this article, one method will be used -
AddOrRemoveFavourite .
And so, the framework of our expanding method is presented below:
public static IHtmlString ImageActionLink(this AjaxHelper helper, string actionName, bool inFavourite, AjaxOptions ajaxOptions) { }
Input parameters are:
- actionName - the name of the controller method (AddOrRemoveFavourite);
- inFavorite - a sign of whether the entry has already been added to favorites;
- ajaxOptions - request execution parameters.
To create HTML markup for our image, use the
TagBuilder class:
var builder = new TagBuilder("img"); builder.MergeAttribute("src", String.Format("/Content/images/star-{0}.png", inFavourite ? "on" : "off")); builder.MergeAttribute("title", inFavourite ? " " : " ");
To create a link, use the standard Ajax.ActionLink method:
var link = helper.ActionLink("[replaceme]", actionName, routeValues, ajaxOptions).ToHtmlString();
and then add a link text replacement to the content of our HTML img element:
return new MvcHtmlString(link.Replace("[replaceme]", builder.ToString(TagRenderMode.SelfClosing)));
As a result, our Extensions.cs class will look like this:
public static class Extensions { public static IHtmlString ImageActionLink(this AjaxHelper helper, string actionName, bool inFavourite, AjaxOptions ajaxOptions) { var builder = new TagBuilder("img"); builder.MergeAttribute("src", String.Format("/Content/images/star-{0}.png", inFavourite ? "on" : "off")); builder.MergeAttribute("title", inFavourite ? " " : " "); var link = helper.ActionLink("[replaceme]", actionName, inFavourite, ajaxOptions).ToHtmlString(); return new MvcHtmlString(link.Replace("[replaceme]", builder.ToString(TagRenderMode.SelfClosing))); } }
If you add a call to our extending method to the view (after specifying the
@using directive
MVC3_AjaxActionImageLink.Core ), the following HTML markup will be generated:
<a data-ajax="true" data-ajax-mode="replace" data-ajax-update="#favourite" ref="/Home/AddOrRemoveFavourite"> <img src="/Content/images/star-on.png" title=" " /> </a>
or
<a data-ajax="true" data-ajax-mode="replace" data-ajax-update="#favourite" href="/Home/AddOrRemoveFavourite"> <img src="/Content/images/star-off.png" title=" " /> </a>
It remains to add only a div, pictures of stars, a method call in the view, and the AddOrRemoveFavourite method itself, but I would like to dwell on the latter in more detail.
4. Adding the AddOrRemoveFavite method to the controller
In general, the method that handles an asynchronous request returns a value, be it a string, a number, JSON data, etc., but in our case, we will need to return the HTML markup of the new element that our extension method generates. Alas (or fortunately) in ASP .NET MVC 3 there is no possibility to call our extending method on the server side (in the controller method) and therefore we will not be able to generate markup without duplicating the code itself in the controller method (otherwise, one of the fundamental principles of MVC-
DRY ).
However, from the controller's method, we can return a call to Partial View, which initiates a call to our extending method, which in turn will return HTML markup.
Let's get started
4.1. Add a Partial View with a call to an expanding method.
Add the folder folder
Partial in the
Views folder. In
Partial add folder
Favorites .
Add the View to the
Favorites folder by selecting
Create as partial view and indicating the name
AddOrRemoveFavourites_PartialView
We add directives to the contents of the added Partial View:
@using MVC3_AjaxActionImageLink.Core @Model bool
and the call of our method itself:
@Ajax.ImageActionLink("AddOrRemoveFavourite", (bool)Model, new AjaxOptions() { UpdateTargetId = "favourite" });
Note. To simplify the details, the model in this article will be a static variable of type bool.
The contents of Index.cshtml now assigns the call to the expanding Partial View method and looks like this:
@using MVC3_AjaxActionImageLink.Core @model bool @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>Index</h2> <div id="favourite"> @{ Html.RenderPartial("/Views/Partial/Favourites/AddOrRemoveFavourites_PartialView.cshtml", Model); } </div>
4.2. Add an asynchronous AddOrRemoveFavite request processing method to the controller and associate with the model
In order to return our Partial View, you need to specify in the return a call to the PartialView method, passing the path to the first parameter. In addition, since we save the state in a primitive way through a static bool variable, we will transfer it as a model to both our View. The final version of our
HomeController.cs class is presented below:
public class HomeController : Controller { public static bool inFavourite = true; public ActionResult AddOrRemoveFavourite() { if (Request.IsAjaxRequest()) { inFavourite = !inFavourite;
5. What is left?
The final stage will be the addition of the images folder with star-off.png and star-on.png images, as well as the connection of the script for working with AJAX in ASP .NET MVC 3:
<script src="../../Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>
We try.
we click
Conclusion
So, what have we all done in this article and learned:
- Considered the possibility of using AJAX in ASP .NET MVC 3 using the Ajax.ActionLink method
- Gained insight into creating your own extensible methods and using them
- Found out how to return generated HTML markup from an AJAX request by calling the Html helper
- Do not violate the principle of DRY
Note
The name of the method and the principle of building the link as an image was taken from the project Stephen Walthe's
Contact manger project