First, explain the title. What is "UpdatePanel for ASP. net mvc? I believe everyone knows about UpdatePanel in ASP. NET AJAX. Unfortunately, the birth of the ASP. net mvc Framework "destroys" a large number of PostBack-based controls, and the first possibility is UpdatePanel. Without PostBack, UpdatePanel loses all its functions. It is even better to bind some controls, at least they can be used for display. After sighing for UpdatePanel, we began to miss the advantages of UpdatePanel: "Transparent ". With the help of UpdatePanel, AJAX operations are almost completely transparent to developers. We only need to wrap the content that requires AJAX updates with UpdatePanel, and everything is so elegant.
Can we save UpdatePanel in ASP. net mvc? Maybe yes, but it is more like an "impossible task ". I am not the legendary atango, so it seems more feasible to customize an AJAX solution for ASP. NET MVC. Although we will not demand the perfection of a new thing from its birth, even if it is just a prototype, it must strictly abide by the following principles:
◆ Do not undermine protocol collaboration and responsibilities in MVC)
◆ Transparent to developers as much as possible
Nikhil Kothari once proposed his AJAX solution under ASP. net mvc framework. If you do not know his practice, I will summarize it here first. Nikhil extends the Controller to support an Ajax operation, so we can write the following code in the Code:
public class TaskListController : AjaxController { ... public void CompleteTask(int taskID) { if (String.IsNullOrEmpty(Request.Form["deleteTask"]) == false) { InvokeAction("DeleteTask"); return; } Task task = _taskDB.GetTask(taskID); if (task != null) { _taskDB.CompleteTask(task); } if (IsAjaxRequest) { if (task != null) { RenderPartial("TaskView", task); } } else { RedirectToAction("List"); } } ...} |
Like AjaxController, Nikhil also provides some extension methods for ViewPage and ViewControl. Therefore, we can see the following code in ViewList. aspx:
<div id="taskList"> <% foreach (Task task in Tasks) { %> <div> <% this.RenderPartial("TaskView", task); %> </div> <% } %></div> |
Both View and Controller have calls to the RenderPartiel method. Their function is to output an HTML code generated by "Partial Template" to the client. In the default configuration of ASP. net mvc, the Partial Template is User Control. In the Partial Template of TaskView, we can see some auxiliary methods:
<div id="taskItem<%= Task.ID %>" class="taskPanel"><% Ajax.Initialize(); %><% this.RenderBeginAjaxForm( Url.Action("CompleteTask"), new { Update = "taskItem" + Task.ID, UpdateType = "replace", Completed = "endUpdateTask"}); %> <input type="hidden" name="taskID" value="<%= Task.ID %>" /> <input type="submit" class="completeButton" name="completeTask" value="Done!" /> <input type="submit" class="deleteButton" name="deleteTask" value="Delete" /> <span><%= Html.Encode(Task.Name) %></span> <% this.RenderEndForm(); %><% Ajax.RenderScripts(); %></div> |
These auxiliary methods are used to generate tags and scripts that trigger AJAX updates. When you click the submit button between the tags generated by RenderBeginAjaxForm and RenderEndForm, the webpage sends an AJAX request to the server, and the server Action finally outputs the HTML generated by a Partial Template through the RenderPartial method. The HTML output by the server end will be replaced or added to an element of the page. This forms an AJAX effect. This solution looks cool in some aspects, especially the generated code can be added to an element, not just as an UpdatePanel replacement, for example, Nikhil uses this feature in his example to implement an add function. However, it seems that this solution is not ideal if we use the previously proposed principles.
The reason is simple, because it is not transparent.
Some people also commented that the logic in the Controller should not process Nikhil differently based on the AJAX request or not. RenderPartial is used to replace RenderView for AJAX operation output ), therefore, this solution undermines the role of MVC. I don't think so, but I hope to do this, because doing so means absolute transparency. Absolute transparency means that the Controller has completely handed over the AJAX decision of an application to the client, which is ideal because AJAX is completely a concept of a presentation layer. The UpdatePanel in ASP. net ajax has a remarkable performance in this aspect, although it is far from perfect). Therefore, I finally decided to develop a component similar to UpdatePanel for ASP. NET MVC. Fortunately, ASP. net mvc uses WebForm pages as view templates by default. Under this powerful model, it does not seem very difficult to build a prototype of such an AJAX solution.
I name this control MvcAjaxPanel. The biggest difference between MvcAjaxPanel and UpdatePanel is that the latter receives PostBack, while the former only receives normal HTTP requests. Post "Back" means that after the Post, the original Page is returned, and ASP. net mvc requests are usually directed to different pages. Therefore, how to update content across pages is the primary solution of MvcAjaxPanel. Finally, I chose to specify an UpdateAreaID for each MvcAjaxPanel.
<mvc:MvcAjaxPanel runat="server" ID="mvcAjaxPanel" UpdateAreaID="Header"> ...</mvc:MvcAjaxPanel> |
When a page sends an AJAX request to the server, the UpdateAreaID information in the page is attached, and the server Action does not realize this, therefore, a view template is still specified according to the common logic and HTML is output. However, if the MvcAjaxPanel in the View template finds that this request is actually an agreed AJAX request, please note that only the View component realizes that this is the nature of the request ), the new method is used to replace the standard output. In this case, the template will find the MvcAjaxPanel with the same attribute value based on the UpdateAreaID passed by the client and output the content selectively. On the client, the corresponding JavaScript code will receive data from the server and update the corresponding area on the page.
Obviously, MvcAjaxPanel has many similarities with UpdatePanel, and is transparent to some extent. In addition, compared with the Nikhil solution, a very important advantage is that multiple regions in the page can be updated at a time-in fact, this is one of the characteristics of UpdatePanel. In addition, this method of transparency to the Controller has a natural feature, that is, the ability to easily switch pages in browsers that do not support AJAX.
The implementation principle on the server side is not complex. However, as another key part of the solution, it is worth thinking about how to trigger an AJAX commit on the client side. The UpdatePanel method is "fully automated": When a page is loaded, the server-side Trigger information is output to the client, and then the client intercepts the form submission event, the UniqueID or DOM structure is used to determine whether the submission should be converted to AJAX. However, there will be almost no PostBack elements in an ASP. net mvc page. On the contrary, there will be a large number of common links, which are the main interception targets of AJAX updates.
For this reason, I provide some JavaScript code to intercept the original target address of a link and convert it into an AJAX request. Here, I use the code in the example to demonstrate this method. This example is derived from ASP provided by Brad Abrams. net mvc example, But I discard the Northwind database and Entity Framework, and replaced it with XML data and a simple custom Model. In addition, I also transplanted it to the 0416 Build of ASP. NET MVC Framework ):
<% foreach (var category in this.ProductCategories) { %> <li> <%= Html.ActionLink<ProductsController>( c => c.List(category, 1), category, new { onclick = "mvcAjax.get(this, event)" })%> </li><% } %> |
This Code comes from the category list page. Compared with the code before AJAX improvement, the only difference is that the onclick event bold part of the element is specified ). In The onclick event execution, the default redirect behavior of this link will be canceled and replaced by an AJAX request. The request target is the List Action in ProductsController.
We can use the above method to deal with common links. How can we change the from commit behavior of a client to AJAX operation? The following code is still in the example:
<form method="post" action="<%= Url.Action("Update", new { id = this.Product.ProductID }) %>" onsubmit="mvcAjax.submit(this, event);"> <table> <tr> <td>Name:</td> <td><%= Html.TextBox("Name", this.Product.Name) %></td> </tr> ... </table> <input type="submit" value="Save" /></form> |
After a form submit event is intercepted, the client collects all input and select values in the form to form the Request body and sends an AJAX request in the form of http post. The rest is no different from the previous one.
Compared with UpdatePanel, The MvcAjaxPanel client interception method can be described as "Manual", but I don't think this will cause any problems. ASP. net mvc emphasizes separation of duties, which is not only reflected in code, but also in developers' responsibilities. When developing ASP. net mvc applications, the front-end development engineers are responsible for the View. For them, JavaScript and AJAX are a very familiar technology. In this case, manually writing some JavaScript calls will make them extremely free. For example, in the previous code example, when calling the mvcAjax. get or mvcAjax. submit method, you can freely add additional operations or condition judgments before and after. This is not like using UpdatePanel. If you need to use JavaScript to submit an AJAX update, you also need to use the trick that does not appear in the dark.
Because of this, the solution proposed by Nikhil is very good, and it can be flexibly combined with the custom logic of front-end developers. In addition, read ASP. net mvc Framework 0416 Build code, I found in the new version of ASP. net mvc seems to be built into this AJAX solution-but it does comply with Microsoft's consistent practice, isn't it?
The usage and working principles of this AJAX solution prototype have been described. If you are interested in the specific implementation or want to try it yourself, you can download the attachment at the end of the article. The solution in the attachment contains three projects. MvcAjax provides MvcAjaxPanel projects, while MvcWebApp is a common ASP. net mvc sample program, while MvcAjaxWebApp is naturally the result after the AJAX effect is added. In the example, the menu defined in the Master Page, that is, the menu on the left of the Page, shows the current time. This is to reflect the MvcAjaxPanel's "One commit, multiple updates.
However, it must be emphasized that this is just a prototype. In other words, this is just an implementation attempt and has not made much pursuit in many details. If you want to become a perfect AJAX solution, you still need to make a lot of improvements. For example:
◆ Some client hooks are provided for front-end developers to use, for example, when the client initiates another request before, after, or after a submission has not been returned ).
◆ More powerful functions and better development experience, such as the client trigger mechanism)
◆ Exception Handling
◆ Script supported
◆ Supports Redirection to Redirection)
◆...
In addition, as an AJAX solution specific to ASP. net mvc, there are also some additional issues to consider. One of the most typical problems is that the template control is rarely used when ASP. net mvc is used, and more loops in pages are used. How can MvcAjaxPanel take effect in the loop content? I have also come up with some ideas, but if you want to determine the final implementation method, there are many things that need further consideration. If you have any suggestions or other ideas about this AJAX solution, please let me know as soon as possible.
One more interesting thing: One day after I implemented this prototype, I suddenly realized that this control can not only be used for ASP. net mvc can also be used in common WebForms applications. This is an unexpected discovery.
- ASP. net mvc Case Study
- Technical details of Microsoft's latest ASP. net mvc Framework Beta edition
- Use jQuery with ASP. NET MVC