Scott Hanselman

ASP.NET MVC Preview 4 - Using Ajax and Ajax.Form

July 16, '08 Comments [51] Posted in ASP.NET | ASP.NET MVC
Sponsored By

ASP.NET MVC Preview 4 is up on CodePlex. The Gu has all the exquisite Gu-Like Detail on his blog. Phil Haack has some notes on this release on his blog.

If you take a look at the generated "changes" document, it shows a bunch of new stuff like AjaxHelpers and AjaxExtensions that set the stage for some interesting things the community could do with ASP.NET MVC and Ajax. I'd like to see some JQuery love in there, maybe with some MVCContrib as they've been quiet lately.

Using the new Preview 4 bits, here's what I was able to get running in just a few minutes.

Given a ViewPage that has a TextBox and a Button on it, when I click the button (and submit the form) I'll call back to the server and get some text that should then go in the div next to the button.

mvcpreview4ajax

The View looks like:

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<p>
<%using (Ajax.Form("ExamineTextBox", new AjaxOptions { UpdateTargetId = "result" }))
{ %>
<%= Html.TextBox("textBox1")%>
<input type="submit" value="Button"/>
<span id="result"/>
<% } %>
</p>
</asp:Content>

Notice the Ajax.Form helper and the UpdateTargetID that refers to the span. There's more AjaxOptions in there to explore as well, that we'll see in a second. The controller action looks like this:

public class HomeController : Controller
{
public string ExamineTextBox(string textBox1)
{
if (textBox1 != "Initial Data")
{
return "This text is MVC different from before!";
}
return String.Empty;
}
}

Notice that the return method of the ExamineTextBox isn't an ActionResult, it's a string. In fact, the string result is being wrapped for you into a ContentResult. You could certainly make a ContentResult yourself, but this makes for a nicer looking method signature.

The result of that method is returned via the AJAX call, then put into that span via magic and pixie dust. Actually, the request looks like this:

POST /Home/ExamineTextBox HTTP/1.1
Referer: http://localhost.:45210/Home
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Accept-Encoding: gzip, deflate
Host: localhost.:45210
Content-Length: 28
Connection: Keep-Alive
Pragma: no-cache

textBox1=dude&__MVCAJAX=true

and the Response like this:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/9.0.0.0
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 39
Connection: Close

This text is MVC different from before!

And that UpdateTargetID (the span) mentioned in the Ajax Form helper above? That's swapped in via the magic in MicrosoftMvcAjax.debug.js. There are options for before, after and replace.

// Insert the results into the target element
if (targetElement) {
switch (insertionMode) {
case Sys.Mvc.InsertionMode.Replace:
targetElement.innerHTML = executor.get_responseData();
break;
case Sys.Mvc.InsertionMode.InsertBefore:
targetElement.innerHTML = executor.get_responseData() + targetElement.innerHTML;
break;
case Sys.Mvc.InsertionMode.InsertAfter:
targetElement.innerHTML = targetElement.innerHTML + executor.get_responseData();
break;
}
}

Note that I had to manually (for now) add the JavaScript libraries, so I put them in my Site.Master View.

<script src="/Content/MicrosoftAjax.debug.js" type="text/javascript"></script>
<script src="/Content/MicrosoftMvcAjax.debug.js" type="text/javascript"></script>

Also, notice that the MicrosoftMvcAjax.js is new and it's in your /Content folder if you make a new MVC Application. Congrats to Phil and Eilon and the team for this release!

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Thursday, July 17, 2008 12:55:42 AM UTC
I just downloaded Preview 3 last night... lol
Thursday, July 17, 2008 1:31:20 AM UTC
i HOPE it's not the javascript library from asp.net ajax! if it is anywhere close, why bother? who wants the bloat? jQuery or YUI support would be great perhaps much in the same way Ext JS creates adapters for different libraries but then it's even more bloat. i wonder how many other developers outside of MS will use the AJAX when this is so easy to do with the MVC framework and jQuery. i guess this is for webform developers who needs this stuff pre-canned for them. give me bare metal MVC!

