Introduction
Now you’ve got the basics of ASP.NET webforms and how to connect with database and use Datasets. But we have to admit that the code and the User Interface is ugly. So let's create a new project from scratch with the concept of a Meeting Room Reservation system in mind.
These are steps you should always take before starting a new project, but at minimum, you should at least have a sketch of the user interface for what you are going to do.

With this in mind, let's create a new Webform project and call it MRooms
. Now before you click Ok, make sure you have selected Individual User Accounts as Authentication mode. (This will generate code necessary for login and account management, and it will save you tons of time.)

To write clean code, you should have this habit of separating Data Access codes from Logic code and Userinterface code. (This is called Layered architecture, you can read more about it.) But for now, we should at least have a new layer for accessing the data so we can use this in another project when we need it. Don’t worry, it's actually very easy in Visual Studio, you only have to create projects for each layer and add reference to them.
Let's add a new project, select Class Library (.NET Framework) from Visual C# section. Make sure you didn’t select Class Library (standard) or legacy. Call it DataAccessLayer
and click OK.

Add a dataset
:

Create more queries to enable easy access for later:

Add Reference to DataAccessLayer
:

Rebuild the solution.
Add new Folder Rooms and Add new Form with master view called default.aspx.

Add GridView
and create new Datasource
linking with dataset
and tableAdapter
in DataAccessLayer
.
Add new form (NewRoom.aspx) for inserting a room. Drag and drop three TextBox
es and one Button
.
Rename the ids (your aspx file should look like this):
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master"
AutoEventWireup="true" CodeBehind="NewRoom.aspx.cs" Inherits="MRooms.Rooms.NewRoom" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<asp:TextBox ID="TextBoxName" runat="server"></asp:TextBox>
<asp:TextBox ID="TextBoxLocation" runat="server"></asp:TextBox>
<asp:TextBox ID="TextBoxDescription" runat="server"></asp:TextBox>
<asp:Button ID="ButtonNewRoom" runat="server" Text="Save Room" OnClick="Button1_Click" />
</asp:Content>
In the designer view, double-click the button and add table adapter field as:
DataAccessLayer.MRoomsDatasetTableAdapters.roomsTableAdapter rta =
new DataAccessLayer.MRoomsDatasetTableAdapters.roomsTableAdapter();
And inside Button1_Click
handler, add:
protected void Button1_Click(object sender, EventArgs e)
{
rta.Insert(TextBoxName.Text, TextBoxLocation.Text, TextBoxDescription.Text);
Response.Redirect("/rooms ");
}
Open Rooms/default.aspx:
Add this line at the end so that a link to add a new room will be displayed:
<a href="NewRoom.aspx" class="btn btn-primary">Add New Room</a>
Ok, you can run it and test adding a new room.

The add form UI is still ugly, so let's do something about it. Fortunately, Microsoft added Bootstrap (a beautiful CSS UI library). Read more if you are unfamiliar. So we can use it.
Replace NewRoom.aspx content with this (I just added some CSS elements):
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master"
AutoEventWireup="true" CodeBehind="NewRoom.aspx.cs" Inherits="MRooms.Rooms.NewRoom" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<div class="form-horizontal">
<h4>Add New Room</h4>
<hr />
<asp:ValidationSummary runat="server" CssClass="text-danger" />
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="TextBoxName"
CssClass="col-md-2 control-label">Room Name</asp:Label>
<div class="col-md-10">
<asp:TextBox ID="TextBoxName" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator runat="server"
ControlToValidate="TextBoxName"
CssClass="text-danger" ErrorMessage="The Name field is required." />
</div>
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="TextBoxLocation"
CssClass="col-md-2 control-label">Room Location</asp:Label>
<div class="col-md-10">
<asp:TextBox ID="TextBoxLocation" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator runat="server"
ControlToValidate="TextBoxLocation"
CssClass="text-danger"
ErrorMessage="The Room location field is required." />
</div>
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="TextBoxDescription"
CssClass="col-md-2 control-label">Room Description</asp:Label>
<div class="col-md-10">
<asp:TextBox ID="TextBoxDescription" runat="server"></asp:TextBox>
</div>
</div>
<asp:Button CssClass="btn btn-primary" ID="ButtonNewRoom" runat="server"
Text="Save Room" OnClick="Button1_Click" />
</div>
</asp:Content>
And on the Rooms/default.aspx, just add CssClass="table table-striped"
on the gridview
so the GridView
becomes:
<asp:GridView CssClass="table table-striped" ID="GridView1" runat="server"
AutoGenerateColumns="False" DataSourceID="ObjectDataSource1">
You can also add a title at the top (above gridview) like:
<h4>Meeting Rooms</h4>
<hr />
So the whole code becomes:
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master"
AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="MRooms.Rooms.Rooms" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h4>Meeting Rooms</h4>
<hr />
<asp:GridView CssClass="table table-striped" ID="GridView1"
runat="server" AutoGenerateColumns="False" DataSourceID="ObjectDataSource1">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False"
ReadOnly="True" SortExpression="ID" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Location" HeaderText="Location"
SortExpression="Location" />
<asp:BoundField DataField="Description" HeaderText="Description"
SortExpression="Description" />
</Columns>
</asp:GridView>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
InsertMethod="Insert" OldValuesParameterFormatString="original_{0}"
SelectMethod="GetData"
TypeName="DataAccessLayer.MRoomsDatasetTableAdapters.roomsTableAdapter">
<InsertParameters>
<asp:Parameter Name="Name" Type="String" />
<asp:Parameter Name="Location" Type="String" />
<asp:Parameter Name="Description" Type="String" />
</InsertParameters>
</asp:ObjectDataSource>
<p>
</p>
<a href="NewRoom.aspx" class="btn btn-primary">Add New Room</a>
</asp:Content>
Run and see it, and you can see it's somewhat better.

