.NET Portfolio
-
Upload
ron-deliteris -
Category
Technology
-
view
718 -
download
2
description
Transcript of .NET Portfolio
V. Ron DeliterisC# .NET Developer – Design Portfolio
V. Ron Deliteris [email protected] Page 2 of 41
Table of Contents
Projects:
SetFocus – .NET Framework................................................................................3
SetFocus – Library Phase I (Windows Forms) ......................................................8
Library Phase I Screens:.................................................................................................... 11
Presentation tier (MemberInfo Method Code): ................................................................ 13
SetFocus – Library Phase II (ADO.NET) ..............................................................16
Library Database (tables and relationships): ..................................................................... 18
LibraryPhase II Forms: ...................................................................................................... 19
Presentation tier (AddAdult Method Code): ..................................................................... 20
SQL Server 2005 (AddAdult Stored Procedure): ................................................................ 21
DataAccess Tier (AddAdult Method - call to SQL Server Stored Procedure): ...................... 24
SetFocus – Library Phase III (ASP.NET) ..............................................................25
Library Phase III Web Pages:............................................................................................. 27
Web Application (CheckIn Method Code): ........................................................................ 29
XML (Creates controls for CheckIn web page): .................................................................. 31
SetFocus – Library Phase IV (Web Services).......................................................33
Web Services-Service.asmx Pages (View in Browser): ....................................................... 34
Web Services Coding (Web Methods, SoapException, Attributes, etc): ............................. 36
Web Services (Web Pages): .............................................................................................. 38
Web Services Code (AddCopy - Web Application): ............................................................ 39
V. Ron Deliteris [email protected] Page 3 of 41
SetFocus – .NET Framework
Introduction:
This project is designed for use by a retail company. I was responsible for building parts of the
business tier. The first assembly is a class library project called Foundation. It contains various
interfaces and base classes. The second assembly is also a class library project called AppTypes.
It contains various entity, collection, and exception classes used by various business processes.
Summary:
The goal of this project was to create and test two assemblies. This project will demonstrate
fundamental .NET skills and interaction between an n-tiered application. Listed below are the
C#.NET skills used in this project:
• Delegates, events
• Custom exception/attribute classes
• Custom EventArgs classes
• Event logger and collection classes
• Generic Collections
• Custom Serializations
• Bianry & SOAP Formatters
• Abrstact classes & interfaces
• Enumerations
• Properties
• Custom Enumerators Implementation of ISerializable, IComparer, IComparable, &
IList<T> interfaces
V. Ron Deliteris [email protected] Page 4 of 41
SetFocus – .NET Framework
Foundation Assembly:
This assembly contains the foundation interfaces and base classes used throughout the project.
V. Ron Deliteris [email protected] Page 5 of 41
SetFocus – .NET Framework
AppTypes Assembly:
This assembly contains various entity, collection, and exception classes used by the business
tier.
Continued on next page…
V. Ron Deliteris [email protected] Page 6 of 41
SetFocus – .NET Framework
AppTypes Assembly (continued):
V. Ron Deliteris [email protected] Page 7 of 41
SetFocus – .NET Framework
A TestUI was provided to test my code. It was supplied for this project as a pair of dll files and a
Visual Studio project called TestHarness. The TestUI project was added to my Solution for test
purposes only. The TestUI project was set as the default project. The form below is from the
TestUI project. My name is inserted so it can be included on the Windows application which
displays completion results and scores for each phase of the projects completion.
V. Ron Deliteris [email protected] Page 8 of 41
SetFocus – Library Phase I (Windows Forms)
Introduction:
For this project, I was responsible for developing a Windows Forms based front-end application
that will provide a librarian with a visual interface through which day-to-day operations are
performed. The required functionality includes adding new members (adult and juvenile) and
checking books in and out.
Audience:
This project is designed for library personnel to carry out typical library functions, such as
adding a new member (both adult and juvenile) and checking books in and out.
Summary:
The project demonstrates the use of .NET
Windows Forms development techniques.
Some of the techniques used include:
• User input validation and feedback
using erorr poviders
• Data binding to a DataGridView
control and manipulation of the
control
• Incorporate n-tier architecture for
scalability
• Create a user interface that is intuitive
and requires minimal training
• Use of effective error handling messages
• Use of RegularExpressions for input
validation
V. Ron Deliteris [email protected] Page 9 of 41
SetFocus - Library Phase I (Windows Forms)
Description:
To make the interface intuitive, I utilized MDI parent and child technology. All functions were
accessed through the menu control located on the Parent form.
The Client Layer (RD.LibraryWinClient) provided the code behind the user interface to handle all
the input validations, screen changes and contained the logic to perform each operation.
The Business Layer (RD.LibraryBusiness) provided the connection between the UI and the
library Data Access functions. In this project, all book information, member records, loan
records, etc. are all stored in a SQL Server 2005 database. Access to the database occurred
through a Data Access Layer, which was provided as a pre-compiled DLL file for the project.
The UI does not know how the data is accessed or retrieved. If changes are needed to how the
data is accessed, the front-end does not need to be modified, providing for scalibility.
Functionality Details:
Add Adult Member – The required fields are First and Last name, Street, City, State, and
Zipcode. Middle Initial and Phone Number are optional fields.
Add Juvenile Member – The required fields are First and Last name, Birthdate, and sponsoring
Adult Member ID. Middle Initial is an optional filed.
Rules for validating input data when adding members and checking books in and out:
• First and Last name fields are required and must contain no more than 15 alphabetic
characters. The first character of each of these fields is required to be uppercase with
the remaining characters in lowercase.
• Middle Initial (optional). If entered it must be a single uppercase alphabetic character.
• Street address and City fields must be non-empty strings (no spaces), and must contain
no more than 15 characters in length each.
• State field must be two uppercase characters. It is chosen from a ListBox that is
populated from an XML file.
V. Ron Deliteris [email protected] Page 10 of 41
SetFocus - Library Phase I (Windows Forms)
• Zipcode field must be a non-empty string (no spaces) in the format ##### or #####-
####, where # is a digit (0-9).
• Phone Number (optional). If entered it must be in the format (###)###-####. There can
be no space after the closing paren.
• Birthdate is required when adding a Juvenile Member. It must be a valid date in the
format (mm/dd/yyyy), and it must fall within the eighteen-year period ending on the
current date.
• Sponsoring Adult Member is required when adding a Juvenile Member. It has to
reference a valid Adult Member already in the database. It must be validated to contain
only a numeric value in the range of 1 through 32767 inclusive.
• Each member can have a maximum of 4 books checked out at a time. Checking out a
book also requires that the membership’s expiration date be in the future (membership
NOT expired).
• If a book was requested to be checked out, but the database indicates it was already on
loan, the librarian was prompted if they wanted to check the book in first.
• All functions like checking out or checking in a book, and adding a new member (either
adult or juvenile) provides a method for the librarian to cancel the operation.
V. Ron Deliteris [email protected] Page 11 of 41
SetFocus - Library Phase I (Windows Forms)
Library Phase I Screens:
MDI Parent Form (Presentation tier):
All the library functions are accessible through the MDI Parent menu control called Member
Services.
V. Ron Deliteris [email protected] Page 12 of 41
SetFocus - Library Phase I (Windows Forms)
MemberInfo Form (Presentation tier):
This screen shot is of the Member information form, displaying a Juvenile member and current
books that are on loan to this member. The form is contained within an MDI parent. This
membership has expired as indicated by the field highlighted in RED. If there are no books on
loan for a member. The Check In Selected Books button will not be in focus because there is
nothing to check in (no books checked out).
V. Ron Deliteris [email protected] Page 13 of 41
SetFocus - Library Phase I (Windows Forms)
Presentation tier (MemberInfo Method Code):
private void GetMemberInfoButton_Click(object sender, EventArgs e)
{
this.toolStripStatusLabel1.Text = "";
// Verify controls validated in validation methods
if ( !this.ValidateChildren( ValidationConstraints.ImmediateChildren ) )
return;
short memberid = Convert.ToInt16(MemberIDTextBox.Text);
Member m;
try
{
//Check if member # is Adult or Juv and then display member info
BusinessLayer bl = new BusinessLayer();
m = bl.GetInformation( memberid );
if ( m == null )
{
// Member ID box is empty.
this.toolStripStatusLabel1.Text = "Must enter Member ID";
return;
}
if ( m is AdultMember )
{
// Select all characters in MemberIDTextBox
MemberIDTextBox.SelectAll();
juvenilePanel.Visible = false;
AdultMember adult = m as AdultMember;
// Access to Adult member properties now, so populate Adult TextBox fields
ExpDateTextBox.Text = adult.ExpirationDate.ToShortDateString();
FirstNameTextBox.Text = adult.FirstName;
if ( adult.MiddleInitial != null )
MiddleInitialTextBox.Text = adult.MiddleInitial;
LastNameTextBox.Text = adult.LastName;
StreetTextBox.Text = adult.Street;
CityTextBox.Text = adult.City;
StateTextBox.Text = adult.State;
ZipCodeTextBox.Text = adult.ZipCode;
if ( adult.PhoneNumber != null )
PhoneTextBox.Text = adult.PhoneNumber;
}
else
{
// Select all characters in MemberIDTextBox
MemberIDTextBox.SelectAll();
juvenilePanel.Visible = true;
JuvenileMember juvenile = m as JuvenileMember;
// Access to Juv member properties now, so populate Juv TextBox fields
ExpDateTextBox.Text = juvenile.ExpirationDate.ToShortDateString();
AdultMemberIdTextBox.Text = juvenile.AdultMemberID.ToString();
Continued on next page…
V. Ron Deliteris [email protected] Page 14 of 41
SetFocus - Library Phase I (Windows Forms)
JuvenileBirthDateTextBox.Text = juvenile.BirthDate.ToShortDateString();
FirstNameTextBox.Text = juvenile.FirstName;
if ( juvenile.MiddleInitial != null )
MiddleInitialTextBox.Text = juvenile.MiddleInitial;
LastNameTextBox.Text = juvenile.LastName;
StreetTextBox.Text = juvenile.Street;
CityTextBox.Text = juvenile.City;
StateTextBox.Text = juvenile.State;
ZipCodeTextBox.Text = juvenile.ZipCode;
if ( juvenile.PhoneNumber != null )
PhoneTextBox.Text = juvenile.PhoneNumber;
}
// Select all characters in MemberIDTextBox
MemberIDTextBox.SelectAll();
// Change Form name in TitleBar, to Member Name when it is retrieved,
// and format it like this: "John H Doe (memberid)"
this.Text = string.Format("{0} {1} {2} ({3})", FirstNameTextBox.Text,
MiddleInitialTextBox.Text, LastNameTextBox.Text, memberid);
}
catch (LibraryException lex)
{
if ( lex.LibraryErrorCode == ErrorCode.NoSuchMember )
{
// Select all characters in MemberIDTextBox
MemberIDTextBox.SelectAll();
// MemberID not found, so clear all TextBoxes & send status bar message
clearInfoTextBoxes();
copyDataGridView.DataSource = "";
this.Text = string.Format("Get Member Information");
this.toolStripStatusLabel1.Text = "Member ID: " +
memberid + " was not found.";
// When member not found, disable the Check out form
frmMDIParent fmp = (frmMDIParent)this.MdiParent;
fmp.checkOutMenu.Enabled = false;
}
else
{
// Select all characters in MemberIDTextBox
MemberIDTextBox.SelectAll();
this.toolStripStatusLabel1.Text = lex.Message;
}
return;
}
//Set memberid in MDIParent
frmMDIParent f = (frmMDIParent)this.MdiParent;
f.memberid = memberid;
Continued on next page…
V. Ron Deliteris [email protected] Page 15 of 41
SetFocus - Library Phase I (Windows Forms)
try
{
//Display books on loan to member
BusinessLayer bl = new BusinessLayer();
ItemsDataSet ids = bl.GetItems(memberid);
frmMDIParent fmp = (frmMDIParent)this.MdiParent;
copyDataGridView.DataSource = ids.Tables[0];
if ( ids.Items.Count > 0 )
{
ChkInSelectedBooksButton.Enabled = true;
}
else
ChkInSelectedBooksButton.Enabled = false;
// Check if items are > 4 and Expiration Date is >= today's date
if ( ids.Items.Count < 4 && m.ExpirationDate >= DateTime.Today)
{
fmp.checkOutMenu.Visible = true;
fmp.checkOutMenu.Enabled = true;
}
else
{
fmp.checkOutMenu.Visible = true;
fmp.checkOutMenu.Enabled = false;
}
// Expiration Date validation to highlight memberId if expired
if (m.ExpirationDate < DateTime.Today)
{
ExpDateTextBox.BackColor = Color.Red;
ExpDateTextBox.ForeColor = Color.White;
}
else
{
ExpDateTextBox.BackColor = Color.White;
ExpDateTextBox.ForeColor = Color.Black;
}
}
catch (LibraryException lex)
{
// Incorrect MemberID, so clear the DataGridView.DataSource
copyDataGridView.DataSource = "";
this.toolStripStatusLabel1.Text = lex.Message;
return;
}
}
V. Ron Deliteris [email protected] Page 16 of 41
SetFocus – Library Phase II (ADO.NET)
Introduction:
Library Phase I created the UI tier for a library management system. This project created the
Data Access tier and SQL Server Stored Procedures for the library application to replace the
ones provided in a DLL in Phase 1.
Summary:
This project demonstrates the use of ADO.NET and Transact-SQL (T-SQL) to access a SQL Server
2005 database. Some of the techniques used include:
• Create and implement the Entities classes used in the library project
• Create stored procedures using Transact-SQL (T-SQL) on SQL Server 2005
• Data validation completed in stored procedures using T-SQL
• Create and utilize strongly typed datasets based on stored procedures
• Implemented error handling in stored procedures using T-SQL
• Accessing stored procedures through System.Data.SqlClient (ADO.NET)
• Retrieve and process result sets returned from stored procedures
• Process errors raised by T-SQL in ADO.NET using error numbers and states
• Write a T-SQL script to implement the stored procedures
• Write a T-SQL script to test the Stored Procedures for functionality
Description:
Goal of this project is to recreate the DLL’s provided during Phase 1 with a Data Access tier that
encapsulated all the data access logic for the application. This was accomplished by designing
and implementing my own Business and Data Access tiers.
In addition to Phase 1’s functionality, Phase 2 automatically converts the member record of a
juvenile who has turned 18 years old into an adult member record then notifies the librarian
that the member has been converted.
LibraryEntities contain the various classes and enumerations referenced by the entire project.
It contains the AdultMember, JuvenileMember, Member,
Item, LibraryException classes as well as the ErrorCode enumeration. It also
contains the Strongly typed ItemsDataSet dataset.
V. Ron Deliteris [email protected] Page 17 of 41
SetFocus – Library Phase II (ADO.NET)
The Data Access tier provides the layer between
the Business tier and the database. The UI
(user interface) tier makes requests to the
Business tier, which in turn makes the request
of the Data Access tier. The Data Access tier
executes stored procedures (written using T-SQL)
to query and update SQL Server database
tables through ADO.NET. Each stored procedure
utilized data validation and error handling
techniques. Exceptions return a specified error
code back to the Data Access tier, where
customized error handling takes place. If stored
procedure completes without exception, values
are assigned to the appropriate textboxes.
The connection string was stored at the project
level, which means that it only needs to be
changed ONCE.
As long as the DataAccess tier returns the
expected objects, the Business and UI tiers do
NOT need modifying. These tiers were only
modified to add functionality and change from
the DLL’s that were provided in Phase I.
This provides scalability and flexibility on the
database server.
V. Ron Deliteris [email protected] Page 18 of 41
SetFocus – Library Phase II (ADO.NET)
Library Database (tables and relationships):
This diagram shows the tables and their relationships in the Library database used in this
project.
adultmember_no
street
city
state
zip
phone_no
expr_date
juvenile
member_no
adult_member_no
birth_date
member
member_no
lastname
firstname
middleinitial
photograph
reservation
isbn
member_no
log_date
remarks
item
isbn
title_no
translation
cover
loanable
title
title_no
title
author
synopsis
loan
isbn
copy_no
title_no
member_no
out_date
due_date
loanhistisbn
copy_no
out_date
title_no
member_no
due_date
in_date
fine_assessed
fine_paid
fine_waived
remarks
copy
isbn
copy_no
title_no
on_loan
V. Ron Deliteris [email protected] Page 19 of 41
SetFocus – Library Phase II (ADO.NET)
LibraryPhase II Forms:
AddAdult Form (Presentation tier):
Screen print before the AddAdult button is clicked.
Display new member by redirecting to the MemberInfo form at button click.
V. Ron Deliteris [email protected] Page 20 of 41
SetFocus – Library Phase II (ADO.NET)
Presentation tier (AddAdult Method Code):
private void AddAdultMemberButton_Click(object sender, EventArgs e)
{
// Verify controls validated in validation methods.
if (!this.ValidateChildren())
return;
// Save the new member info to am (AdultMember).
AdultMember am = new AdultMember();
am.FirstName = AdultFirstNameTextBox.Text;
if (am.MiddleInitial != null)
am.MiddleInitial = AdultMITextBox.Text;
am.LastName = AdultLastNameTextBox.Text;
am.Street = StreetTextBox.Text;
am.City = CityTextBox.Text;
am.State = StateComboBox.Text;
am.ZipCode = ZipCodeTextBox.Text;
if (am.PhoneNumber != null)
am.PhoneNumber = PhoneTextBox.Text;
am.ExpirationDate = DateTime.Today.AddYears(1);
try
{
// Add the new member to SetFocus LibraryDataAccess assembly.
BusinessLayer bl = new BusinessLayer();
bl.AddMember(am);
memberadded = true;
}
catch (LibraryException lex)
{
// Display error message if adding an adult member fails.
frmMDIParent fmp = (frmMDIParent)this.MdiParent;
if (lex.LibraryErrorCode == ErrorCode.AddAdultFailed)
fmp.toolStripStatusLabel.Text = "Add Adult Member failed";
else
fmp.toolStripStatusLabel.Text = lex.Message;
return;
}
//Set new member nbr in am object by SetFocus LibraryDataAccess
assembly.
short memberid = am.MemberID;
// Message with new Member Id to Status Bar on frmAddAdult Form.
this.toolStripStatusLabel1.Text = "New Adult MemberID is: "
+ am.MemberID;
if (memberadded)
{
clearAdultTextBoxes();
AdultFirstNameTextBox.Focus();
// Reset after clearing Textboxes.
memberadded = false;
}
// Display frmMemberInfo form.
frmMemberInfo fmi = new frmMemberInfo(memberid);
fmi.MdiParent = this.MdiParent;
fmi.Show();
} // end AddAdultMemberButton_Click
V. Ron Deliteris [email protected] Page 21 of 41
SetFocus – Library Phase II (ADO.NET)
SQL Server 2005 (AddAdult Stored Procedure):
USE [library]
GO
-- Drop proc before creating it.
IF OBJECT_ID('uspAddAdultMember') IS NOT NULL
DROP PROCEDURE uspAddAdultMember;
GO
-- =============================================
-- Author: Ron Deliteris
-- Create date: 6/22/2009
-- Description: Add an Adult member.
-- =============================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE uspAddAdultMember
@lastname varchar(15)
,@firstname varchar(15)
,@middleinitial char(1) = NULL
,@street varchar(15)
,@city varchar(15)
,@state varchar(2)
,@zip varchar(10)
,@phone_no varchar(13) = NULL
,@member_no smallint OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
--Check if Last Name is empty.
IF @lastname IS NULL
BEGIN
RAISERROR('Must enter lastname', 11, 1)
RETURN
END
--Check if First Name is empty.
IF @firstname IS NULL
BEGIN
RAISERROR('Must enter firstname', 11, 2)
RETURN
END
Continued on next page…
V. Ron Deliteris [email protected] Page 22 of 41
SetFocus – Library Phase II (ADO.NET)
--Check if Street is empty.
IF @street IS NULL
BEGIN
RAISERROR('Must enter street', 11, 3)
RETURN
END
--Check if City is empty.
IF @city IS NULL
BEGIN
RAISERROR('Must enter city', 11, 4)
RETURN
END
--Check if State is empty
IF @state IS NULL
BEGIN
RAISERROR('Must enter state', 11, 5)
RETURN
END
--Check if Zip is empty.
IF @zip IS NULL
BEGIN
RAISERROR('Must enter zip code', 11, 6)
RETURN
END
BEGIN TRAN
-- Add the new adult member to the [member] table which
-- will generate the new MemberID.
INSERT INTO member ([lastname], [firstname],
[middleinitial])
VALUES (@lastname, @firstname, @middleinitial);
IF (@@ERROR <>0)
BEGIN
ROLLBACK TRAN
RAISERROR('Insert into member table failed', 11, 10);
RETURN;
END
-- Retrieve the last member number created.
SELECT @member_no = SCOPE_IDENTITY();
-- Set expiration date to one year from new member creation
DECLARE @ed datetime;
SELECT @ed = DATEADD(year, 1, GETDATE());
-- Add the new adult member to the [adult] table.
INSERT INTO adult ([member_no], [street], [city], [state],
[zip], [phone_no], [expr_date])
VALUES(@member_no, @street, @city, @state, @zip, @phone_no,
@ed);
Continued on next page…
V. Ron Deliteris [email protected] Page 23 of 41
SetFocus – Library Phase II (ADO.NET)
IF (@@ERROR <> 0)
BEGIN
ROLLBACK TRAN
RAISERROR('Insert into adult table failed', 11, 11);
RETURN;
END
COMMIT TRAN
RETURN @member_no
END
GO
-- =============================================
-- TEST proc after it’s created
-- =============================================
DECLARE @member_no smallint;
DECLARE @ret_value int;
EXEC @ret_value = uspAddAdultMember @lastname = 'Chisum'
, @firstname = 'John', @middleinitial = 'H'
, @street = '1 Chisum Trail', @city = 'Austin'
, @state = 'TX', @zip = '75050-1234'
, @phone_no = '(802)555-1234'
, @member_no = @member_no;
IF @ret_value < 0
BEGIN
RAISERROR('Add adult member failed', 11, 12)
RETURN
END
ELSE
PRINT 'New member number = ' + CAST(@ret_value AS varchar);
EXEC uspGetMember @member_no = @ret_value;
GO
V. Ron Deliteris [email protected] Page 24 of 41
SetFocus – Library Phase II (ADO.NET)
DataAccess Tier (AddAdult Method - call to SQL Server Stored Procedure):
public int AddMember(AdultMember am)
{
using (SqlConnection cnn = new
SqlConnection(Properties.Settings.Default.LibraryConnString))
{
using (SqlCommand cmd = new SqlCommand("uspAddAdultMember", cnn))
{
try
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@lastname", am.LastName);
cmd.Parameters.AddWithValue("@firstname", am.FirstName);
cmd.Parameters.AddWithValue("@middleinitial",
am.MiddleInitial);
cmd.Parameters.AddWithValue("@street", am.Street);
cmd.Parameters.AddWithValue("@city", am.City);
cmd.Parameters.AddWithValue("@state", am.State);
cmd.Parameters.AddWithValue("@zip", am.ZipCode);
cmd.Parameters.AddWithValue("@phone_no", am.PhoneNumber);
cmd.Parameters.Add("@member_no",
SqlDbType.SmallInt).Direction = ParameterDirection.Output;
cnn.Open();
cmd.ExecuteNonQuery();
am.MemberId = (short)cmd.Parameters["@member_no"].Value;
return am.MemberId;
}
catch (SqlException sqe)
{
if (sqe.State == 1)
throw new LibraryException(ErrorCode.None, sqe.Message, sqe);
if (sqe.State == 2)
throw new LibraryException(ErrorCode.None, sqe.Message, sqe);
if (sqe.State == 3)
throw new LibraryException(ErrorCode.None, sqe.Message, sqe);
if (sqe.State == 4)
throw new LibraryException(ErrorCode.None, sqe.Message, sqe);
if (sqe.State == 5)
throw new LibraryException(ErrorCode.None, sqe.Message, sqe);
if (sqe.State == 6)
throw new LibraryException
(ErrorCode.GenericException, sqe.Message, sqe);
throw new LibraryException(ErrorCode.AddAdultFailed,
sqe.Message, sqe);
}
}
}
}
V. Ron Deliteris [email protected] Page 25 of 41
SetFocus – Library Phase III (ASP.NET)
Introduction:
Library Phases I & II created the UI, Business, and DataAccess tiers for a library management
system. This project converted the Windows Forms application into a Web-based application
utilizing ASP.NET. In addition to Phase I & II’s functionality, Phase III includes the ability to
update an adult membership if it is expired, overdue books shown in any display must be
highlighted, the ability to add new books to the system, detect if a Juvenile member is 18 years
old or older and convert the member to an Adult, and
implement authentication and authorization to
restrict access to the system.
Summary:
This project demonstrates the use of ASP.NET.
Some of the techniques used include:
• Create and use ASP.NET master pages to
provide a consistent look across the website.
• Web application project must use Forms-
base authentication and authorization.
• Used membership roles to restrict access to
the day-to-day functions to the Librarian role.
(Use the membership and role management
features of ASP.NET 2.0.
• Create two Librarian roles and two Library
users.
• Create a web interface that is intuitive and
requires minimal training.
• Use various validation controls to validate
input before postback.
• Use of hyperlinks to navigate between
pages.
V. Ron Deliteris [email protected] Page 26 of 41
SetFocus – Library Phase III (ASP.NET)
Description:
To make the interface visually pleasing, yet functional, the design represents items a library
would normally use.
Each control had appropriate error validation controls attached such that validation would
occur through JavaScript on the client. The code behind files for each page contained the same
validations and provided the appropriate feedback in case JavaScript was disabled.
The user interface (UI) used the same Business (RD.LibraryBusiness) and DataAccess
(RD.LibraryDataAccess) tiers as the previous Phases of the project with additional functionality
added to comprehend new requirements.
The additional functionality of adding a book, converting a Juvenile to an Adult, and renewing
an adult’s expired membership required the addition of several Business tier, DataAccess tier,
and Stored Procedures.
Stored Procedures:
Several stored procedures were created
during this phase of the project. The
majority duplicated previous phases.
The uspConvertJuvToAdult procedure
will detect and convert a Juvenile member
that has reached 18 years old, and then
notify the Librarian of the convertion.
The uspRenewMembership procedure will
detect an expired membership and probe
the Librarian to convert or cancel query.
Each stored procedure contained the
same validation on data as the others
layers of the project.
V. Ron Deliteris [email protected] Page 27 of 41
SetFocus – Library Phase III (ASP.NET)
Library Phase III Web Pages:
CheckIn Web Page - Prior to button click (Web Application):
This page is a screen shot after entering data but prior to clicking the Check In Item button.
After the Check In Item button is clicked this MessageBox opens. It gives the Librarian the
choice to continue to CheckIn the book or cancel the CheckIn.
Continued on next page…
V. Ron Deliteris [email protected] Page 28 of 41
SetFocus – Library Phase III (ASP.NET)
CheckIn Web Page - Redirect to GetMember page (Web Application):
After the CheckIn has completed, the code behind redirects and passes the MemberId to the
GetMember page, and displays the member info along with the items that are checked out for
this member. As the display shows the ISBN 47 copy 2 are no longer checked out by this
member.
V. Ron Deliteris [email protected] Page 29 of 41
SetFocus – Library Phase III (ASP.NET)
Web Application (CheckIn Method Code):
protected void btnCheckInItem_Click(object sender, EventArgs e)
{
// Reset InfoMsgs Label.
clearLblInfoMsgs();
isbn = Convert.ToInt32(tbxIsbnCheckInItem.Text);
copyno = Convert.ToInt16(tbxCopyNbrCheckIn.Text);
try
{
BusinessLayer bl = new BusinessLayer();
Item itm = bl.GetItem(isbn, copyno);
// If memberid > 0, then item is on loan, so ask if OK to check in?.
if (itm.MemberNo > 0)
{
string mi = "";
Member m = bl.GetInformation(itm.MemberNo);
// Ternary operator (?, :) for if,else statement.
// If no middle initial, pass a " ", else pass " " + middle
initial + " ".
mi = (m.MiddleInitial == String.Empty) ? " " : " "
+ m.MiddleInitial + " ";
membername = m.FirstName + mi + m.LastName;
DialogResult result;
result = MessageBox.Show
("CheckIn \"" + itm.Title + "\" by " + itm.Author
+ " which is on loan to " + membername + " (ID = "
+ itm.MemberNo + ")", "Confirm CheckIn?",
MessageBoxButtons.YesNo);
if (result == DialogResult.No)
{
clearCheckInItemTextBoxes();
tbxIsbnCheckInItem.Focus();
// Send message to InfoMsgs Label "User cancelled check in."
lblInfoMsgs1.Font.Bold = true;
lblInfoMsgs1.ForeColor = Color.Red;
lblInfoMsgs1.Text = "User cancelled CheckIn.";
return;
}
Continued on next page…
V. Ron Deliteris [email protected] Page 30 of 41
SetFocus – Library Phase III (ASP.NET)
if (result == DialogResult.Yes)
{
// CheckOut item.
bl.CheckInItem(isbn, copyno);
Response.Redirect("MemberInfo.aspx?memberid=" +
itm.MemberNo.ToString());
}
}
else
{
//clearLblInfoMsgs();
clearCheckInItemTextBoxes();
// Send msg to InfoMsgsLabel that isbn and copyno is not on loan.
lblInfoMsgs1.Font.Bold = true;
lblInfoMsgs1.ForeColor = Color.Red;
lblInfoMsgs1.Text = string.Format ("{0} by {1} ", itm.Title,
itm.Author);
lblInfoMsgs2.Font.Bold = true;
lblInfoMsgs2.ForeColor = Color.Red;
lblInfoMsgs2.Text = string.Format
("with ISBN # {0} and Copy # {1} is NOT on loan.", itm.ISBN,
itm.CopyNo);
}
}
catch (LibraryException lex)
{
clearLblInfoMsgs();
if (lex.LibraryErrorCode == ErrorCode.ItemNotFound)
{
lblInfoMsgs1.Font.Bold = true;
lblInfoMsgs1.ForeColor = Color.Red;
lblInfoMsgs1.Text = string.Format
("Item with ISBN # {0} and Copy # {1} was NOT found.", isbn,
copyno);
tbxIsbnCheckInItem.Focus();
}
}
} // end btnCheckInItem_Click
V. Ron Deliteris [email protected] Page 31 of 41
SetFocus – Library Phase III (ASP.NET)
XML (Creates controls for CheckIn web page):
<%@ Page Language="C#" MasterPageFile="~/MasterPage.Master" AutoEventWireup="true"
CodeBehind="CheckInItem.aspx.cs" Inherits="RD.LibraryWebAppl.CheckInItem"
Title="CHECK IN ITEM" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<table>
<tr valign="middle" style="height:25px">
<td style="width:10%">
<br /> <%--Spacer column--%>
</td>
<td valign="middle" style="width:15%; text-align:right; padding-right:10px">
<asp:Label ID="Label1" runat="server" Font-Names="Microsoft Sans Serif"
Height="20px" Text="ISBN #:" ForeColor="Blue" BackColor="White" Font-
Size="9pt" Font-Bold="True" >
</asp:Label>
</td>
<td style="width:77%">
<asp:TextBox ID="tbxIsbnCheckInItem" runat="server"
Font-Names="Microsoft Sans Serif" Height="20px" ForeColor="Black"
BackColor="White" Font-Size="9pt"
style="vertical-align:middle; text-align:left;" Width="100px" TabIndex="1" >
</asp:TextBox>
<%--VALIDATION--%>
<asp:RequiredFieldValidator ID="rfvIsbnCheckInItem" runat="server"
ControlToValidate="tbxIsbnCheckInItem" Display="Dynamic"
ErrorMessage="ISBN number cannot be blank."
ToolTip="Enter valid ISBN number." Text="*" Font-Bold="True" Font-Size="9pt">
</asp:RequiredFieldValidator>
<asp:RangeValidator ID="rvIsbnCheckInItem" runat="server"
ControlToValidate="tbxIsbnCheckInItem" Display="Dynamic"
ErrorMessage="ISBN # is between 1 and 2147483647."
ToolTip="Enter ISBN number." MaximumValue="2147483647"
MinimumValue="1" Type="Integer" Text="*" Font-Bold="true" Font-Size="9pt">
</asp:RangeValidator>
</td>
</tr>
<tr valign="middle" style="height:25px">
<td style="width:10%">
<br /> <%--Spacer column--%>
</td>
<td valign="middle" style="width:15%; text-align:right; padding-right:10px">
<asp:Label ID="Label2" runat="server" Font-Names="Microsoft Sans Serif"
Height="20px" Text="Copy #:" ForeColor="Blue" BackColor="White"
Font-Size="9pt" Font-Bold="True">
</asp:Label>
</td>
<td style="width:77%">
<asp:TextBox ID="tbxCopyNbrCheckIn" runat="server"
Font-Names="Microsoft Sans Serif" Height="20px" ForeColor="Black"
BackColor="White" Font-Size="9pt"
style="vertical-align:middle; text-align:left;" Width="100px" TabIndex="2" >
</asp:TextBox>
<%--VALIDATION--%>
<asp:RequiredFieldValidator ID="rfvCopyNbrCheckIn" runat="server"
ControlToValidate="tbxCopyNbrCheckIn" Display="Dynamic"
ErrorMessage="Copy number cannot be blank."
ToolTip="Enter valid Copy number." Text="*" Font-Bold="True" Font-Size="9pt">
</asp:RequiredFieldValidator>
Continued on next page…
V. Ron Deliteris [email protected] Page 32 of 41
SetFocus – Library Phase III (ASP.NET)
<asp:RangeValidator ID="rvCopyNbrCheckIn" runat="server"
ControlToValidate="tbxCopyNbrCheckIn" Display="Dynamic"
ErrorMessage="Copy # is between 1 and 32767." ToolTip="Enter Copy number."
MaximumValue="32767" MinimumValue="1" Type="Integer" Text="*"
Font-Bold="true" Font-Size="9pt">
</asp:RangeValidator>
</td>
</tr>
<%--SPACER ROW--%>
<tr style="height:15px">
</tr>
<tr valign="middle" style="height:25px">
<td style="width:10%">
<br /> <%--Spacer column--%>
</td>
<td valign="middle" style="width:15%; text-align:right; padding-right:10px">
<asp:Button ID="btnCheckInItem" runat="server" Font-Names="Microsoft Sans Serif"
Height="25px" Text="Check In Item" ForeColor="Blue" BackColor="White"
Font-Size="9pt" Font-Bold="true" Width="170px" TabIndex="3"
style="vertical-align:middle; text-align:center;"
OnClick="btnCheckInItem_Click"/>
</td>
<td align="left" style="width:77%">
<asp:Button ID="btnCancelCheckIn" runat="server" Height="25px" Text="Cancel"
Font-Names="Microsoft Sans Serif" ForeColor="Blue" BackColor="White"
Font-Size="9pt" Font-Bold="true" Width="170px" TabIndex="4"
style="vertical-align:middle; text-align:center;" CausesValidation="False"
OnClick="btnCancelCheckIn_Click" />
</td>
</tr>
<%--SPACER ROW--%>
<tr style="height:15px">
</tr>
<%--VALIDATION--%>
<tr>
<td colspan="2" style="height: 76px">
<asp:ValidationSummary ID="ValidationSummary1" runat="server" Font-Size="9pt"
ShowMessageBox="True" style="text-align:left" Font-Bold="True" />
</td>
<%--MESSAGE DISPLAY LABEL--%>
<td colspan="2" style="height: 76px" valign="top">
<asp:Label ID="lblInfoMsgs1" runat="server" Height="20px"
Font-Names="Microsoft Sans Serif" Font-Bold="True" Font-Size="9pt" >
</asp:Label><br />
<asp:Label ID="lblInfoMsgs2" runat="server" Height="20px"
Font-Names="Microsoft Sans Serif" Font-Bold="True" Font-Size="9pt" >
</asp:Label><br />
<asp:Label ID="lblInfoMsgs3" runat="server" Height="20px"
Font-Names="Microsoft Sans Serif" Font-Bold="True" Font-Size="9pt" >
</asp:Label>
</td>
</tr>
</table>
</asp:Content>
V. Ron Deliteris [email protected] Page 33 of 41
SetFocus – Library Phase IV (Web Services)
Introduction:
As potential to acquire libraries and partnerships with other libraries increase, there is a need
to take the library management system to the next level –
allow interoperability with other systems. To do this, Web
services must be implemented. The Web service provides
access to the business tier of the system. Because of the
possibility of interfacing with systems of partner libraries,
security must be implemented as well.
Summary:
This project demonstrates the use of Web Service
implementation techniques.
Some of the techniques used include:
• Support previous project functionality.
• Customize formatting of XML for some Business
types by treating some properties as attributes.
• Employed WSE 3.0 (Web Services Enhancement)
security using Certificates. Included Signing
and Encryption.
• Use true n-Tier structures.
• Create and interpret custom SoapException objects.
Description:
The goal of this phase of development was to separate
the UI (RD.LibraryWebAppl) from the Business and
DataAccess tiers. Certain Business tier methods were
overloaded. I reworked these methods for the web service
since WebServices does not support overloaded methods.
Web methods and classes were developed to allow for the
interoperability of the properties that could not be serialized.
V. Ron Deliteris [email protected] Page 34 of 41
SetFocus – Library Phase IV (Web Services)
The AddMember methods of the Business tier simply modified the parameters passed in. Since
Web Services are inherently one-way, these methods were rewritten so the appropriate data
was passed back to the UI tier (Web Application) .
The GetMember method returns the base class Member. To tell the client and web service to
handle the sub-classes correctly, the XmlInclude attribute was used.
Another obstacle is that Web Services only throw SoapExceptions and the Business tier was
encoded to throw a LibraryException. I encoded the type of error received from the Business
tier and encoded all appropriate information into a custom SoapException.
Web Services-Service.asmx Pages (View in Browser):
Directory Listing (Web Services):
V. Ron Deliteris [email protected] Page 35 of 41
SetFocus – Library Phase IV (Web Services)
Web Services (Supported Web Services operations):
V. Ron Deliteris [email protected] Page 36 of 41
SetFocus – Library Phase IV (Web Services)
Web Services Coding (Web Methods, SoapException, Attributes, etc):
Service Class (RD.libraryWebService.Service.cs):
The Service.cs Class in the Web Service (RD.LibraryWebService) using Policy and WebService.
[WebService(Namespace = "http://www.LibraryPhase4.com/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[Policy("LibPolicy")]
public class Service : System.Web.Services.WebService
{
. . . . .
} // end class Service
GetMember method (RD.libraryWebService.Service.cs):
Shows the use of the XmlInclude attribute and SoapExtension. Retrieves Member Information
based on provided memberid, using the LibraryDataAccess GetInformation method.
[WebMethod]
[XmlInclude(typeof(AdultMember))]
[XmlInclude(typeof(JuvenileMember))]
public Member GetMember(short memberid)
{
// Create a library business layer object.
BusinessLayer bl = new BusinessLayer();
try
{
//Call GetInformation() method, pass in MemberId, return member.
Member myMember = bl.GetInformation(memberid);
return myMember;
}
catch (LibraryException le)
{
SoapException soapex = AssignFaultCode(le);
throw soapex;
}
} // end GetMember
V. Ron Deliteris [email protected] Page 37 of 41
SetFocus – Library Phase IV (Web Services)
AssignFaultCode method of type SoapException (RD.libraryWebService.Service.cs):
This method is passed a LibraryException parameter and converts it to a SoapException.
private SoapException AssignFaultCode(LibraryException le)
{
SoapException soapex = new SoapException
(le.LibraryErrorCode.ToString() + ":" + le.Message,
SoapException.ClientFaultCode, le);
return soapex;
} // end AssignFaultCode
WSE 3.0 Security (RD.libraryWebAppl. wse3policyCache.config):
Xml used to setup Policies and Certificates (LibPolicy).
<policies xmlns="http://schemas.microsoft.com/wse/2005/06/policy">
<extensions>
<extension name="mutualCertificate11Security"
type="Microsoft.Web.Services3.Design.MutualCertificate11Assertion,
Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
<extension name="x509" type="Microsoft.Web.Services3.Design.X509TokenProvider,
Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
<extension name="requireActionHeader"
type="Microsoft.Web.Services3.Design.RequireActionHeaderAssertion,
Microsoft.Web.Services3, Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
</extensions>
<policy name="LibPolicy">
<mutualCertificate11Security establishSecurityContext="true"
renewExpiredSecurityContext="true"
requireSignatureConfirmation="true"
messageProtectionOrder="SignBeforeEncrypt"
requireDerivedKeys="true" ttlInSeconds="300">
<clientToken>
<x509 storeLocation="CurrentUser" storeName="My"
findValue="CN=WSE2QuickStartClient"
findType="FindBySubjectDistinguishedName" />
</clientToken>
<serviceToken>
<x509 storeLocation="CurrentUser" storeName="AddressBook"
findValue="CN=WSE2QuickStartServer"
findType="FindBySubjectDistinguishedName" />
</serviceToken>
Continued on next page…
V. Ron Deliteris [email protected] Page 38 of 41
SetFocus – Library Phase IV (Web Services)
<protection>
<request signatureOptions="IncludeAddressing, IncludeTimestamp,
IncludeSoapBody" encryptBody="true" />
<response signatureOptions="IncludeAddressing, IncludeTimestamp,
IncludeSoapBody" encryptBody="true" />
<fault signatureOptions="IncludeAddressing, IncludeTimestamp, IncludeSoapBody"
encryptBody="false" />
</protection>
</mutualCertificate11Security>
<requireActionHeader />
</policy>
</policies>
Web Services (Web Pages):
AddCopy Web Page - Prior to button click (Web Application):
This page is a screen shot after entering the ISBN that you want to add the copy to, but it’s prior
to clicking the Add One Copy button.
V. Ron Deliteris [email protected] Page 39 of 41
SetFocus – Library Phase IV (Web Services)
AddCopy Web Page - After button click (Web Application):
This page is a screen shot after the Add One Copy button is clicked and confirmation message is
dispalyed in message line below buttons.
Web Services Code (AddCopy - Web Application):
This code example shows instantiating a new instance of the web service using ServiceWse and
assigning the Policy name to LibPolicy referenced in previous XML page.protected void btnAddCopy_Click(object sender, EventArgs e)
{
try
{
clearLblInfoMsgs();
isbn = Convert.ToInt32(tbxIsbnAddCopy.Text);
// Create a WSE proxy.
// Call SetPolicy method of proxy object, specify policy entry used.
ServiceWse ws = new ServiceWse();
ws.SetPolicy("LibPolicy");
LibraryWebService.Item newCopy = ws.AddNewCopy(isbn);
Continued on next page…
V. Ron Deliteris [email protected] Page 40 of 41
SetFocus – Library Phase IV (Web Services)
lblInfoMsgs1.Font.Bold = true;
lblInfoMsgs1.ForeColor = Color.Blue;
lblInfoMsgs1.Text = string.Format
("Copy # {0} was successfully added to ISBN # {1}, ",
newCopy.CopyNo.ToString(), newCopy.ISBN.ToString());
lblInfoMsgs2.Font.Bold = true;
lblInfoMsgs2.ForeColor = Color.Blue;
lblInfoMsgs2.Text = string.Format
("for {0} by {1}.", newCopy.Title, newCopy.Author);
clearAddCopyTextBoxes();
tbxIsbnAddCopy.Focus();
}
catch (SoapException soapex)
{
clearLblInfoMsgs();
// Convert NonLibraryException msg to a LibraryException ErrorCode.
String msg = soapex.Message.Substring(45);
int colon = msg.IndexOf(':');
String errorcodestr = msg.Substring(0, colon).Trim();
ErrorCode errorcode =
(ErrorCode)Enum.Parse(typeof(ErrorCode), errorcodestr);
msg = msg.Substring(colon + 1).Trim();//lops off errorcode
msg = msg.Substring(0, msg.IndexOf("--->")).Trim();//lops off the end
if (errorcode == ErrorCode.IsbnDoesNotExist)
{
lblInfoMsgs1.Font.Bold = true;
lblInfoMsgs1.ForeColor = Color.Red;
lblInfoMsgs1.Text = string.Format
("ISBN # {0} was NOT found in data base, ErrorCode 3.",
isbn);
return;
}
if (errorcode == ErrorCode.AddCopyFailed_CopyTable)
{
lblInfoMsgs1.Font.Bold = true;
lblInfoMsgs1.ForeColor = Color.Red;
lblInfoMsgs1.Text = string.Format
("Add new Copy for ISBN # {0} FAILED", isbn);
lblInfoMsgs2.Font.Bold = true;
lblInfoMsgs2.ForeColor = Color.Red;
lblInfoMsgs2.Text = string.Format
("during a [Copy] table insert, ErrorCode 10.");
return;
}
Continued on next page…
V. Ron Deliteris [email protected] Page 41 of 41
SetFocus – Library Phase IV (Web Services)
else
{
clearLblInfoMsgs();
lblInfoMsgs1.Font.Bold = true;
lblInfoMsgs1.ForeColor = Color.Red;
lblInfoMsgs1.Text = string.Format
("Error other than: IsbnDoesNotExist &
AddCopyFailed_CopyTable.{0}{0}Message: {1}",
Environment.NewLine, msg);
}
clearAddCopyTextBoxes();
tbxIsbnAddCopy.Focus();
return;
}
catch (WebException wex)
{
clearLblInfoMsgs();
//Exception when you can't communicate with WebService at all.
lblInfoMsgs1.Font.Bold = true;
lblInfoMsgs1.ForeColor = Color.Red;
lblInfoMsgs1.Text = string.Format
("There was error connecting to Web service.{0}{0}Message: {1}",
Environment.NewLine, wex.Message);
return;
}
catch (Exception ex)
{
clearLblInfoMsgs();
// Generic Exception if its not a Soap or Web Exception.
lblInfoMsgs1.Font.Bold = true;
lblInfoMsgs1.ForeColor = Color.Red;
lblInfoMsgs1.Text = string.Format
("There was an unexpected error.{0}{0}Message: {1}",
Environment.NewLine, ex.Message);
return;
}
} // end btnAddCopy_Click