If you are an ASP.NET Web Forms programmer making the switch to ASP.NET MVC – what’s the first thing you should learn?
There are lots of candidates for the number one spot. Some people will say the first thing to do is learn and embrace the spirit of the MVC design pattern. Others might say you should learn how to unit test a controller, or learn how to use a view model.
Learn how to use an HTML <form>.
Please excuse the ASP.NET web forms programmer who forgets about the <form> tag. Although every .aspx file has one, they never need to touch it, or even look at it. The form tag is not only well hidden, but also constrained. It only take a few years to start thinking the web revolves around pages that only submit information back to themselves.
The most important things to lean (or relearn) are:
Let’s look at each case.
There are two types of requests a web browser will use when communicating with a web server – POST requests and GET requests. Both are designed to do what they sound like – GET a response, or POST some information and receive a response. Web forms always use POST methods. HTTP POST is the best method to use when you are submitting information to a web server and changing state in your application. For example, if a user fills out a <form> with textbox and radio button controls full of patient information you want to save in a database, then POST is the HTTP method you should use. The browser will POST the user’s values to the server where you can save them in the database, and then you can respond and tell the user everything worked (or tell them something blew up).
On the other hand, an HTTP GET operation operation is the best way to submit information to a server when you are not changing state inside the application. The best example is a form used to search for information. You need to send search parameters to the server, but the search parameters aren’t creating new records in a database – they are only used as to query information.
<form action="/search" method="get"> <input type="text" name="searchTerm" /> <input type="submit" value="Search" /> </form>
If the user enters “baby blue bathysphere” into the textbox and clicks the button, the browser will send off a GET request with the following URL:
/search?searchTerm=baby+blue+bathysphere
Notice how the submitted form values are placed in the URL itself. Not only is a GET operation cacheable, but users can also bookmark the response to a GET submission because all the information needed to produce the page is in the URL. GET is the default value for the method attribute of a <form>, so if you don’t specify the method you’ll have a GET by default.
ASP.NET web forms always POST to themselves, which can be limiting. As the previous example demonstrates, you can set the action attribute to submit a form to any URL, even a URL pointing to another application on a different server. For example, the following HTML would send the user to Google (both Google and Bing both expect the search parameter to have the name “q”).
<form action="http://google.com/search" method="get"> <input type="text" name="q" /> <input type="submit" value="Search" /> </form>
You’ll usually be setting the action attribute to submit information to some controller action in your MVC application. The Html.BeginForm helpers will help build the correct <form> tag to reach the desired action for you. If we were using the first code-snippet in this post (the one with an action of “/search”), we could respond to the search request with the default action of a SearchController. The MVC framework can automatically pass the searchTerm form parameter as a parameter to the action.
public class SearchController : Controller { public ActionResult Index(string searchTerm) { // .... return View(); } }
Well … not always.
There are times when having multiple <form> tags on a page is a good idea. You can have two distinct pieces of a page submit information to two different URLs. Multiple <form> tags regularly make sense on portal type pages that contain multiple sections with disparate functionality. Like an area that lets a user get a stock quote, and an area that lets a user search for a movie. These are two different tasks that will probably best be handled by two different controllers, two different URLs, two different forms, and two different sets of input controls.
<form action="/stock/quote"> <input type="text" name="symbol" /> <input type="submit" value="Quote It!" /> </form> <!-- ... ---> <form action="/movie/search"> <input type="text" name="q" /> <input type="submit" value="Search" /> </form>
Not every scenario requires multiple forms, however. Sometimes you want a single form to provoke different behaviors from the server. For example, imagine a shopping page where a user selects some check boxes for products they are interested in. You might need a button allowing the user to submit this information to “compare products” and another button allowing the user to save the selected items in a “wish list”. Both buttons need to submit the same information to the server, so they’ll probably live inside the same form
<form action="products/shop" method="post"> <!-- --> <input type="submit" name="task" value="Compare" /> <input type="submit" name="task" value="Save to wish list" /> </form>
Both buttons in the above form will force the browser to POST to products/shop. Notice how both buttons have the same value for the name attribute, but their values are different. In an MVC application you can create a controller to accept this form submission:
public class ProductsController : Controller { [AcceptVerbs(HttpVerbs.Post)] public ActionResult Shop(string task) { // ... return View(); } }
The value of the task parameter in the Shop action will contain the value of the button – either “Compare” or “Save to wish list”. You can inspect this value and decide what to do next.
Having <form> tags available to due your bidding in an MVC application allows you a great deal of flexibility and control. Every bit you learn about using forms will give you an edge in building your application. Experiment with them, read about them, and learn to love them!
Comments
@Shiju - thanks!
Reminds me of good old classic ASP, where one had to write vbscript mixed with html.
<input type="submit"....
<%= %>
Too much of wrapped functionality & one loses the control over basic things. It has happened with webforms.
Good post as always.
In fairness to web forms it would be worth mentioning that as of ASP.NET 2.0 it is possible to post form data to different URLs using the Cross Page Posting property.
thanx
I'm going back to learn Html <Form></Form>
the best thing to learn the basis of thing
thaaaaaanx
Only if you use webcontrols in your aspx directly who in turn needs a form (like textbox, datagrid etc)
You can use Repeater WITHOUT a form, you can even use multiple html STANDARD form, with get/post with .aspx. If one use regular html lika input type text you don't need Form runat server (what about databinding?) use similar/same technique to bind from post variables like MVC does...
you could also render a gridview in memory and put the generated HTML to a say lika a literalcontrol.
I concur that WebForms developers should REALLY learn standard (x)html before touching webcontrols.
Dirty is as dirty does. I've seen some very dirty web forms apps in my time.
Web Forms attempted to solve this by isolating presentation in the .aspx page and putting application logic in the code-behind.
This works, even tho sometimes you have to do odd things in the code-behind to output appropriate things in the HTML from time to time.
It's definitely better than classic ASP, but the real problem is that application logic doesn't belong in the presentation layer at all!
You can use web forms "correctly" to solve this problem by creating business objects and static methods, etc... but MVC, by design, actually *forces* us to move the application logic into the controller where it belongs. So, it is hard to be lazy and do things the wrong way.
Which is good because it leaves us with a much more basic set of data to deal with in the view, data that is much more tuned to being handled with these techniques that feel more like classic ASP.
Both approaches are valid - I don't think there is any intention to convert all web forms folks or projects to MVC but it is probably a better approach for certain types of problems.
I'd suggest anybody who hasn't tried it to grab a sample and work through it a bit and you'll see how refreshing it can be.
What exactly is the function of the MVC Framework and what is so "revolutionary" about it?
Really i never thought of this...Great Post ..Thank you Scott
Actions
ASP.NET web forms always POST to themselves"
I am confused:
when the POST is default
and
when the GET is?
For an HTML form tag the default is a GET.
In ASP.NET Web Forms the server side form (the form tag with runat="server") that ASP.NET writes out always uses method="post", so when you are using web forms ASP.NET overrides the default to always POST to themselves.