Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning ASP.NET 2.0 With CSharp (2006) [eng]

.pdf
Скачиваний:
84
Добавлен:
16.08.2013
Размер:
20.33 Mб
Скачать

Appendix A

Not only can you see these links, but clicking these links will take you to the appropriate pages.

Exercise 3

The Admin user has had a request by a reporter out in the field — he’s uploaded a score for a match, but the score has just changed. Unfortunately, the reporter’s laptop has run out of battery, so he’s asked the Admin user to update the score for him. Make sure that the Admin user can update the score of a match.

Solution

You have two options. First, you could add the Admin user to the Reporters role, thereby enabling the access to the page as desired. The alternative is to enable access to the UpdateScore.aspx page on the site to all site administrators by making the following change to the Web.config file within the root of the Admin folder:

<location path=”UpdateScore.aspx”> <system.web>

<authorization>

<allow roles=”Administrator, Reporter” /> </authorization>

</system.web>

</location>

Whichever method you decide on, the Admin user needs to be able to access the UpdateScore.aspx page. If you are successful, you will see Figure A-8.

Figure A-8

638

Exercise Answers

Exercise 4

Add a field to the user profile for the Wrox United application called DateOfBirth. Give this property a data type of System.DateTime. Add an input field to the FanClub.aspx page so that users can update their date of birth. Note that you will need to convert the value entered in a text box to a DateTime value when you save the data — you might want to try the DateTime.Parse() function for this purpose. To retrieve the data, use the Profile.DateOfBirth.ToShortDateString() function.

Solution

1.Add the following highlighted line to Web.config:

<profile enabled=”true”> <properties>

<add name=”MemberName”/> <add name=”Name”/>

<add name=”Address”/> <add name=”City”/> <add name=”County”/> <add name=”PostCode”/> <add name=”Country”/>

<add name=”Mailings” type=”System.Boolean”/> <add name=”Email”/>

<add name=”DateOfBirth” type=”System.DateTime”/> <add name=”Theme”/>

<add name=”Cart” serializeAs=”Binary” type=”Wrox.Commerce.ShoppingCart” allowAnonymous=”true”/>

</properties>

</profile>

2.Modify FanClub.aspx to include a text box for entering and displaying the date of birth:

<span class=”boxFloat”>Name:<br /> Address:<br />

<br /> <br /> <br />

City:<br /> County:<br /> Postcode:<br /> Country:<br />

Subscribe to email updates:<br /> Email:<br />

Date of Birth: <br /> Membership Alias:<br /> Theme:</span><span>

<asp:TextBox ID=”txtName” runat=”server” Columns=”30” /> <br />

...

<asp:TextBox ID=”txtEmail” runat=”server” /> <br />

<asp:TextBox ID=”txtDoB” runat=”server” />

<br />

<asp:TextBox ID=”txtAlias” runat=”server” /> <br />

...

</span>

639

Appendix A

3.The code file for the FanClub.aspx page also needs some changes. First, modify the btnSaveChanges_Click event handler code:

protected void btnSaveChanges_Click( object sender, System.EventArgs e)

{

Profile.Theme = ((DropDownList)FCLoginView.FindControl(“ThemeList”)).SelectedValue;

Profile.Name = ((TextBox)FCLoginView.FindControl(“txtName”)).Text; Profile.Address = ((TextBox)FCLoginView.FindControl(“txtAddress”)).Text; Profile.City = ((TextBox)FCLoginView.FindControl(“txtCity”)).Text; Profile.County = ((TextBox)FCLoginView.FindControl(“txtCounty”)).Text; Profile.PostCode = ((TextBox)FCLoginView.FindControl(“txtPostCode”)).Text; Profile.Country = ((TextBox)FCLoginView.FindControl(“txtCountry”)).Text; Profile.Mailings = ((CheckBox)FCLoginView.FindControl(“chkMailing”)).Checked; Profile.Email = ((TextBox)FCLoginView.FindControl(“txtEmail”)).Text; Profile.MemberName = ((TextBox)FCLoginView.FindControl(“txtAlias”)).Text;

TextBox DoB = (TextBox)FCLoginView.FindControl(“txtDoB”); if (DoB.Text <> “”)

{

Profile.DateOfBirth = DateTime.Parse(DoB.Text);

}

Server.Transfer(SiteMap.CurrentNode.Url);

}

Note that you need to check that the text box is not empty (if you try to save with an empty text box, you’ll see an error page due to an exception).

4.Add the following code to the DisplayProfileProperties()method:

private void DisplayProfileProperties()

