RSS

Tag Archives: Partial View

ASP.NET MVC Partial View and Ajax “real world” example

If you would like this sample code, right click here and “save as” to download. Then rename to a zip file and open.

In my previous post I have discussed and demonstrated how you can easily use jQuery and a ASP.NET MVC’s Partial View to accomplish an UpdatePanel-like solution. In this post I’d like to demonstrate a “real world” usage of this technique.

I wanted a cool looking Login dialog to popup on request when a user hits a simple “Log On” button, without having to refresh the entire page or redirecting the client to a Login page. In other words, there is no Login page, just a Login dialog. Naturally, I wanted this Log On button to be available across all the pages in the site. This could be easily be implemented using a layout (“Master Page”). But it’s more generic and nice to use a PartialView, to represent that button. More over, the basic code for this already exists in the MVC application template. Simply create a new MVC application and see for yourself. So there’s nothing new so far. However, the code for the login dialog is something new which is required and here I had basically 2 options:

  1. I could render the login dialog as a hidden dialog (“display:none”) in the Partial View (or layout). This is possible, will save a round trip to the server when the user requests to login, but is also quite “ugly” as it is inefficient to render a hidden dialog every time.
  2. I could have an UpdatePanel like implementation. Using a placeholder div, I could request another PartialView from the server on demand. The html rendered will be then “injected” into the placeholder div. I figure that this is way more efficient than the first option and can be considered, well, “nice”.

I decided to go with option 2. It felt more cool and correct, and also provided me with a great opportunity to practice this technique. Here’s the basics:

  1. We’ll create (or rather re-use MVC’s template code) a Partial View to represent a Log On/Log Off button. This will be rendered from the layout onto all pages. This view will also contain a place holder div, which will be injected with the log-in dialog.
  2. We’ll create a Partial View for the login dialog. This is basically a simple div which wraps the username/password textboxes. This will not be rendered anywhere at design time.
  3. We’ll use jQuery’s ‘load’ method to perform an Ajax call to the server, and return the Partial View of the log-in dialog. The dialog’s html will be injected into the place holder described in stage 1.
  4. We’ll create server side code to support the logon/logoff scenarios.

“Strategy”: The login button’s partial view is going to have a wrapping div, which will change according to the whether a user is logged in or not. This will be rendered at first according to the authenticity state, but will change at run-time according to the user’s operations. This will be described in 4 stages below.

Stage 1: Login button (Partial View). I reused MVC’s template code to do this. The entire code is wrapped with a div (‘divLoginButton’), whose contents will dynamically change according to Log on/log off operations performed by the user.

  • Line 1 is the wrapping div.
  • Line 2 is the server side code which decides whether a Log On or Log Off button will be rendered from the server.
  • Lines 4-9 represents a Log Off button. The user is logged in, authenticated, and has not requested to logoff (line 2 makes that decision).
  • Line 7 contains an Ajax call to actually perform the log off, and to replace the div’s entire content with a new state. This really resembles a Web Form’s UpdatePanel’s behavior, only cleaner and more efficient.
  • Lines 13-28 represent a situation that the user is not authenticated and a Log On button is displayed.
  • In line 17 we query whether the login dialog has already rendered from the server. This can happen if the user has clicked the Log On button, the dialog has rendered from the server (line 19), but has not logged in (e.g. clicked the Cancel button of the dialog). In this case, there’s no point in reloading the dialog from the server, so we reset the username/password fields (line 22) and reopen the dialog (line 25).
  • Lines 29-30 is the place holder for the login dialog.