anyway, i didn't mean to be negative. all this stuff is great. i hope there will be an article on using IronRuby with ASP.NET MVC Preview 4. there was supposed to be some support from it if I remember correctly.
mike
Thursday, July 17, 2008 2:51:47 AM UTC
@Mike We're definitely looking into the idea of having more JQuery support one way or another. Several members of the ASP.NET team are fans of JQuery. I'll post some samples of using MVC Ajax w/ JQuery soon.
Thursday, July 17, 2008 3:37:33 AM UTC
Well, i have to say that I like jquery also. But don't ride off the implemantation of ms ajax only for winforms people who demand canned easy to use things. Fact of the matter is somtime a project roles around with the requirment that no opensource libraries be used. and that whatever it is being used is somthing to be garanteed supported by a Company like Microsoft.
jack
Thursday, July 17, 2008 4:01:06 AM UTC
I've started a series of posts detailing the creation of a Grid html helper using AJAX and JQuery using the preview 3 bits here. I'd love some feedback/help.
-Seth
Thursday, July 17, 2008 4:12:28 AM UTC
Hi Scott/Phil

Thanks for the post.Different choices are good things and I am happy that MVC is pluggable to any client side javascript frameworks. If anyone like jQuery or other frameowork, they can use that one and anyone like MS Ajax they can use it. Don't argue for a single framework. The MVC team should learn lesson from the problems of ASP.net Ajax while developing Ajax helpers for MVC. The fact is that JQuery is very popular among the web develoeprs regardsless of specific community.Please provide samples in both JQuery and MS Ajax.

Thanks,
Shiju Varghese
Thursday, July 17, 2008 8:06:39 AM UTC
Although it works nice, I'd prefer an unobtrousive JS solution. I mean, I hate the standard ASP.NET AJAX framework for the bloat, the use of updatepanel and all that non-standard stuff, but at least it works in an unobtrousive way, so if the have JS disabled the page works in the normal way.

I'll stick to my custom self-written ajax library for now, hoping to see something in the future. The MVC framework is awesome, been waitin for it for ages, and all you guys are doing wonders, keep it up!
Thursday, July 17, 2008 9:50:53 AM UTC
I noticed that when I refresh my page it doesn't loose value in textBox! What is it? View State come back? Why I ever need this? How can I disable?!
Dennis
Thursday, July 17, 2008 12:59:34 PM UTC
I created some jQuery love for preview 3, and will also do this for preview 4 ofcourse... though it's too bad to see that p4 does not allow you to override the default ajaxhelper :( ... all methods are non-virtual.
Thursday, July 17, 2008 1:06:11 PM UTC
Hmm, openid doesn't give much about my identity :)
Anyway, forgot to include a link to my p3 version of jQuery love
Thursday, July 17, 2008 1:28:52 PM UTC
+1 for jQuery

I'm missing HtmlHelpers such as SubmitButton, Image - were they removed?
Steve
Thursday, July 17, 2008 1:42:40 PM UTC
What's even better, is that it's optional and I don't have to use it. Unobtrusive is the way to go.
Corey
Thursday, July 17, 2008 2:00:02 PM UTC
Support jQuery.

No Asp.net ajax!!!!!!!!!!!
Nirvana
Thursday, July 17, 2008 2:27:38 PM UTC
Just makes me cry that so much effort is being spent on these helpers (that anyone working with a good AJAX library doesn't need) instead of working on things like subcontrollers and components... :(
Jamie
Thursday, July 17, 2008 3:13:46 PM UTC
NIrvana, I've been using the <a href="http://developer.yahoo.com/yui/>Yahoo! User Interface Library</a> with ASP.NET MVC without any problems, and I suspect you could easily do the same with JQuery. What I like best about ASP.NET MVC is that it provides me with a lot more control over my output than I ever felt like I had with ASP.NET WebForms.
Thursday, July 17, 2008 4:08:25 PM UTC
This looks like you are replicating the UpdatePanel behavior at some degrees
Thursday, July 17, 2008 4:57:00 PM UTC
@Simone Nah, definitely not replicating UpdatePanel. UpdatePanel is a very different beast. It's focused on setting a region as "asynch updateable" and forget about it. There's a lot of magic involved to get it to work. It has to understand __VIEWSTATE, etc... This is very different from UpdatePanel. It's not fire and forget. You need to be explicit. You have full control. It's very lightweight.

@Jamie We wanted to provide a small set of simple Ajax helper methods for those who aren't as familiar with Javascript libraries. These can enable simple scenarios, and we don't plan on having a huge number of them. For that, I think they still provide value and for those who are competent with good JS libraries, you can totally ignore them. We'll also be digging into various ways of swapping in JQuery. Watch my blog for some posts on that.
Thursday, July 17, 2008 6:07:37 PM UTC
too difficult
Ruslan
Thursday, July 17, 2008 6:45:53 PM UTC
has page invoke page methods ?
Thursday, July 17, 2008 7:50:20 PM UTC
Could you do readme in PDF in the future? Thanks!
Mike
Thursday, July 17, 2008 7:59:19 PM UTC
Mike - There should be DOC and PDF versions of all the files on CodePlex.
Thursday, July 17, 2008 8:12:08 PM UTC
there's a bug in the ButtonsAndLinkExtensions class.

the button builder always builds a closed tag button, which is invalid and causes serious rendering bugs in the HTML. the button tag has to be open:

<button arg="val">Text</button>
Carl
Thursday, July 17, 2008 8:14:33 PM UTC
Good find, Carl! I'll pass it on.
Thursday, July 17, 2008 8:28:17 PM UTC
looking forward to this release... I'm a fan of both JQuery and ExtJS.
Thursday, July 17, 2008 9:25:43 PM UTC
I just ran this sample, but how can you prevent your form from losing the text in the textbox after submit? It doesn't seem like the desired behavior in many ajax application.
Thursday, July 17, 2008 9:40:57 PM UTC
You'd have to put the text right back into the Textbox, I'm afraid!
Friday, July 18, 2008 3:08:51 PM UTC
Is it too late to complain about the misuse of the 'using' keyword? Are we really freeing an unmanaged resource by calling Dispose on a Form object (or whatever object is returned by the call to Ajax.Form)?

How about something less abusive, like:


<%= Ajax.Form(...) %>

<%= Ajax.EndForm() %>


GuyIncognito
Friday, July 18, 2008 3:29:24 PM UTC
ps. This is really a horrible example. :)

