Saturday, January 3, 2015

Creating a Service Client

We created web services with the last assignment. Now we will create a client that consumes those services. Our web site will have a page to register, a page to log in, and a page to add a new review and optionally add a new book and author.

Designing the Web Forms

Start a new Empty Web site. Add a default page, which will contain the login form, a registration page and an add review page. The add review page should only be available if the user logs in. Here is the source code for each of the pages. You can cut and paste them into your project if you like, or better, you can recreate them on your own.

Default.aspx


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>BookReview Login</title>
    <link href="BookReviewAtLargeStyles.css" rel="stylesheet" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>Book Reviews At Large</h1>
        <hr />
        <p>To leave reviews you must log in.</p>
        <table class="login">
            <tr>
                <td class="login">User Name</td>
                <td class="login">
                    <asp:TextBox ID="txtUserName" runat="server">
</asp:TextBox></td>
            </tr>
                <tr>
                <td class="login">Password</td>
                <td class="login">
                    <asp:TextBox ID="txtPassword" runat="server" 
TextMode="Password">
                   </asp:TextBox></td>
            </tr>
                <tr>
                <td class="login">
                    <asp:Button ID="btnLogin" runat="server" Text="LogIn" />
                </td>
                <td class="login">
                    <asp:Label ID="lblMessage" runat="server" Text="">
</asp:Label> </td>
            </tr>
        </table>
        <asp:LinkButton ID="lbRegister" runat="server" 
            PostBackUrl="~/Register.aspx">Register</asp:LinkButton>
    
    </div>
    </form>
</body>
</html>

Register.aspx


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Register.aspx.cs" Inherits="Register" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Registration</title>
    <link href="BookReviewAtLargeStyles.css" rel="stylesheet" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>Book Review at Large Registration</h1>
    <table>
        <tr>
            <td>Last Name</td>
            <td>
                <asp:TextBox ID="txtLastName" runat="server"></asp:TextBox></td>
        </tr>
         <tr>
            <td>First Name</td>
            <td>
                <asp:TextBox ID="txtFirstName" runat="server"></asp:TextBox></td>
        </tr>
         <tr>
            <td>Email</td>
            <td>
                <asp:TextBox ID="txtEmail" runat="server"></asp:TextBox></td>
        </tr>
         <tr>
            <td>User Name</td>
            <td>
                <asp:TextBox ID="txtUserName" runat="server"></asp:TextBox></td>
        </tr>
         <tr>
            <td>Password</td>
            <td>
                <asp:TextBox ID="txtPassword" runat="server" TextMode="Password">
                </asp:TextBox></td>
        </tr>
         <tr>
            <td>Confirm Password</td>
            <td>
                <asp:TextBox ID="txtConfirm" runat="server" TextMode="Password">
                </asp:TextBox></td>
        </tr>
         <tr>
            <td><asp:Button ID="btnRegister" runat="server" Text="Register" /></td>
            <td>
                <asp:Label ID="lblResult" runat="server" Text=""></asp:Label>
                </td>
        </tr>
    </table>
        <asp:LinkButton ID="lbLogin" runat="server" PostBackURL="~/Default.aspx">Log in</asp:LinkButton>
    </div>
    </form>
</body>
</html>


NewReview.aspx


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="NewReview.aspx.cs" Inherits="NewReview" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Create Review</title>
    <link href="BookReviewAtLargeStyles.css" rel="stylesheet" />
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>Book Reviews At Large</h1>
        <hr />
        <p>Add Your review</p>
    <table>
        <tr>
            <td>Choose an existing title or enter your own</td>
            <td>
                <asp:DropDownList ID="ddlTitles" runat="server"></asp:DropDownList></td>
            <td>
                <asp:TextBox ID="txtTitle" runat="server"></asp:TextBox></td>
        </tr>
          <tr>
            <td>Choose an existing Author or enter your own</td>
            <td>
                <asp:DropDownList ID="ddlAuthor" runat="server"></asp:DropDownList></td>
            <td>
                <asp:TextBox ID="txtAuthor" runat="server"></asp:TextBox></td>
        </tr>
          <tr>
            <td>Choose a category</td>
            <td>
                <asp:DropDownList ID="ddlCategory" runat="server"></asp:DropDownList></td>
            <td>
                 </td>
        </tr>
          <tr>
            <td>Enter a title for your review</td>
            <td>
                <asp:TextBox ID="txtReviewTitle" runat="server"></asp:TextBox>  </td>
            <td>
                </td>
        </tr>
          <tr>
            <td>Rate the book 1 to 5</td>
            <td>
                <asp:DropDownList ID="ddlRating" runat="server">
                   
                </asp:DropDownList></td>
            <td>
                </td>

        </tr>
        
          <tr>
            <td>Enter your review</td>
            <td colspan="2">
                <asp:TextBox ID="txtReview" runat="server" 
                    TextMode="MultiLine" width="100%" Height="300"></asp:TextBox>  

            </td>
     
        </tr>
        
          <tr>
            <td>
                <asp:Button ID="btnSave" runat="server" Text="Save" /></td>
            <td>
                <asp:Label ID="lbResult" runat="server" Text=""></asp:Label> </td>
            <td>
                </td>
        </tr>
    </table>
    </div>
    </form>
