BIT 285: (Web) Application Programming Instructor: Craig Duckett Lecture 07: Tuesday, January 27, 2015 Web.config, Cookies, URL Encoding, Themes, Master and Content Pages Assignment 1: Web Forms is due on Thursday, February 5rd (zipped and uploaded to StudentTracker by midnight) Assignment 2: Database is due on Thursday, February 26th 2 The Web.config File 3 The Web.Config File You might have been wondering what exactly the Web.config file does, as you’ve seen it in every project that you’ve worked with so far. The Web.config is an XML file which contains settings to tell the web server how to handle your web site. By changing the settings in Web.config you can modify many important settings. Changing settings in Visual Studio often automatically makes changes to your Web.config file. Whenever you create an new application project, you'll see that there is actually very little code inside the Web.config file. This is because ASP.NET 4.5 automatically manages a lot of settings that had to be specified in the Web.config file in previous versions of ASP.NET. 4 The Web.Config File: mimeType 5 Suggested Web.config Links of Interest • ASP.NET Web.config Guidelines (Microsoft) • ASP.NET Web.config File (Code Project) • ASP.NET Configuration (TutorialsPoint) • 10 Things ASP.NET Developers Need to Know About Web.config • Configuration-Specific Web.config Files (DrDobbs) • Configuration Files in ASP.NET (YouTube Video) • Prepare Web.config for HTML5 and CSS3 (Blog) • The Meaning of Mime-Types Error (Blog) 6 Cookies 7 Cookies A cookie is a name/value pair that is stored on the client's computer. To create a cookie, you instantiate an object from the HttpCookie class. Then, you include it in the HTTP response that the server sends back to the browser, and the user's browser stores the cookie either in its own memory or in a text file on the client machine's disk. A cookie that's stored in the browser's memory is called a session cookie because it exists only for that session. When the browser session ends, the contents of any session cookies are lost. Session cookies are what ASP.NET uses to track session ID's. In contrast, persistent cookies are written to disk, so they are maintained after the browser session ends. Whether session or persistent, though, once a cookie is sent to a browser, it's automatically returned to the server with each HTTP request. Besides using cookies for session IDs, you can use cookies to save information that identifies each user so the users don't have to enter that information each time they visit your web site. You can also use cookies to store information that lets you personalize the web pages that are displayed for a user. When you use cookies to store this type of information, you should keep in mind that some users may have disabled cookies on their browsers. In that case, you won't be able to save cookies on the user's computer. Unfortunately, ASP.NET doesn't provide a way for you to determine whether a user has disabled cookies. As a result, if you use cookies in an application, you may need to notify the user that cookies must be enabled to use it. 8 Cookies Cookies are fairly easy to use. Both the Request and Response objects (which are provided through Page properties) provide a Cookies collection. The important trick to remember is that you retrieve cookies from the Request object, and you set cookies by using the Response object. To set a cookie, just create a new HttpCookie object. You can then fill it with string information (using the name/value pattern) and attach it to the current web response: // Create the cookie object. HttpCookie userCookie = new HttpCookie("UserInfo"); // Set a value in it. cookie["Name"] = "Rex Winkus"; // Add another value. cookie["City"] = "Bothell"; // Add it to the current web response. Response.Cookies.Add(userCookie); A cookie added in this way will persist until the user closes the browser and will be sent with every request. 9 Cookies To create a longer-lived cookie, you can set an expiration date: // This cookie lives for 3 days userCookie.Expires = DateTime.Now.AddDays(3); or // This cookie lives for one year userCookie.Expires = DateTime.Now.AddYears(1); 10 Cookies You retrieve cookies by cookie name, using the Request.Cookies collection. Here’s how you retrieve the preceding cookie, which is named userInfo: HttpCookie cookie = Request.Cookies["UserInfo"]; This code won’t cause an exception if the cookie doesn’t exist. Instead, you’ll simply get a null reference. Before you attempt to retrieve any data from the cookie, you should test the reference to make sure you actually have the cookie: if (cookie != null) { string name = cookie["Name"]; string city= cookie["City"]; } The only way to remove a cookie is by replacing it with a cookie that has an expiration date that has already passed. This code demonstrates the technique: HttpCookie userCookie = new HttpCookie("UserInfo"); userCookie.Expires = DateTime.Now; Using IE for demo: %userprofile%\AppData\Roaming\Microsoft\Windows\Cookies (You'll need to "show" hidden system files to see them) 11 Cookies WALK THROUGH DEMO Using IE for demo: %userprofile%\AppData\Roaming\Microsoft\Windows\Cookies (You'll need to "show" hidden system files to see them) 12 Suggested Cookies Links of Interest • ASP.NET Cookies Overview (Microsoft) • Beginner's Guide to ASP.NET Cookies (Code Project) • On the Care and Handling of Cookies (Code Project) • Reading and Writing Cookies in ASP.NET and C# (ASPNetTutorials) • Code: How to Use Cookies in ASP.NET (Runnable) 13 URL Encoding (Query Strings Revisited) 14 URL Encoding (Query Strings Revisitied) What is a QueryString? A query string is a value specified in an HTTP query that can be accessed easily within ASP.NET. The query string is appended at the end of the URL following the question mark ? character. Multiple query strings can be specified in the URL by separating them by either an ampersand & or a semicolon ; . The following is an example of the query string with a field name of id and a value of 1: http://www.mywebsite.com/default.aspx?id=1. Query strings can be used for many different reasons, one common use is to display different data on the same page based on the query string. For example, if I had an online store and wanted a page to display an inidividual item from my database on the page, we could use a query string. This would work by passing something such as the item’s id in the database as a query string to the page, and then displaying data from the database based on the value of the query string. 15 URL Encoding (Query Strings Revisitied) One potential problem with the query string is that some characters are not allowed in a URL. In fact, the list of characters that are allowed in a URL is much shorter than the list of allowed characters in an HTML document. All characters must be alpha-numeric or one of a small set of special characters, including $ -_ . + ! * ' ( ) , . Some browsers tolerate certain additional special characters (Internet Explorer is notoriously lax), but many do not. Furthermore, some characters have special meaning. For example, the ampersand & is used to separate multiple query string parameters, the plus sign + is an alternate way to represent a space, and the pound sign # is used to point to a specific bookmark in a web page. If you try to send query string values that include any of these characters, you will lose some of your data. To avoid potential problems, it’s a good idea to perform URL encoding on text values before you place them in the query string. With URL encoding, special characters are replaced by escape character sequences starting with the percent sign %, followed by a two-digit hexadecimal representation. For example, the & character becomes %26. The only exception is the space character, which can be represented as the character sequence %20 or the + sign. To perform URL encoding, you use the UrlEncode() and UrlDecode() methods of the HttpServerUtility class. 16 URL Encoding (Query Strings Revisitied) The following code uses the UrlEncode() method to rewrite the code of the querystringdemo example, so it might work with input that contains special characters: string url = "Default2.aspx?"; url += "UserId=" + Server.UrlEncode(txtUserId.Text) + "&"; url += "UserName=" + txtUserName.Text; Response.Redirect(url); Notice that it’s important not to encode everything. In this example, you can’t encode the & character that joins the two query string values, because it truly is a special character. You can use the UrlDecode() method to return a URL-encoded string to its initial value. However, you don’t need to take this step with the query string. That’s because ASP.NET automatically decodes your values when you access them through the Request.QueryString collection. NOTE: Many people still make the mistake of decoding the query string values a second time. Usually, decoding already decoded data won’t cause a problem. The only exception is if you have a value that includes the + sign. In this case, using UrlDecode() will convert the + sign to a space, which probably isn’t what you want. 17 Suggested URL Encoding Links of Interest • How to Encode a URL in Asp.NET (Blog) • How to Encode/Decome QueryString in ASP.NET (Blog) • ASP.NET Encode/Decode Functions (ASPNut) 18 Themes 19 Themes With the convenience of CSS styles, you might wonder why developers need anything more. The problem is that CSS rules are limited to a fixed set of style attributes. They allow you to reuse specific formatting details (fonts, borders, foreground and background colors, and so on), but they obviously can’t control other aspects of ASP. NET controls. For example, the CheckBoxList control includes properties that control how it organizes items into rows and columns. Although these properties affect the visual appearance of the control, they’re outside the scope of CSS, so you need to set them by hand. Additionally, you might want to define part of the behavior of the control along with the formatting. For example, you might want to standardize the selection mode of a Calendar control or the wrapping in a TextBox. This obviously isn’t possible through CSS. The themes feature fills this gap. Like CSS, themes allow you to define a set of style details that you can apply to controls in multiple pages. However, unlike CSS, themes are not implemented by the browser. Instead, ASP.NET. processes your themes when it creates the page. 20 Themes CONTINUED How Themes Work All themes are application specific. To use a theme in a web application, you need to create a folder that defines it. This folder needs to be placed in the App_Themes folder, which must be placed inside the toplevel directory for your web application. In other words, a web application named ProCommerce might have a theme named FunkyTheme in the folder ProCommerce\App_Themes\FunkyTheme. An application can contain definitions for multiple themes as long as each theme is in a separate folder. Only one theme can be active on a given page at a time. To actually make your theme accomplish anything, you need to create at least one skin file in the theme folder. A skin file is a text file with the .skin extension. ASP.NET never serves skin files directly; instead, they’re used behind the scenes to define a theme. A skin file is essentially a list of control tags—with a twist. The control tags in a skin file don’t need to completely define the control; they need only set the properties that you want to standardize. 21 Themes CONTINUED For example, if you’re trying to apply a consistent color scheme, you might be interested in setting only properties such as ForeColor and BackColor. When you add a control tag for the ListBox in the skin file, it might look like this: <asp:ListBox runat="server" ForeColor="White" BackColor="Orange"/> The runat="server" portion is always required. Everything else is optional. You should avoid setting the ID attribute in your skin file because the page that contains the ListBox needs to define a unique name for the control in the actual web page. It’s up to you whether you create multiple skin files or place all your control tags in a single skin file. Both approaches are equivalent because ASP.NET treats all the skin files in a theme directory as part of the same theme definition. Often, it makes sense to put the control tags for complex controls (such as the data controls) in separate skin files. 22 Themes CONTINUED 23 Themes CONTINUED WALK THROUGH: Creating and Applying a Simple Theme 1. Download and unzip the controlsdemo.zip file from Lecture 7 Example Files 2. Using Visual Studio, open the controlsdemo website 3. Select the BulletList.aspx page in Solution Explorer, and run debug to see what it does in browser. 4. Stop running the debug 5. In Solution Explorer, right-click on the project and Add > New > Skin File and give it the name lec7.skin. Visual Studio will warn you that skin files need to be placed in a subfolder of the App_Themes folder and ask you whether that’s what you intended. Choose Yes and Visual Studio will create a folder with the same name as your theme file. 24 Themes CONTINUED 6. Unfortunately, Visual Studio doesn’t include any design-time support for creating themes, so it’s up to you to copy and paste control tags from other web pages. Here’s a sample skin file that sets background and foreground colors for several common controls: <asp:ListBox runat="server" ForeColor="Green" BackColor="Wheat" /> <asp:TextBox runat="server" ForeColor="Green" BackColor=" Wheat " /> <asp:BulletedList runat="server" ForeColor="Green" BackColor=" Wheat " /> <asp:Button runat="server" ForeColor="Green" BackColor=" Wheat " /> 7. To apply the theme in a web page, you need to set the Theme attribute of the Page directive to the folder name for your theme. <%@ Page Language = "C#" AutoEventWireup = "true" ... Theme = "lec7" %> 8. Now ASP.NET will automatically look for a folder named AppThemes\FunkyTheme inside your website, and it will scan all the skin files in that theme. 9. You can make this change by hand, or you can select the DOCUMENT object in the Properties window at design time and set the Theme property (which provides a handy drop-down list of all your web application’s themes). Visual Studio will modify the Page directive accordingly. When you apply a theme to a page, ASP.NET considers each control on your web page and checks your skin files to see whether they define any properties for that control. If ASP.NET finds a matching tag in the skin file, the information from the skin file overrides the current properties of the control. 25 Themes CONTINUED Creating Multiple Skins for the Same Control Having each control locked into a single format is great for standardization, but it’s probably not flexible enough for a real-world application. For example, you might have several types of text boxes that are distinguished based on where they’re used or what type of data they contain. Labels are even more likely to differ, depending on whether they’re being used for headings or body text. Fortunately, ASP.NET allows you to create multiple declarations for the same control. Ordinarily, if you create more than one theme for the same control, ASP.NET will give you a build error stating that you can have only a single default skin for each control. To get around this problem, you need to create a named skin by supplying a SkinID attribute. <asp:ListBox runat="server" ForeColor="Green" BackColor="Wheat" /> <asp:TextBox runat="server" ForeColor="Green" BackColor="Wheat" /> <asp:Button runat="server" ForeColor="Green" BackColor="Wheat" /> <asp:TextBox runat="server" ForeColor="Green" BackColor="Orange" Font-Bold="True" SkinID="Bright"/> <asp:Button runat="server" ForeColor="Green" BackColor= "Orange" Font-Bold="True" SkinID="Bright"/> The catch is that named skins aren’t applied automatically like default skins. To use a named skin, you need to set the SkinID of the control on your web page to match. You can choose this value from a drop-down list that Visual Studio creates based on all your defined skin names, or you can type it in by hand: <asp:Button ID="Button1" runat="server" ... SkinID="Bright" /> If you don’t like the opt-in model for themes, you can make all your skins named. That way, they’ll never be applied unless you set the control’s SkinID. 26 Themes CONTINUED Applying a Theme to an Entire Website Using the Page directive, you can bind a theme to a single page. However, you might decide that your theme is ready to be rolled out for the entire web application. The cleanest way to apply this theme is by configuring the <pages> element in the web.config file for your application, as shown here: <configuration> <system.web> <pages theme = "lec7"> ... </pages> </system.web> </configuration> 27 Suggested Themes & Skins Links of Interest • ASP.NET Themes and Skins (Microsoft) • How to Define ASP.NET Themes (Microsoft) • How to Apply ASP.NET Themes (Microsoft) • How to Apply ASP.NET Themes Programmatically (Microsoft) 28 Master and Content Pages 29 Master and Content Pages As you develop the pages of a web site, you'll undoubtedly find that many pages require some of the same elements like headers, navigation bars, and footers. The easiest way to create pages with common elements like that is to use master pages. Essentially, a master page is a blueprint for part of your website. Using a master page, you can define web page layout, complete with the usual details such as headers, menu bars, and ad banners. Once you’ve perfected a master page, you can use it to create content pages. Each content page automatically acquires the layout and the content of the linked master page. Master pages are similar to ordinary ASP.NET pages. Like ordinary pages, master pages are text files that can contain HTML, web controls, and code. However, master pages have a different file extension (.master instead of .aspx), and they cannot be viewed directly by a browser. Instead, master pages must be used by other pages, which are known as the content pages. Essentially, the master page defines the page structure of the content pages. 30 Master and Content Pages Creating a Master Page in Visual Studio To create a master page in Visual Studio, select Website > Add New Item from the menu. Select Master Page, give it a file name (e.g., SiteTemplate.master), and click Add. 31 Master and Content Pages When you create a new master page in Visual Studio, you start with a blank page that includes a ContentPlaceHolder control. The ContentPlaceHolder is the portion of the master page that a content page can change. Or, to look at it another way, everything else that’s set in the master page is unchangeable in a content page. If you add a header, that header appears in every content page. If you want to give the content page the opportunity to supply content in a specific section of the page, you need to add a ContentPlaceHolder. 32 Master and Content Pages When you first create a master page, you’ll start with two (2) ContentPlaceHolder controls. One is defined in the <head> section, which gives content pages the add page metadata, such as search keywords and style sheet links. The second, more important ContentPlaceHolder is defined in the <body> section, and represents the displayed content of the page. It appears on the page as a faintly outlined box. If you click inside it or hover over it, the name of ContentPlaceHolder appears in a tooltip. To make this master page example more practical, try adding a header before the ContentPlaceHolder (using an <img> tag) and a footer after it (using some static text). You may notice that the content area of the page looks very small, but this appearance is deceptive. The content section will expand to fit the content you place inside. 33 Master and Content Pages Now you’re ready to create a content page based on this master page. To take this step, select Website > Add New Item from the menu. Select Web Form, and choose to select a master page. Click Add. 34 Master and Content Pages Now you’ll see something a little more interesting. Your content page will have all the elements of the master page, but the elements will be shaded in gray, indicating that you can’t select or change them in any way. However, you can add content or drag and drop new controls into the ContentPlaceHolder region to create a page like the one shown below. In fact, this is the only editable portion of your page. DEMO: masterpages.zip 35 Suggested Master Pages Links of Interest • ASP.NET Master Pages (MSDN) • Interacting with the Master Page from the Content Page (C#) (MSDN) • Interacting with the Content Page from the Master Page (C#) (MSDN) • Beginner's Tutorial on Master Pages in ASP.NET (Code Project) • How to Create Content Pages for an ASP.NET Master Page (MSDN) • Master Page and Content Page Interaction (Code Project) • ASP.NET Master Pages (W3Schools) • Create ASP.NET C# Master and Content Pages in Visual Studio 2012 (BBUps) • ASP.NET Master Pages (YouTube Video) • WALK THROUGH: Create ASP.NET Master Page Using HTML5 (YouTube Video) 36 Lecture 07: In-Class Exercise From the menu bar, select Lectures and go to the Lectures 07 bar and select Lecture 07 ICE to begin working on today's in-class exercises. 37