How about changing it to something where you're at least doing some sort of server side validation on the textbox input instead of something that could have been done without the postback to the server.

I'm just saying it's a really confusing example... and it's hard to see what you're exactly getting with Ajax.Form.


1. <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
2. <p>
3. <% using (Ajax.Form("UsernameExists", new AjaxOptions { UpdateTargetId = "result" }))
4. { %>
5. <%= Html.TextBox("username")%>
6. <input type="submit" value="Button"/>
7. <span id="result"/>
8. <% } %>
9. </p>
10. </asp:Content>

public class HomeController : Controller
{
public string UsernameExists(string username)
{
string[] existingUsers = { "ScottGu", "ScottHa", "GuyIncognito", "Boris" };

if (existingUsers.Contains(username))
{
return "The username is already in use";
}
else
{
return "The username is available";
}
}
}



@me.yahoo.blahblahblahb


I haven't run this example yet, but if it's truly an "ajax" example, the entire page should NOT post back to the server and reload entirely (which would cause you to lose whatever value was in the the textbox). The postback should happen behind the scenes without the page reloading. I'll have to try out the new MVC 4 bits and see what you mean, cause I'm confused...
GuyIncognito
Friday, July 18, 2008 4:39:14 PM UTC
Guy - Valid point. I did it in like 2 minutes. Your example is a good one!
Sunday, July 20, 2008 4:42:05 AM UTC
zbleo vegoti qecvifsl wrzkpbgjl wvaj bpry yxiequokd
Sunday, July 20, 2008 9:03:26 PM UTC
trying out openid
Monday, July 21, 2008 5:41:15 PM UTC
I don't know why everyone is so into jQuery. Every prototype based library offers kind'a the same access elements. More to the point I like the idea of MooTools more than I do jQuery.

And also I'll much more like to use ASP MVC Ajax rather than jQuery. It is a matter of personal preferences after all. I for one have never used ASP.NET before mostly because I didn't find it appealing enough. Ever since MVC was introduced things changed and I hope it will be ready for release soon =p~.

Congrats to the MVC Team you are building a great piece of software.

Monday, July 21, 2008 8:25:48 PM UTC
What adjustments do you have to make at the IIS in order to publish the .net website using MVC framework?
Tania
Monday, July 21, 2008 8:34:58 PM UTC
Tania - For IIS7, nothing, it just works. For IIS6, you need to associate the MVC extension with the ASPNET_ISAPI dll.
Monday, July 21, 2008 9:06:48 PM UTC
Tuesday, July 22, 2008 9:20:34 AM UTC
@GuyIncognito: I like the "using" syntax. It think it's far more readable than a lot of Begin() / End() blocks (it won't compile in case of errors, whereas it would just spit out invalid HTML otherwise).

