Monday, October 8, 2012

app uno

What I hope to offer in this blog posting is an exposition on how to make a very simple application using the tools that web monkeys who professionally wrangle line-of-business applications use. Some of the code that follows could be a lot better, but it is kept simple in the name of being easy to understand. This blog post is intended to just show off a bare bones app, devoid of the hand-washing professionals tend to do to tidy things up and make them as maintainable as possible. We will not cut corners on the tooling however. You should use the tools detailed here, namely Microsoft Visual Studio 2012 and Microsoft SQL Server 2012 which may be downloaded online. Both are modern (writing this in 2012), industry standard tools for working with the Microsoft stack where there is a lot of work being done on line-of-business applications currently (again, in 2012). Visual Studio will stop working after a month without an expensive license. I do not know the best way to hack around this problem. Perhaps setting up VMs as detailed here and then reinstalling the software fresh on VMs may do the trick. I am not sure if one can get away with that or not. But, without further ado, assume that you would like to keep a contact list of your friends, Brad, Janet, and Vladimir Putin, on your laptop (which runs Microsoft Windows 7) which is viewable as a web page like so:

Share photos on twitter with Twitpic

To make a file like this, you can make a .txt file on your desktop and rename the file so that it instead has an .html extension. You can then right-click on the file to open it in Notepad and paste in this copy which is of a language called HTML (HyperText Markup Language):

<html>
   <body>
      <h1>My Rolodesk:</h1>
      <table>
         <tr>
            <th>Name</th>
            <th>Phone</th>
            <th>Email</th>
         </tr>
         <tr>
            <td>Brad</td>
            <td>(512) 335-9517</td>
            <td>brad@x.com</td>
         </tr>
         <tr>
            <td>Janet</td>
            <td>(512) 219-1316</td>
            <td>janet@damnit.com</td>
         </tr>
         <tr>
            <td>Vladimir Putin</td>
            <td>(512) 657-0229</td>
            <td>vlad.poo@example.com</td>
         </tr>
      </table>
   </body>
</html>

 
 

If you will save the file and then open it just by double-clicking upon it, you should see the content shown off in the topmost image in this blog posting. This sort of simple content was what Marc Andreessen's World Wide Web was all about in its infancy in the mid 1990s. This sort of content could be hosted as a web page that others could find online, or, in our case, could just sit standalone on someone's laptop. HTML is just one of four varieties of code that I would like to show off however. The others are SQL, ASP.NET with C# and JavaScript. These other three are needed because it turns out there are some things that HTML cannot do on its own that would be really useful. What if you wanted to be able to add a record to your list of contacts without editing in the HTML language that you have recently learned? What if you want your Mom to add to your contacts for you at the same time she is doing your laundry? (I'm just kidding.) Well, your Mom is going to have a tough time wrangling HTML right? Maybe things need to be made more user friendly so that anyone could add a contact through a form. You cannot do this with HTML alone. The first step towards this is to spin up a new database in Microsoft SQL Server 2012. We will make a table to represent our data like so:

Share photos on twitter with Twitpic

We have made a table that represents the data for Brad, Janet, and Vladimir Putin. We have four columns instead of three however. One of the columns, Id, contains a Guid for each row in the database and serves as a unique identifier. This is good policy in database design. The table can be created with SQL (Structured Query Language) which is a language for making database tables like this and manipulating them. The code to make our table is:

/* To prevent any potential data loss issues, you should review this script in detail before
      running it outside the context of the database designer.*/
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.MyDatabaseTable
   (
   Id uniqueidentifier NULL,
   Name varchar(50) NOT NULL,
   Phone varchar(50) NOT NULL,
   Email varchar(50) NOT NULL
   ) ON [PRIMARY]
GO
ALTER TABLE dbo.MyDatabaseTable SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
select Has_Perms_By_Name(N'dbo.MyDatabaseTable', 'Object', 'ALTER') as ALT_Per,
      Has_Perms_By_Name(N'dbo.MyDatabaseTable', 'Object', 'VIEW DEFINITION') as
      View_def_Per, Has_Perms_By_Name(N'dbo.MyDatabaseTable', 'Object', 'CONTROL')
      as Contr_Per

 
 

One could just use the database to keep contacts, but your Mom might have trouble using this too. Instead, I think we should make the database data bled into our web page, replacing the static data typed in there. Strictly speaking, we will need to forgo our web page and instead spin up an ASP.NET Web Forms Application in Visual Studio as this will allow us to do a few things we will need.

