.NET Portfolio
Upcoming SlideShare
Loading in...5
×
 

.NET Portfolio

on

  • 910 views

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

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.

Statistics

Views

Total Views
910
Views on SlideShare
909
Embed Views
1

Actions

Likes
0
Downloads
24
Comments
0

1 Embed 1

http://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

.NET Portfolio .NET Portfolio Document Transcript

  • V. Ron Deliteris C# .NET Developer – Design Portfolio
  • 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 Ron.Deliteris@SetFocus.com Page 2 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 Ron.Deliteris@SetFocus.com Page 3 of 41
  • SetFocus – .NET Framework Foundation Assembly: This assembly contains the foundation interfaces and base classes used throughout the project. V. Ron Deliteris Ron.Deliteris@SetFocus.com Page 4 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 Ron.Deliteris@SetFocus.com Page 5 of 41
  • SetFocus – .NET Framework AppTypes Assembly (continued): V. Ron Deliteris Ron.Deliteris@SetFocus.com Page 6 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 Ron.Deliteris@SetFocus.com Page 7 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 Ron.Deliteris@SetFocus.com Page 8 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 Ron.Deliteris@SetFocus.com Page 9 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 Ron.Deliteris@SetFocus.com Page 10 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 Ron.Deliteris@SetFocus.com Page 11 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 Ron.Deliteris@SetFocus.com Page 12 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 Ron.Deliteris@SetFocus.com Page 13 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 Ron.Deliteris@SetFocus.com Page 14 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 Ron.Deliteris@SetFocus.com Page 15 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 Ron.Deliteris@SetFocus.com Page 16 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 Ron.Deliteris@SetFocus.com Page 17 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. m ber em m ber_no em loan lastname isbn firstname copy_no reservation title_no middleinitial isbn photograph m ber_no em m ber_no em out_date log_date due_date remarks juvenile m ber_no em loanhist adult_m ber_no em isbn item birth_date copy_no isbn out_date title_no title_no translation m ber_no em cover due_date loanable adult in_date m ber_no em fine_assessed street fine_paid city fine_waived state remarks zip title phone_no title_no expr_date title author synopsis copy isbn copy_no title_no on_loan V. Ron Deliteris Ron.Deliteris@SetFocus.com Page 18 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 Ron.Deliteris@SetFocus.com Page 19 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 Ron.Deliteris@SetFocus.com Page 20 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 Ron.Deliteris@SetFocus.com Page 21 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 Ron.Deliteris@SetFocus.com Page 22 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 Ron.Deliteris@SetFocus.com Page 23 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 Ron.Deliteris@SetFocus.com Page 24 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 Ron.Deliteris@SetFocus.com Page 25 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 Ron.Deliteris@SetFocus.com Page 26 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 Ron.Deliteris@SetFocus.com Page 27 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 Ron.Deliteris@SetFocus.com Page 28 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 Ron.Deliteris@SetFocus.com Page 29 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 Ron.Deliteris@SetFocus.com Page 30 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 Ron.Deliteris@SetFocus.com Page 31 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 Ron.Deliteris@SetFocus.com Page 32 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 Ron.Deliteris@SetFocus.com Page 33 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 Ron.Deliteris@SetFocus.com Page 34 of 41
  • SetFocus – Library Phase IV (Web Services) Web Services (Supported Web Services operations): V. Ron Deliteris Ron.Deliteris@SetFocus.com Page 35 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 Ron.Deliteris@SetFocus.com Page 36 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 Ron.Deliteris@SetFocus.com Page 37 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 Ron.Deliteris@SetFocus.com Page 38 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 Ron.Deliteris@SetFocus.com Page 39 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 Ron.Deliteris@SetFocus.com Page 40 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 V. Ron Deliteris Ron.Deliteris@SetFocus.com Page 41 of 41