One more thing, let's change the default connection string in web.config to the database you created earlier:
Data Source=.;Initial Catalog=MRooms;Integrated Security=True

When we added Individual Accounts Authentication while creating the project, Microsoft added a local database connection to store users and another account information. By just changing the connection string to our database, it can automatically re-create the tables needed for login (like users, roles…). Run the application and try to register new user. (Register link is at the top.)
Ok, now let’s add another table for room reservation. You can do this however you like. One method is to use Visual Studio builtin database editor. Find Server Explorer window (usually a tab on the right panel next to Solution Explorer). Find your connection, right click Tables and Add new table.
Or you can just run this query (after clicking new query):
CREATE TABLE RoomReservation
(
[Id] [int] IDENTITY(1,1000) NOT NULL,
[Description] VARCHAR(MAX) NULL,
[RoomId] INT NOT NULL,
[UserId] NVARCHAR(128) NULL,
[ReservationDate] DATETIME NULL,
[DateCreated] DATETIME NULL,
CONSTRAINT [FK_RoomReservation_Room] FOREIGN KEY ([RoomId]) REFERENCES [Rooms]([Id]),
CONSTRAINT [FK_RoomReservation_User] _
FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers]([Id])
)
Let's now add the table to our dataset file so the tableAdabpter
and other codes are generated.
Open Dataset.xsd in DataAccessLayer
Project.

On the Server Explorer window, expand your database and drag RoomReservation
table to the dataset window. Right click the adapter and add Query for insert
, delete
and update
.
Rebuild the project (go to Build menu -> Rebuild). Every time you make a change to the DataAccessLayer
, you may have to rebuild. Now you may not see objects when you add datasource
.)
Just like Rooms, add a folder called Reservations and add a form with master view called default.aspx.
Open Reservations/default.aspx and Drag GridView
from tool box, add a new datasource
, just like before select object and this time, use Reservations Adapter.
Adding New Reservation
Create a new form called NewReservation
in the reservations folder. Users should select a Room
from Dropdown list, add description
and Date
to reserve the room.
Drag drop a Dropdown
and two text boxes. One for description
and another for the Date
. We only have to set the Textmode
to DateTimeLocal
(TextMode="DateTimeLocal"
), most browsers will make known its date input.
On the Dropdown
, create a datasource
and use object
and RoomTable
adapter.
Also add a button and double-click for handler, and add this inside the handler. (We just instantiated the ReservationAdapter
and use insert
function to insert from the inputs.)
DataAccessLayer.MRoomsDatasetTableAdapters.RoomReservationTableAdapter rrta =
new DataAccessLayer.MRoomsDatasetTableAdapters.RoomReservationTableAdapter();
protected void Button1_Click(object sender, EventArgs e)
{
rrta.Insert(TextBoxDescription.Text, int.Parse(DropDownRoom.SelectedValue),
null, DateTime.Parse(TextBoxDate.Text), DateTime.Now);
Response.Redirect("/reservations ");
}
Add some validation bootstrap body around it.
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master"
AutoEventWireup="true" CodeBehind="NewReservation.aspx.cs"
Inherits="MRooms.Reservations.NewReservation" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<div class="form-horizontal">
<h4>Add Reservation</h4>
<hr />
<asp:ValidationSummary runat="server" CssClass="text-danger" />
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="DropDownRoom"
CssClass="col-md-2 control-label">Room</asp:Label>
<div class="col-md-10">
<asp:DropDownList ID="DropDownRoom" runat="server"
DataSourceID="ObjectDataSource1" DataTextField="Name"
DataValueField="ID"></asp:DropDownList>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
InsertMethod="Insert" OldValuesParameterFormatString="original_{0}"
SelectMethod="GetData"
TypeName="DataAccessLayer.MRoomsDatasetTableAdapters.roomsTableAdapter">
<InsertParameters>
<asp:Parameter Name="Name" Type="String" />
<asp:Parameter Name="Location" Type="String" />
<asp:Parameter Name="Description" Type="String" />
</InsertParameters>
</asp:ObjectDataSource>
<asp:RequiredFieldValidator runat="server"
ControlToValidate="DropDownRoom"
CssClass="text-danger" ErrorMessage="The Room field is required." />
</div>
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="TextBoxDate"
CssClass="col-md-2 control-label">Reservation Date</asp:Label>
<div class="col-md-10">
<asp:TextBox ID="TextBoxDate" TextMode="DateTimeLocal"
runat="server"></asp:TextBox>
<asp:RequiredFieldValidator runat="server" ControlToValidate="TextBoxDate"
CssClass="text-danger" ErrorMessage="The Date field is required." />
</div>
</div>
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="TextBoxDescription"
CssClass="col-md-2 control-label">Room Description</asp:Label>
<div class="col-md-10">
<asp:TextBox ID="TextBoxDescription" runat="server"></asp:TextBox>
</div>
</div>
<asp:Button CssClass="btn btn-primary" ID="ButtonNewReservation"
runat="server" Text="Save Reservation" OnClick="Button1_Click" />
</div>
</asp:Content>
Run and test adding new Reservation.
So this is how you use TypedDataset
and Webforms to create datadriven applications.
In the Next Part we'll see how we use the default Indentity Authetication of .net to autherize users to Add Rooms or Reserations
Part 4-> Autherization and Clean-up (Coming soon)
History
- 5th February, 2020: Initial version