Stage 2: Login dialog (Partial View). I created the new LoginDialog.cshtml PartialView file. This looks like this:

  • Lines 1-13 represent the “dialog”. This is just a basic div with username/password textboxes. This will be displayed as a modal dialog using jQuery UI’s Dialog. Because the dialog is set to autoopen, this will be automatically opened when rendered for the first time.
  • Lines 15-43 contains the JavaScript which will display the window as a dialog. If you’d rather have the JavaScript in a different JS file because you believe that rendering a JavaScript ajax response from the server is a bad thing, it’s also possible.
  • Line 23 indicates a POST ajax call. POST is done for security as I’d rather have the username/password (lines 25/26) not sent in the query string. The Ajax call is for the Login action method in the Home Controller.
  • Line 32 is executed when the result of the Login method is “Success”. This is what does the trick of replacing the “Log On” button with a “Log Off”, similar to the signout process discussed in Stage 1 above. It is possible to return the PartialView directly from the Login action (line 23), but I wanted to render a Success boolean in order to have more control, especially in case the Login fails.

Stage 3: Server side code to support the Log On / Log Off situations.

The comments are probably sufficient, but just in case:

  • Lines 15-18 return the Login Dialog partial view.
  • Lines 21-26 supports a Log Off scenario. Line 23 performs the actual Sign Out. Line 24 instructs the LoginButton partial view that although the user is still authenticated at this point, a Log On button should be rendered and not a Log Off button.
  • Lines 30-33 return a Log On or Log Off button, depending on the authenticity state of the user. Basically this is used after a successful login operation, when we would like to render a Log Off button.
  • Lines 36-42 represents a Login process. Line 38 should be replaced with actual Membership user login validation check. If true, line 40 sets the authentication cookie. Line 41 returns if a successful login was performed. As you can see, in this example the login is always a success.

Stage 4: Render the Login button in the layout (“Master Page”), so it’s visible throughout all the pages.

  • Line 11 represents the Login Button partial view (Log On / Log Off button).
  • Lines 5 and 8 are jQuery UI (required for the modal dialog).

Here’s how it looks. At first, the page is loaded and the Login button is rendered as a Log On button.

Now we click the Log On button. jQuery’s load method performs an Ajax request to the server, and the Login Dialog Partial View is rendered back. Because the JavaScript code which creates the dialog has an autoopen set to true, it automatically opens:

Now we type-in our credentials and click Login. A POST Ajax call to the server performs credential validation and returns a JSON with Success, meaning that the Login went ok and the user has logged in. Now another Ajax call takes place to “refresh” the state of the Login Button to that of a Log Off button. This looks like this:

Finally, when we click the Log Off button, another “refresh” takes place as the server’s LogOff button returns an updated Login Button.

That’s about it. As stated above, you could take the JavaScripts to a different JS file if you feel bad about rendering back JavaScript, or if you think that it’s more efficient either because the network load is reduced or because the JS file will be cached by the browser. It’s also possible to render both a Log On and a Log Off buttons at once and toggle their visibility on the client side, settling just for Ajax calls only to perform the credential validation and to set the cookies. In either case, this isn’t the point of this blog post. The point is to show multiple examples of Partial Views used as Web Forms Update Panels, using jQuery.

 
117 Comments

Posted by on 26/04/2011 in Software Development

 

Tags: , , , , ,

ASP.NET MVC – PartialView with Ajax

In this post I will briefly discuss how to use a PartialView either as a Web Form’s “UserControl” or as an “UpdatePanel”. You can click on the links to navigate accordingly, or just read on. UPDATE: If you’d rather have a “real world” example, you can read this post: http://evolpin.wordpress.com/2011/04/26/asp-net-mvc-partial-view-and-ajax-real-world-example/.

I’ve wanted to use a PartialView for quite some time now. A PartialView provides two functionalities which aren’t necessarily overlapping although have much in common. In comparison with Web Forms, a PartialView is a kind of a UserControl, but it also provides a kind of UpdatePanel.

What’s great about a PartialView is that it’s very straight forward – you simply place your HTML and/or JavaScript in a separate View file, probably placed in your Shared views folder so it can be used easily across views. Then you can either use it as a control, by placing Html.Partial(…) calls on your View as desired, or you can render it in run-time as a response to an Ajax call.

UserControl like implementation:

Let’s go quickly over the first usage, that of a “UserControl”: we right-click on the Shared folder to add a new View, give it a name, and select the “Create as a partial view” checkbox:

Our solution explorer looks as follows (Index.cshtml will be using the newly created MyPartialView.cshtml):

MyPartialView contains a simple dummy html place holder which will display a “My View” header; whereas Index.cshtml in this example will now include 2 references to MyPartialView:

1: <table border='1'> 
2:     <tr>
3:         <td>
4:             @Html.Partial("MyPartialView")
5:         </td>
6:         <td>
7:             @Html.Partial("MyPartialView")
8:         </td>
9:     </tr>
10: </table>

That’s about it, and this is how it looks:

One more thing worth mentioning, is that the ViewData dictionary which can be populated in the Controller, is available both to the View and to it’s Partial Views.

Ajax and html injection – “UpdatePanel”:

As I mentioned earlier, Partial Views can also provide a functionality resembling Web Form’s UpdatePanel. Those familiar with UpdatePanel usually either appreciate the (relatively) ease of use, or despise it for being so heavy and inefficient. Almost an Ajax “wannabe”. Personally, I think that UpdatePanel has its place in Ajax side by side with PageMethods/WebMethods. I consider it the better alternative for rendering a “mass” of html onto the client, especially when paging or sorting grids. In MVC, a PartialView could perform this exact functionality, and could prove to be the better solution for rendering plenty of html to the client.

Basically there are 4 steps to achieve this:

  1. Create a PartialView.
  2. Create a place holder html control.
  3. Use jQuery’s load method to fetch the partial view from the server and inject it into the place holder.
  4. Create a server side Action in a Controller that will return the partial view.

Here’s a quick example how this can be done. We’ll use the same partial view created earlier (i.e. MyPartialView.cshtml). So now we have to prepare a place holder div, and use jQuery to load and inject the response:

1: <a href='javascript:getView();'>Get Partial View</a>
2: <script type="text/javascript">
3:     function getView() {
4:         $('#divResult').load("@Url.Action("GetView" , "Home" )");
5:     }
6: </script>
7: <div id='divResult'>
8: </div>
  • Line 1 is a simple anchor which will invoke the JavaScript containing jQuery’s load.
  • Line 4 is the simple one-line code which performs an ajax call to the server’s GetView action in the Home Controller (will be done shortly), and injects the result.
  • Line 7-8 is where the result will be injected to.

And now for the server side – pretty self-explanatory:

1: public ActionResult GetView()
2: {
3:    return PartialView("MyPartialView");
4: }

When we run the sample, prior to the Ajax call this looks like this:

After clicking the link, jQuery’s load method performs the Ajax call as expected, and the partial view’s HTML is injected into the place holder. All this can be viewed in the picture below:

  1. The load method performs a GET operation to the server’s GetView.
  2. Response is returned with html.
  3. jQuery injects the result in the place holder div.
  4. The result is rendered in the browser.

That’s it! No doubt this is real simple to achieve. From here on, the possibilities are quite remarkable. You see, it turns out that when jQuery injects the code, it is also able to inject JavaScript. This means that you can actually render not only html, but JavaScript code as well. Naturally you can argue if this is a good thing or not, but it just gives you a hint on how extensible this can be.

As usual, credits are in order. This great post summarizes different jQuery Ajax approaches with ASP.NET MVC.

BTW: If you ask yourself why you should use jQuery instead of Microsoft Client libraries, I guess you should relate to Microsoft’s statements about “throwing its weight behind jQuery”. You can read about this in Stephen Walther’s blog. Stephen’s conclusion says it all: “Our plan is to focus on jQuery as the primary technology for building client-side Ajax applications moving forward. We want to adapt Microsoft technologies to work great with jQuery and we want to contribute features to jQuery that will make the web better for everyone. We are very excited to be working with the jQuery core team.” Although MVC 3 comes with Microsoft Ajax client scripts, it also includes jQuery and I guess that we’ll see more and more of jQuery in Microsoft’s VS templates.

 
12 Comments

Posted by on 12/04/2011 in Software Development

 

Tags: , , , ,

 
Follow

Get every new post delivered to your Inbox.

Join 66 other followers