The great Form lie

7. December 2009


The "lie"

In Asp.Net development many web form developers tend to think that a Form runat server is a necessity...
Several tutorials, bloggers tend to suggest that there must be a form (or there could be no .aspx page)

This is NOT the case, and I will show/prove it in numerous ways to rid yourself of this "lie"/misconception.

So what is a form (really) in (x)html

W3Scool has the following to tell.
There are 2 ways of sending data from a form, get and post. In Standard (x)Html one can have 0..to many forms.

There is no form

Just as in the movie "The Matrix" you must understand that there is no spoon, or Form runat server. So just because the Visual Studio template show a default form runat server does not mean one HAVE to use it, (the same can be said about the doctag!), in context it's just a text template that one can use as is or change either after creation OR the template itself.
Grasp "there is no form" and the journey  towards a more free mind with asp.net webforms development has begun.

 

About Demo1

Use standard Request Querystring/Form to retrieve standard form values, this could be done automatically in a mvc-like "autobinder" fashion on own POCO's. Always HtmlEncode value to present on page to prevent XSS, this could be done automatically on the control with attribute Mode like: <asp:Literal ID="litResult" runat="server" Mode="Encode" />

 

Demo1.aspx

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Demo1.aspx.vb" Inherits="Demo1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Demo 1 without form</title>
</head>
<body>
<h1>Demo with form - without runat server</h1>
    <asp:Literal ID="litResult" runat="server" />
   
    <h2>Form with post</h2>
    <form action="Demo1.aspx" method="post">
        <p>
            <label for="name">Name</label>
            <input type="text" id="name" name="name" />           
        </p>
        <input type="submit" value="Send" />
    </form>   
   
    <h2>Form with get</h2>
     <form action="Demo1.aspx" method="get">
        <p>
            <label for="name2">Name</label>
            <input type="text" id="name2" name="name" />           
        </p>
        <input type="submit" value="Send" />
    </form>   
</body>
</html>

Partial Class Demo1
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim name = String.Empty
        If Request.Form("name") = Nothing Then
            name = If(Request.QueryString("name"), String.Empty)
        Else
            name = Request.Form("name")
        End If

        litResult.Text = String.Format("The name is: {0}", HttpUtility.HtmlEncode(name))

    End Sub

End Class

About Demo2

Here databinding without a form is shown. Worth of interrest is the strongly typed way of databinding against a known datatype (Customer in this case) instead of the standard Eval("") - *shivers* way of reflecting the value with a magic string villain. (but more on that in a future blog post)

Demo 2

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Demo2.aspx.vb" Inherits="Demo2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>No Form runat server</title>  
</head>
<body>
    <h1>Databinding Demo with no form</h1>
    <asp:Repeater ID="Repeater1" runat="server">
        <HeaderTemplate><ul></HeaderTemplate>
        <ItemTemplate>
            <li><%#Item.ID%> - <%#Item.Name%></li>
            </ItemTemplate>
        <FooterTemplate></ul></FooterTemplate>
    </asp:Repeater>  
</body>
</html>

Partial Class Demo2
    Inherits System.Web.UI.Page


    Protected RandomInstance As New Random

    Protected ReadOnly Property Item() As Customer
        Get
            Return DirectCast(Page.GetDataItem, Customer)
        End Get
    End Property

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim customers = New List(Of Customer)
        customers.Add(New Customer() With {.ID = 42, .Name = "Alfred Futterkiste"})
        customers.Add(New Customer() With {.ID = 101, .Name = "Tomas Edwards"})

        Repeater1.DataSource = customers
        Repeater1.DataBind()

    End Sub


End Class

Public Class Customer

    Private _id As Integer
    Public Property ID() As Integer
        Get
            Return _id
        End Get
        Set(ByVal value As Integer)
            _id = value
        End Set
    End Property

    Private _name As String
    Public Property Name() As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            _name = value
        End Set
    End Property

End Class

About Demo3

Here a form "required" control is rendered in memory and the output used on a non form runat server page.

Demo 3

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Demo3.aspx.vb" Inherits="Demo3" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Demo 3</title>
</head>
<body>
    <h1>Render form runat server-controls without form</h1>
    <asp:Literal ID="litAGridComeTrue" runat="server" />
</body>
</html>

Imports System.IO

Partial Class Demo3
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Dim customers = New List(Of Customer)
        customers.Add(New Customer() With {.ID = 42, .Name = "Alfred Futterkiste"})
        customers.Add(New Customer() With {.ID = 101, .Name = "Tomas Edwards"})


        Dim g = New GridView
        g.DataSource = customers
        g.DataBind()

        Dim sb = New StringBuilder()
        Dim sw = New StringWriter(sb)

        Dim htw = New HtmlTextWriter(sw)

        g.RenderControl(htw)

        litAGridComeTrue.Text = sb.ToString
    End Sub

End Class

Finally

Hope you liked the demos, and that it removes the misconception about asp.net "required" form runat server.

// code on!

 

 

ASP.NET ,

Comments are closed