Share photos on twitter with Twitpic

Once we make an application we can preview it in Visual Studio. The home page of the application will appear in a web browser and will look like so.

Share photos on twitter with Twitpic

The code for the page will appear as such. The tags with percent symbols and colons in them are special tags not of HTML but instead of ASP.NET. They will render to HTML tags when we preview them in a browser (so to speak).

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master"
      AutoEventWireup="true" CodeBehind="Default.aspx.cs"
      Inherits="MyApplication._Default" %>
   
<asp:Content runat="server" ID="FeaturedContent"
      ContentPlaceHolderID="FeaturedContent">
   <section class="featured">
      <div class="content-wrapper">
         <hgroup class="title">
            <h1><%: Title %>.</h1>
            <h2>Modify this template to jump-start your ASP.NET application.</h2>
         </hgroup>
         <p>
            To learn more about ASP.NET, visit <a href="http://asp.net" title="ASP.NET
                  Website">http://asp.net</a>.
            The page features <mark>videos, tutorials, and samples</mark> to help you get
                  the most from ASP.NET.
            If you have any questions about ASP.NET visit
            <a href="http://forums.asp.net/18.aspx" title="ASP.NET Forum">our forums</a>.
         </p>
      </div>
   </section>
</asp:Content>
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
   <h3>We suggest the following:</h3>
   <ol class="round">
      <li class="one">
         <h5>Getting Started</h5>
         ASP.NET Web Forms lets you build dynamic websites using a familiar drag-and-
               drop, event-driven model.
         A design surface and hundreds of controls and components let you rapidly build
               sophisticated, powerful UI-driven sites with data access.
         <a href="http://go.microsoft.com/fwlink/?LinkId=245146">Learn more…</a>
      </li>
      <li class="two">
         <h5>Add NuGet packages and jump-start your coding</h5>
         NuGet makes it easy to install and update free libraries and tools.
         <a href="http://go.microsoft.com/fwlink/?LinkId=245147">Learn more…</a>
      </li>
      <li class="three">
         <h5>Find Web Hosting</h5>
         You can easily find a web hosting company that offers the right mix of features and
               price for your applications.
         <a href="http://go.microsoft.com/fwlink/?LinkId=245143">Learn more…</a>
      </li>
   </ol>
</asp:Content>

 
 

We will now bring in our prior HTML content. Some of it will be recreated, but we can just copy this tag from our original document.

<h1>My Rolodesk:</h1>

 
 

We will splice it into the code between the second set of asp:Content tags, dropping all of the prior content there first. We will also drag a GridView control from the Toolbox to below our H1 tag.

Share photos on twitter with Twitpic

The code now looks like this:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master"
      AutoEventWireup="true" CodeBehind="Default.aspx.cs"
      Inherits="MyApplication._Default" %>
   
<asp:Content runat="server" ID="FeaturedContent"
      ContentPlaceHolderID="FeaturedContent">
   <section class="featured">
      <div class="content-wrapper">
         <hgroup class="title">
            <h1><%: Title %>.</h1>
            <h2>Modify this template to jump-start your ASP.NET application.</h2>
         </hgroup>
         <p>
            To learn more about ASP.NET, visit <a href="http://asp.net" title="ASP.NET
                  Website">http://asp.net</a>.
            The page features <mark>videos, tutorials, and samples</mark> to help you get
                  the most from ASP.NET.
            If you have any questions about ASP.NET visit
            <a href="http://forums.asp.net/18.aspx" title="ASP.NET Forum">our forums</a>.
         </p>
      </div>
   </section>
</asp:Content>
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
   <h1>My Rolodesk:</h1>
   <asp:GridView ID="GridView1" runat="server"></asp:GridView>
</asp:Content>

 
 

In order to let ASP.NET bind database data to our GridView control we will need to alter the code behind file for our web form. The code behind file is written in C# and starts out looking like so:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
   
namespace MyApplication
{
   public partial class _Default : Page
   {
      protected void Page_Load(object sender, EventArgs e)
      {
         
      }
   }
}

 
 

We alter it to this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Data;
   