{

TextBox NameBox = (TextBox)FCLoginView.FindControl(“txtName”);

if (NameBox != null)

{

((DropDownList)FCLoginView.FindControl(“ThemeList”)).SelectedValue = Profile.Theme;

((TextBox)FCLoginView.FindControl(“txtName”)).Text = Profile.Name; ((TextBox)FCLoginView.FindControl(“txtAddress”)).Text = Profile.Address; ((TextBox)FCLoginView.FindControl(“txtCity”)).Text = Profile.City; ((TextBox)FCLoginView.FindControl(“txtCounty”)).Text = Profile.County; ((TextBox)FCLoginView.FindControl(“txtPostCode”)).Text = Profile.PostCode; ((TextBox)FCLoginView.FindControl(“txtCountry”)).Text = Profile.Country; ((CheckBox)FCLoginView.FindControl(“chkMailing”)).Checked = Profile.Mailings; ((TextBox)FCLoginView.FindControl(“txtEmail”)).Text = Profile.Email; ((TextBox)FCLoginView.FindControl(“txtAlias”)).Text = Profile.MemberName; ((TextBox)FCLoginView.FindControl(“txtDoB”)).Text =

Profile.DateOfBirth.ToShortDateString();

}

}

This code will convert the DateTime value stored in the user’s profile into its string representation so that it can be displayed on the screen. Because users are unlikely to know the exact time they were born, you can ignore the time part of the date — which is why you used the ToShortDateString() instead of ToString() method. After you are finished, you can test

it out on the user of your choice. Figure A-9 uses Alan the Admin.

640

Exercise Answers

Figure A-9

Chapter 12

Exercise 1

What is the role of SOAP in web services?

Solution

SOAP is a framework for exchanging messages. Its role in web services is to parcel function calls and parameters to enable you to call the web services remotely in a standardized way.

Exercise 2

Create a web service that retrieves a Wrox United score whenever they’ve scored more than one goal.

Solution

[WebMethod]

public DataSet Fixtures() As

{

641

Appendix A

SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[“WroxUnited”].ConnectionString );

SqlDataAdapter adapter = new SqlDataAdapter(“SELECT FixtureDate, Opponents, FixtureType, GoalsFor, GoalsAgainst FROM Fixtures WHERE GoalsFor>1 ORDER BY FixtureDate”, conn);

DataSet ;

adapter.Fill(ds, “Fixtures”);

return ds;

}

Exercise 3

Create a page that consumes the third-party weather forecast for Birmingham, United Kingdom. (Hint: You will also need to discover this service first.)

Solution

Add a Web Reference first via the Add Web Reference function and discover the service by typing the URL www.webservicex.net/globalweather.asmx

Create a blank page and add a label called Weather Label to it. Then add the following code to the codebehind:

partial class WeatherPage :System.Web.UI.Page

{

protected void Page_Load(object sender , EventArgs e )

{

net.webservicex.www.GlobalWeather wsConvert = new net.webservicex.www.GlobalWeather();

wsConvert.Credentials = System.Net.CredentialCache.DefaultCredentials; WeatherLabel.Text = wsConvert.GetWeather(“Birmingham”, “United Kingdom”).ToString();

}

}

Chapter 13

Exercise 1

The member discount is something that is applied to the shopping cart as you add items to the cart. What do you need to add to the ShoppingCart object to make sure it can store a discount of 10% for fan club members? You can assume that you can detect a fan club member with the property:

HttpContext.Current.User.IsInRole(“FanClubMember”).

Hint: You will need to create a subtotal as well.

642

Exercise Answers

Solution

You need to create a MemberDiscount property first:

public class ShoppingCart

{

private single const MemberDiscountPercentage = 0.1;

...

public readonly double MemberDiscount() get

if (HttpContext.Current.User.IsInRole(“FanClubMember”))

{

return SubTotal * MemberDiscountPercentage;

}

else

{

return 0;

}

}

}

}

Then you need to create a SubTotal property because between the total and the individual prices of the items, you need to show how you arrive at your figures — otherwise, it will just look like your shopping cart doesn’t add up correctly:

public readonly double SubTotal() get

{

double t

if (_items == null}

{

return 0;

}

foreach (CartItem Item In _items) t += Item.LineTotal;

}

return t;

}

}

Then you’ll need in Source View to add a Panel called DiscountPanel and add two labels, one called SubTotalLabel and another called MemberDiscount, and make sure both contain nothing to begin with and that both are visible.

You’ll also need to add some extra parameters to the checkout.aspx page called @subtotal and @memberdiscount, and make sure they are added as part of the INSERT clause in this page.

Exercise 2

How can you display the member discount details on the Shopping Cart page so that only a fan club member will see them?

643

Appendix A

Solution

You need to check to see whether a user is in the role FanClubMember, and only if they are do you then apply the extra formatting to show the subtotal and the member discount items. Last, you display the discount panel:

if (Context.User.IsInRole(“FanClubMember”)) SubTotalLabel.Text = string.Format(“Sub-Total:{0,35:C}”, Profile.Cart.SubTotal);

MemberDiscount.Text = string.Format(“Member Discount:{0:C}”, Profile.Cart.MemberDiscount);

DiscountPanel.Visible = True;

}

Chapter 14

Exercise 1

Convert the two shop pages, Shop.aspx and ShopItem.aspx, from using SQL statements to stored procedures.

Solution

For Shop.aspx, you need to create the following stored procedure:

CREATE PROCEDCURE dbo.usp_Shop

AS

SELECT ProductID, Name, Description, Price, PictureURL

FROM Products

ORDER BY Name

Next, change the SelectCommand from the SQL to usp_Shop.

For ShopItem.aspx, the stored procedure should be as follows:

CREATE PROCEDURE dbo.usp_ShopItem @ProductID int

AS

SELECT *

FROM Products

WHERE ProductID = @ProductID

Next, change the SelectCommand from the SQL to usp_ShopItem.

Exercise 2

Add caching to the ShopItem.aspx page, so that the page is cached. Note that you need to take into account that this page shows different products, so the cache needs to be varied by the product being shown.

644

Exercise Answers

Solution

For this you simply add the OutputCache directive to the page, but because the product being shown is defined in the querystring, you need to vary it with the following querystring:

<%@ OutputCache Duration=”3600” VaryByParam=”ProductID” %>

Chapter 15

Exercise 1

Add defensive coding to the GenerateThumbnail method of the ImageHandling class stored in the App_Code directory.

Solution

Having learned what you have about defensive coding and exceptions, you might be tempted to change the code for GenerateThumbnail to what was shown in the chapter, where both defensive coding and exception handling were used. However, during the chapter, you used the Application_Error event to centrally log exceptions, so the explicit logging within GenerateThumbnail isn’t required. But you still need to code against a missing source file, so the code could be changed to the following:

public static void GenerateThumbnail(string SourceImagePath, string TargetImagePath)

{

if (!File.Exists(sourceImagePath))

return;

using (Image image1 = Image.FromFile(SourceImagePath))

{

short num1 = (short) Math.Round((double) (image1.Height * 0.25)); short num2 = (short) Math.Round((double) (image1.Width * 0.25)); Image.GetThumbnailImageAbort abort1 =

new Image.GetThumbnailImageAbort(ImageHandling.ThumbnailCallback); using (Image image2 = image1.GetThumbnailImage(num2, num1,

abort1, IntPtr.Zero))

{

image2.Save(TargetImagePath, ImageFormat.Gif);

}

}

}

This assumes that a failure generating the thumbnail isn’t critical, which may not be a correct assumption. Thumbnails are generated when pictures are uploaded to the site — pictures such as products for the shop, match photos, and so on. The site can run quite well when these images are missing, so it isn’t critical, and any exception would be logged by the central code so the site administrators would know about it.

645

Appendix A

Exercise 2

Add validation controls to the Checkout page, the part that accepts the delivery address. There is a check box to copy the address from the membership details of the user, but there is nothing to ensure that all of the fields are filled in.

Solution

To ensure data is entered into the address boxes, you can use RequiredFieldValidator controls. You can add a validator for each TextBox, adding it next to the field it validates:

<tr><td><asp:TextBox id=”txtName” runat=”server” /> <asp:RequiredFieldValidator id=”rfv1” runat=”server”

ControlToValidate=”txtName” Text=”*”

ErrorMessage=”You must enter a value for the delivery name” />

</td></tr>

You will also need a ValidationSummary, which can be put after the table containing the address fields:

</table>

<asp:ValidationSummary id=”vs” runat=”server” DisplayMode=”BulletList” /> </asp:WizardStep>

Exercise 3

Use the debugger.

Solution

This exercise is more important than you realize, because learning how to debug is critical, especially when you are a beginner. When learning, you tend to make more mistakes, or perhaps code less efficiently than you do with years of experience. That’s only natural, and learning how to quickly track down bugs will make you a better developer, not only because you’ll be good at finding bugs, but also because, in finding those bugs, you learn what the problem was and how to avoid it next time. So in finding bugs you become a better coder.

Chapter 16

Exercise 1

You are now developer and maintainer of the Wrox United web site. What else would you add to the Wrox United site? Make a list of possible add-ons, and prioritize them with the simplest to do first. Implement some of these add-ons.

Solution

There is no hard and fast solution to this exercise, but to get some ideas for add-ons to your site, or to compare notes with other developers and the authors of this book, go to http://p2p.wrox.com and look for this book’s discussion board.

646

B

Setup

The ASP.NET 2.0 runtime comes as part of the Visual Web Developer Express download. ASP has undergone an evolution in terms of setup, each version being simpler (although often larger and lengthier) to install than the previous one. In classic ASP 2.0, ASP was separate even from the IIS web server itself, both of which had to be downloaded and attached manually to IIS. By version 3.0 of classic ASP, ASP had been integrated with the web server. With ASP.NET 1.x, you had to download the .NET Framework separately to get ASP, and enable IIS, which by then was part of the operating system. However, throughout each of these iterations, you still had to download and install a database solution separately.

With ASP.NET 2.0, all four parts come together in one easy-to-install package — Visual Web Developer Express 2005. ASP.NET 2.0, the web server, development tools, and the database are all installed at the same time. The web server is a test-development server nicknamed ASP.NET Development Server (after the discoverer of the gaps and particular matter in the rings of Saturn) and can run without IIS, alongside IIS, or you can choose to use IIS in place of the ASP.NET Development Server.

System Requirements

Before you install VWD Express, you should check that your system meets the minimum requirements. We have taken the requirements from the Microsoft web site. They are listed in the following sections.

Processor

Minimum: 600 megahertz (MHz) Pentium processor.

Recommended: 1 gigahertz (GHz) Pentium processor.