</body>
</html>


Here is the rather minimal style sheet BookReviewsAtLarge.css


body {
}
.login
{
    background-color:Navy;
    color:white;
    border:solid 2px black;
}
h1 {
    color:navy;
}

Here is what the pages look like in Design view

 

Adding The Code


Part one: Registering the services

For this part we will need three instances of Visual Studio Running: The Registration, log in service, and the Client app. This would not be necessary if we had registered the service with IIS proper rather than the built in IISExpress, but this version will work even if you don't have IIS installed and configured on your own computer. I will create another blog soon about how to register the service with IIS.

With the Client open, right click on the Visual studio Icon in the tray (at the bottom of the screen.) Open the two services. It is also important that you run them and leave them running.

Now we will register the services with the client. First we will do the Registration service. In the Test Client dialog for the running Registration Services, right click on the address and select Copy Address.

Now go the the Client Web Site. Choose Add and then Service Reference

In the dialog paste in the address and click GO. I have expanded the services to show the methods. I have named it "RegistrationLoginService."

Click OK to Add the Service. Go through the same steps to add the Review service. Name it "ReviewService."

The Code

Let's just do the pages in order. We will start with the login page. Double click the login button in design mode to get the click event for the button. Here is the code

Notice it is fairly simple. All the work is done by the service. You merely need to register the service and call the appropriate method. If the result is good we store the user's id in a Session variable and redirect them to the review page. If not we give them a message that the log in is invalid.

You should test the log in now. To make sure it works. It is always a good idea to test each section before moving on.

Now let's work on the Registration page. Double click the button in design mode to get the click event. In this method we will instantiate the service. Declare an instance of the ReviewLite class that we created in the service as a Data Contract, assign the contents of the textboxes to the ReviewLite properties and pass the class to the Register method in the service. It would be a very good idea to validate all the text boxes just as we did in assignment 3. Here is the code:

Again, test this before moving on. Register someone and then see if you can log in as them.

Now it is time to tackle the most complex part. Adding the review itself. First we will fill in the drop down boxes. To do this we will make a separate method for each drop down and then call them from the Page Load event. We want to register the service at class level so we can access it in all our methods. Here is the FillTitleList() method. All the others follow exactly the same pattern.

Here is the code for all the lists.

Here is the page load event

Notice a couple of points. One is the if statement that makes sure that the Session variable is not null, that it exists and has a value. This is to keep anyone who has not logged in from accessing this page. If the session object does not exist they are thrown back to the log in page. The second if is to make sure that the lists only repopulate on the initial load and not with every postback. This allows your selection to be preserved.

Now go back to design view and double click the Save button to get the click event. The code for this is a bit complex because we must determine if there are values in the text boxes. If there is then we need to add them rather than the values in the drop down lists.
1. Is the title an existing one (from the drop down list) or a new one (from the textbox)
2. If it is a new one
    A:add the book
    B:Is it a new author or an existing one
        a: If is new one add the author
    C: Add the author and category to the book
    D: Save the Book
3. If it is not a new title
    A:Get the bookKey from the drop down list
4.Add the review Assign the values to the review
5. Save the Review

I have commented the code and pasted it in so you can examine it.

protected void btnSave_Click(object sender, EventArgs e)
    {
            //get the session value (the users id)
            int key = (int)Session["Id"];

           //create a new instance of the Review class
        //we get to it through the ReviewService object
            ReviewService.Review rev = new ReviewService.Review();
        //if the text box is not empty use the text in the text box
            if (!txtTitle.Text.Equals(""))
            {
                //create new book and author objects
                ReviewService.Book b = new ReviewService.Book();
                ReviewService.Author a = new ReviewService.Author();
                string c = null;
                //assign some values to the book
                b.BookTitle = txtTitle.Text;
                b.BookEntryDate = DateTime.Now;

                //determine if the author text box has text
                if (!txtAuthor.Text.Equals(""))
                {

                    //if it does add the value to the author
                    //and call the add author method in the service
                    a.AuthorName = txtAuthor.Text;
                    rsc.AddAuthor(a);
                   
                }
                else
                {
                    //otherwise get the author's name
                    //from the drop down list
                    a.AuthorName = ddlAuthor.SelectedItem.Text.ToString();
 
                }
 
                //add the category
                c = ddlCategory.SelectedItem.Text;

                //call the add Book method of the service
                rsc.AddBook(b, a, c);
                rev.BookKey = b.BookKey;

            }

            else
            {
                //Otherwise get the bookkey from the drop down list
                rev.BookKey = int.Parse(ddlTitles.SelectedValue.ToString());

            }
        //add all the values to the review object
            rev.ReviewDate = DateTime.Now;
            rev.ReviewerKey = key;
            rev.ReviewTitle = txtReviewTitle.Text;
            rev.ReviewRating = int.Parse(ddlRating.SelectedItem.Text);
            rev.ReviewText = txtReview.Text;
            //pass the review to the AddReview method
            bool result = rsc.AddReview(rev);
        //check the result to see if it wrote.
            if (result)
            {
                lbResult.Text = "Review Added";
            }
            else
            {
                lbResult.Text = "Review failed to save";
            }
        
    } 

No comments:

Post a Comment