namespace MyApplication
{
   public partial class _Default : Page
   {
      protected void Page_Load(object sender, EventArgs e)
      {
         SqlConnection connection = new
               SqlConnection(@"server=.\TWENTYTWELVE;database=MyDatabase;
               Integrated Security=true;");
         SqlCommand command = new SqlCommand();
         SqlDataAdapter adapter = new SqlDataAdapter();
         DataSet dataSet = new DataSet();
         string query = "SELECT * FROM MyDatabaseTable";
         command.CommandText = query;
         command.CommandType = CommandType.Text;
         command.Connection = connection;
         adapter.SelectCommand = command;
         adapter.Fill(dataSet);
         GridView1.DataSource = dataSet;
         GridView1.DataBind();
      }
   }
}

 
 

When we preview our project we see this:

Share photos on twitter with Twitpic

Note that this piece of code in the code behind is a SQL statement that is run against our database to get all of the data in our table.

SELECT * FROM MyDatabaseTable

 
 

If we view the HTML the browser is receiving we will see that our GridView is becoming HTML that looks not unlike the other HTML we originally wrote. This is a good example of how ASP.NET tags behave differently yet similar too regular HTML tags.

Share photos on twitter with Twitpic

The HTML made by our H1 tag and GridView is:

   <h1>My Rolodesk:</h1>
   <div>
   <table cellspacing="0" rules="all" border="1" id="MainContent_GridView1"
         style="border-collapse:collapse;">
      <tr>
         <th scope="col">Id</th><th scope="col">Name</th><th scope="col">Phone</th>
               <th scope="col">Email</th>
      </tr><tr>
         <td>71352ec1-63a8-4f7f-a30c-8d4a042ee301</td><td>Brad</td><td>(512) 335-
               9517</td><td>brad@x.com</td>
      </tr><tr>
         <td>3be815ae-83ce-4892-881c-86d85d2ff316</td><td>Janet</td><td>(512) 219-
               1316</td><td>janet@damnit.com</td>
      </tr><tr>
         <td>519f3334-4fbc-4fd6-91e0-265e7ea2c7db</td><td>Vladimir Putin</td><td>(512)
               657-0229</td><td>vlad.poo@example.com</td>
      </tr>
   </table>
</div>

 
 

Now we will make a form to shove data into our database table as a new row. If we made the form in our original HTML it might look like so:

Share photos on twitter with Twitpic

The code would be revised as such:

<html>
   <body>
      <h1>My Rolodesk:</h1>
      <table>
         <tr>
            <th>Name</th>
            <th>Phone</th>
            <th>Email</th>
         </tr>
         <tr>
            <td>Brad</td>
            <td>(512) 335-9517</td>
            <td>brad@x.com</td>
         </tr>
         <tr>
            <td>Janet</td>
            <td>(512) 219-1316</td>
            <td>janet@damnit.com</td>
         </tr>
         <tr>
            <td>Vladimir Putin</td>
            <td>(512) 657-0229</td>
            <td>vlad.poo@example.com</td>
         </tr>
      </table>
      <h1>Add an entry:</h1>
      Name: <input name="Name" />
      <br />
      Phone: <input name="Phone" />
      <br />
      Email: <input name="Email" />
      <br />
      <button type="submit">Submit</button>
   </body>
</html>

 
 

But, there is no way to make our form speak to our database table with HTML alone so we should instead have our form inside our ASP.NET web form in our ASP.NET project. We will copy and paste it there:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master"
      AutoEventWireup="true" CodeBehind="Default.aspx.cs"
      Inherits="MyApplication._Default" %>
   
<asp:Content runat="server" ID="FeaturedContent"
      ContentPlaceHolderID="FeaturedContent">
   <section class="featured">
      <div class="content-wrapper">
         <hgroup class="title">
            <h1><%: Title %>.</h1>
            <h2>Modify this template to jump-start your ASP.NET application.</h2>
         </hgroup>
         <p>
            To learn more about ASP.NET, visit <a href="http://asp.net" title="ASP.NET
                  Website">http://asp.net</a>.
            The page features <mark>videos, tutorials, and samples</mark> to help you get
                  the most from ASP.NET.
            If you have any questions about ASP.NET visit
            <a href="http://forums.asp.net/18.aspx" title="ASP.NET Forum">our forums</a>.
         </p>
      </div>
   </section>
</asp:Content>
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
   <h1>My Rolodesk:</h1>
   <asp:GridView ID="GridView1" runat="server"></asp:GridView>
      <h1>Add an entry:</h1>
      Name: <input name="Name" />
      <br />
      Phone: <input name="Phone" />
      <br />
      Email: <input name="Email" />
      <br />
      <button type="submit">Submit</button>
</asp:Content>

 
 

What we create looks like so:

Share photos on twitter with Twitpic

Now our code behind must change to be able to push a record into our table:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Data;
   
namespace MyApplication
{
   public partial class _Default : Page
   {
      protected void Page_Load(object sender, EventArgs e)
      {
         SqlConnection connection = new
               SqlConnection(@"server=.\TWENTYTWELVE;database=MyDatabase;
               Integrated Security=true;");
         if (Page.IsPostBack)
         {
            connection.Open();
            SqlCommand insert = new SqlCommand("INSERT INTO MyDatabaseTable (Id,
                  Name, Phone, Email) VALUES ('" + Guid.NewGuid() + "','" +
                  Request.Form["Name"] + "','" + Request.Form["Phone"] + "','" +
                  Request.Form["Email"] + "')", connection);
            insert.ExecuteNonQuery();
            connection.Close();
         }
         SqlCommand command = new SqlCommand();
         SqlDataAdapter adapter = new SqlDataAdapter();
         DataSet dataSet = new DataSet();
         string query = "SELECT * FROM MyDatabaseTable";
         command.CommandText = query;
         command.CommandType = CommandType.Text;
         command.Connection = connection;
         adapter.SelectCommand = command;
         adapter.Fill(dataSet);
         GridView1.DataSource = dataSet;
         GridView1.DataBind();
      }
   }
}

 
 

Our code behind empowers us to add a record for Karen. To add a record for Karen we will ultimately run this line of SQL:

INSERT INTO MyDatabaseTable (Id, Name, Phone, Email) VALUES ('0d9d4a70-64bb-42ff-a19c-707134c54827','Karen','(512) 419-8788','karen@something.com')

 
 

Karen will show up like so when we preview our app:

Share photos on twitter with Twitpic

Karen will show up like so when we look at our database table:

Share photos on twitter with Twitpic

We are there. We have a way to add records to our web page that holds our contacts. Brad, Janet, Vladimir Putin, and Karen are now all collected together and we may give them other playmates easily whenever we please. As you can see, we are just getting started. There is a lot not to like about this set up. For example, what if we have a typo in a record? It would be good to create a way to edit records, maybe even delete records. All that is a little bit more than the scope of this example however. One enhancement I will offer is to use JavaScript to ensure that one cannot submit the form without filling out all of the form fields. That will keep a user from entering a partial record accidentally. This trick will work in most browsers. We will need to reference the jQuery library that is part of our Visual Studio project. Here is our revised web form. The stuff in the second script tag is a type of code known as JavaScript.

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master"
      AutoEventWireup="true" CodeBehind="Default.aspx.cs"
      Inherits="MyApplication._Default" %>
   
<asp:Content runat="server" ID="FeaturedContent"
      ContentPlaceHolderID="FeaturedContent">
   <section class="featured">
      <div class="content-wrapper">
         <hgroup class="title">
            <h1><%: Title %>.</h1>
            <h2>Modify this template to jump-start your ASP.NET application.</h2>
         </hgroup>
         <p>
            To learn more about ASP.NET, visit <a href="http://asp.net" title="ASP.NET
                  Website">http://asp.net</a>.
            The page features <mark>videos, tutorials, and samples</mark> to help you get
                  the most from ASP.NET.
            If you have any questions about ASP.NET visit
            <a href="http://forums.asp.net/18.aspx" title="ASP.NET Forum">our forums</a>.
         </p>
      </div>
   </section>
</asp:Content>
<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
   <h1>My Rolodesk:</h1>
   <asp:GridView ID="GridView1" runat="server"></asp:GridView>
      <h1>Add an entry:</h1>
      Name: <input name="Name" />
      <br />
      Phone: <input name="Phone" />
      <br />
      Email: <input name="Email" />
      <br />
      <button type="submit">Submit</button>
   <script src="/Scripts/jquery-1.7.1.js" type="text/javascript"></script>
   <script type="text/javascript">
      jQuery(document).ready(function () {
         $("form").submit(function () {
            var emptyField = false;
            var inputs = document.getElementsByTagName("input");
            if (inputs["Name"].value == "") emptyField = true;
            if (inputs["Phone"].value == "") emptyField = true;
            if (inputs["Email"].value == "") emptyField = true;
            if (emptyField) {
               alert('Be careful! You have yet not filled out all of the form fields!');
               return false;
            } else {
               return true;
            }
         });
      });
   </script>
</asp:Content>

 
 

We get this error if we try to submit our form with an empty field. The submission will be blocked. We will not write a partial record to our database table.

Share photos on twitter with Twitpic

Again, and in conclusion, we have a my-first-app sort of app here. Does this make sense?

No comments:

Post a Comment