I'd vote for jQuery support too. :)
Tuesday, July 22, 2008 12:59:54 PM UTC
So, .net MVC not even a beta yet. Do you have a timeline for the releases? I would like to know it because we are planning to use it for a very important project of ours. Thanks!
Tania
Tuesday, July 22, 2008 4:20:25 PM UTC
Tania - I think MVC will be released in a month than ends in "-ber."
Wednesday, July 23, 2008 4:28:07 PM UTC
Hi Scott. Thank you for your responses.

I worked at a Flex shop previously and am familiar with the Cairngorm MVC. You can consider me 'relatively' new in the .NET arena. I have a few more questions -

1) Where are you keeping the state - server? Saw the runat="server" controls on your examples. What happens when one page depends on the input values from other pages? I am used to keeping it in the Model as Value Objects.

2) How does the 'session' come into play in this?
Tania
Friday, July 25, 2008 5:50:47 AM UTC
Hi Scott,

You guys are doing great work with MVC and the Ajax helpers. One question though: why are the helpers sealed? That could be a great extensibility point for other JS frameworks.
Friday, July 25, 2008 3:14:29 PM UTC
Hi Scott!

Here is the jQuery love you asked for:
http://blog.goeran.no/PermaLink,guid,e55bfb55-ac10-48db-98a4-d28343e0f98a.aspx
Friday, July 25, 2008 3:25:39 PM UTC
Hi Scott!

Here is the jQuery love you asked for:
http://blog.goeran.no/PermaLink,guid,e55bfb55-ac10-48db-98a4-d28343e0f98a.aspx
Tuesday, July 29, 2008 5:44:29 AM UTC
Thanks for the simple post; sometimes the 2 minute ones are the best ;).
Monday, August 11, 2008 9:44:10 AM UTC
How about a new insertionmode for the Ajax helper to write to the outerHTML instead of the innerHtml therefore replacing the target completely.

Here's the scenario. I have a table and at the end of each row is a delete button when I press the delete button I want to delete the item and remove the row from the table using the Ajax.ActionLink I can set the target to the id of the row and remove the innerHTML but this doesn't completely remove the row causing the html rendering to show a couple of pixel gap where the row used to be. This makes the table look messy. I could surround the tr tags with span or div however this isn't exactly valid XHTML









Ian
Monday, August 11, 2008 10:58:30 PM UTC
I've tried with FF and all works fine.
I've tried with IE 7 and the HTML was messy after the async callback because of the way the result was rendered (the footer goes away).
I've changed the markup to fix it up: <span id="result"></span>
Tuesday, August 19, 2008 6:01:22 PM UTC
Scott,

So September it is! Ah, just kidding, but not really.
Tuesday, August 19, 2008 7:32:25 PM UTC
From personal experience, the only issue I'm having with this current setup is that the receiving action can no longer view the Request object for the value of the submitting button.

for example:

<%using (Ajax.Form("Update", new AjaxOptions { UpdateTargetId = "result" }))
{ %>
<input type="hidden" id="id" name="id" value="foo" />
<input type="submit" id="submit" name="submit" value="Add"/>
<span id="result" />
<% } %>

(note: the above code was never run, so there may be an error or two)
in the action, I cannot view the value of my submit button. I tested with the hidden input, and that worked great, but on a form that has several buttons, you need to be able to pull out the value, or have a different way of distinguishing which of the buttons was pressed.
Danny
Monday, August 25, 2008 5:31:06 PM UTC
You'd have to put the text right back into the Textbox, I'm afraid!


Hey Scott, any way to avoid this and have this app behave like an Ajax app should? I need the form data to remain in the form after the asynch form submission.
Peter
Tuesday, August 26, 2008 3:17:15 AM UTC
There´s a nice sample about ASP.NET MVC and Ajax Forms on http://sharpmasters.blogspot.com/.
Ricardo Lonzetti
Tuesday, September 09, 2008 2:24:28 AM UTC
Okay, question. How on earth do I get the javascript includes to work in my page?

Using <script type="text/javascriptscript" src="../../Content/MicrosoftAjax.debug.js"></script> certainly doesn't work! Unlike <link/> tag for CSS, where it automatically resolves it relative to current page, it doesn't do this for scripts. And I can't seem to find any other way to get it to register using code behind.

Someone save me from my stupidity trying to get this to work! :P
Jessica
Wednesday, September 10, 2008 4:18:05 AM UTC
Wow. MVC looks a lot like ruby on rails.
Barry
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.