net portfolio

41
V. Ron Deliteris C# .NET Developer – Design Portfolio

Upload: ron-deliteris

Post on 25-Dec-2014

711 views

Category:

Technology


2 download

DESCRIPTION

Portfolio includes 2 projects completed at SetFocus. First is .NET Framework project and the second is an n-tiered Library application project that includes 4 phases. Responsibility includes developing a Windows Forms phase, Data Access (ADO.NET) phase utilizing SQL Server (T-SQL), Web Application (ASP.NET) phase, and Web Services (WSE) phase.

TRANSCRIPT

Page 1: NET Portfolio

V. Ron DeliterisC# .NET Developer – Design Portfolio

Page 2: NET 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

Page 3: NET Portfolio

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

Page 4: NET Portfolio

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.

Page 5: NET Portfolio

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…

Page 6: NET Portfolio

V. Ron Deliteris [email protected] Page 6 of 41

SetFocus – .NET Framework

AppTypes Assembly (continued):

Page 7: NET Portfolio

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.

Page 8: NET Portfolio

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

Page 9: NET Portfolio

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.

Page 10: NET Portfolio

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.

Page 11: NET Portfolio

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.

Page 12: NET Portfolio

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).

Page 13: NET Portfolio

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…

Page 14: NET Portfolio

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…

Page 15: NET Portfolio

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;

}

}

Page 16: NET Portfolio

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.

Page 17: NET Portfolio

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.

Page 18: NET Portfolio

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

Page 19: NET Portfolio

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.

Page 20: NET Portfolio

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

Page 21: NET Portfolio

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…

Page 22: NET Portfolio

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…

Page 23: NET Portfolio

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

Page 24: NET Portfolio

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);

}

}

}

}

Page 25: NET Portfolio

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.

Page 26: NET Portfolio

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.

Page 27: NET Portfolio

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…

Page 28: NET Portfolio

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.

Page 29: NET Portfolio

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…

Page 30: NET Portfolio

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

Page 31: NET Portfolio

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…

Page 32: NET Portfolio

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>

Page 33: NET Portfolio

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.

Page 34: NET Portfolio

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):

Page 35: NET Portfolio

V. Ron Deliteris [email protected] Page 35 of 41

SetFocus – Library Phase IV (Web Services)

Web Services (Supported Web Services operations):

Page 36: NET Portfolio

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

Page 37: NET Portfolio

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…

Page 38: NET Portfolio

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.

Page 39: NET Portfolio

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…

Page 40: NET Portfolio

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…

Page 41: NET Portfolio

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