ASP.NET 4.0 in Practice phần 5 pps

50 425 0
ASP.NET 4.0 in Practice phần 5 pps

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

175TECHNIQUE 43 Build a table-less control adapter for the DataList VB: If ((index + 1) Mod RepeatColumns) = 0 Then writer.Indent -= 1 writer.WriteLine() writer.WriteEndTag("div") End If Next As you can see, the code isn’t complex, but it requires that you understand how the DataList (and template controls) works. To complete the scenario, we need to show you how to render the header (and footer). The following listing contains the code. C#: private void RenderHeader(HtmlTextWriter writer, DataList dataList) { writer.WriteBeginTag("div"); CssStyleCollection style = GetStyleFromTemplate(dataList, dataList.HeaderStyle); if (!String.IsNullOrEmpty(style.Value)) writer.WriteAttribute("style", style.Value); writer.Write(HtmlTextWriter.TagRightChar); PlaceHolder container = new PlaceHolder(); dataList.HeaderTemplate.InstantiateIn(container); container.DataBind(); if ((container.Controls.Count == 1) && typeof(LiteralControl) .IsInstanceOfType(container.Controls[0])) { writer.WriteLine(); LiteralControl literalControl = container.Controls[0] as LiteralControl; writer.Write(literalControl.Text.Trim()); } else { container.RenderControl(writer); } writer.WriteEndTag("div"); } VB: Private Sub RenderHeader(ByVal writer As HtmlTextWriter, ByVal dataList As DataList) writer.WriteBeginTag("div") Dim style As CssStyleCollection = GetStyleFromTemplate(dataList, dataList.HeaderStyle) If Not String.IsNullOrEmpty(style.Value) Then writer.WriteAttribute("style", style.Value) Listing 7.6 Rendering the header with a special function Preserve style, if specified B Instantiate and bind template C Specific to text- only controls D Preserve style, if specified B 176 CHAPTER 7 Taking control of markup End If writer.Write(HtmlTextWriter.TagRightChar) Dim container As New PlaceHolder() dataList.HeaderTemplate.InstantiateIn(container) container.DataBind() If (container.Controls.Count = 1) AndAlso GetType(LiteralControl) .IsInstanceOfType(container.Controls(0)) Then writer.WriteLine() Dim literalControl As LiteralControl = TryCast(container.Controls(0), LiteralControl) writer.Write(literalControl.Text.Trim()) Else container.RenderControl(writer) End If writer.WriteEndTag("div") End Sub The interesting part in this code listing is how the styles are restored (which is per- formed for the ItemTemplate , too). This code lets you specify a CSS style using the ItemStyle B or HeaderStyle properties, so you won’t lose any features from the stan- dard DataList . Data binding C is also supported, as well as Literal -only controls D . The RenderFooter method is similar to RenderHeader , so we’ve omitted it from the code (you can find it in the downloadable samples). Just as with the header, the footer is rendered if a template is specified. If you register this control adapter (as we did in the previous scenario), you can adapt the DataList rendering to be more standard-friendly. Figure 7.3 shows you the result. This layout is identical to what you would get if you didn’t use the adapter. To produce this result, both the RenderBeginTag and RenderEndTab methods are overridden to generate a container < div /> tag, instead of the original <table /> tag. In this way, you can replace all the tags with your own. Instantiate and bind template C Specific to text-only controls D Products (Vertical) Yogurt Beef Cheese Bread Biscuits Fish Peanuts Pasta Pork Soy Other Products (Horizontal) Yogurt Bread Peanuts Soy Beef Biscuits Pasta Other Cheese Fish Pork Figure 7.3 The layout generated for the DataList control remains the same as the original. You can use control adapters to enhance the visual results without changing the control declaration. 177TECHNIQUE 43 ASP.NET 4.0 browser capabilities DISCUSSION Control adapters are incredibly powerful, as you might have noticed by examining the two scenarios we covered in this chapter. Because you can also write page adapters— after all, a page is a control, so this makes sense—the sky’s the limit when it comes to what control adapters can do for you. You can use adaptive rendering to selectively adapt the control rendering to differ- ent devices or to globally change its behavior if you need to. Even though the focus of ASP.NET 4.0 is to be friendlier to web standards, old controls like DataList might ben- efit from a little makeup. 7.1.1 Mobile controls and the Control Adapter Toolkit Mobile controls were the first example of adaptive rendering. Introduced in ASP.NET 1.0, they were intended to provide the right markup for different kinds of mobile devices automatically. At the time, mobile devices were quite different from each other: there was c HTML, XHTML, WML, and so on. Right now, it’s clear that the mobile web is composed of smart devices capable of rendering complex layouts, and these original control adapters (and their respective controls) aren’t needed any more. For that reason, mobile controls are deprecated in ASP.NET 4.0. If you need to maintain a solution based on this technology, you can update the browser definitions on this page: http://mdbf.codeplex.com/. (Note that the informa- tion on this website is no longer updated or supported.) From http://www.asp.net/ mobile/, you can browse for more content and access the original controls source code. CSS Friendly Control Adapters, also known as the CSS Control Adapter Toolkit, is a pack of control adapters shipped after ASP.NET 2.0 that increases adherence to web standards for controls like Login , Menu , and so on. They were intended to provide more CSS-friendly controls, with a cleaner markup structure. At the time of this writing, a Control Adapter Toolkit equivalent doesn’t exist for ASP.NET 4.0, which actually makes sense if you think about it. In chapter 6, we explained the new features of ASP.NET web controls, and the short story is that they now embed a set of adapters to produce better markup without adding external classes. At http://www.asp.net/cssadapters/ you can download the original implementa- tion. We’re recommending that you download this implementation because you can look at it to understand how to implement control adapters. The download contains great examples of how to deal with adaptive rendering. Now that we’re done with adaptive rendering, the next part of the chapter is dedi- cated to how you can influence this feature by specifying the browser capabilities. Some new features in ASP.NET 4.0 make this area more interesting than ever. 7.2 ASP.NET 4.0 browser capabilities We’ve talked about ASP.NET browser capabilities before. They work in conjunction with adaptive rendering. To be more precise, browser capabilities influence the way control adapters are used by ASP.NET for rendering infrastructure, for both pages and controls. 178 CHAPTER 7 Taking control of markup This feature is innate in ASP.NET and is based on a set of file definitions that include the most common user agents, from both stand-alone and mobile device browsers. Time has proven that it’s practically impossible for Microsoft to maintain this list and keep it updated, so new alternatives have emerged. To maintain updated defini- tions before ASP.NET 4.0, you had to do it manually. Now several different sources pro- vide the definitions, and one of the most authoritative is the definition distributed at http://mdbf.codeplex.com/. In the current version of ASP.NET, the following browsers and platforms are directly supported: Plus, there’s a generic profile, a profile for search engine crawlers/spiders, and a default profile to cover the other platforms and browsers. Even though the file definitions represent a useful way to instruct browser capabil- ities and adaptive rendering, it’s sometimes better to control the way the capabilities are provided via code. Even if .browser files (and everything else in ASP.NET) are con- verted in objects, having complete control over the process can produce simpler results than editing or updating those XML files. That’s why ASP.NET 4.0 introduces the concept of browser capabilities providers. Building a custom browser capabilities provider You can use ASP.NET browser capabilities providers to totally replace the standard capabilities definition mechanism or to expand it by adding new functionalities. By replacing the standard definition, you can alter the way ASP.NET produces output. PROBLEM One of the problems of the default file definitions is that they’re not updated regu- larly. We want to bypass the standard mechanism and provide a new one that will pro- duce, for every request, the best markup possible. SOLUTION ASP.NET 4.0 introduces a new class, named HttpCapabilitiesProvider . This feature implements the Provider Model pattern, which we’ll explain in chapter 11. Basically, it works the same way as the Membership Provider pattern: you can define a provider to implement a specific behavior, using a base class as the interface to implement. The providers are guaranteed to have the same identical structure, so they can be defined in the configuration. The advantage is that you don’t need to write specific adapters or define file configurations, but you can express your own rules in code. To implement a custom engine, you have to overwrite the GetBrowserCapabili- ties method and provide a new instance of HttpBrowserCapabilities . Because this ■ RIM’s Blackberry ■ Internet Explorer Mobile ■ Google Chrome ■ Apple’s iPhone ■ Mozilla FireFox ■ Opera ■ Internet Explorer ■ Apple’s Safari TECHNIQUE 44 179TECHNIQUE 44 Building a custom browser capabilities provider method will be called several times during the page lifecycle, you need to specify a caching pattern. (If you don’t know how cache works, you can find more information in chapter 14.) The following listing shows a basic implementation of a provider. C#: public class MyBrowserProvider : HttpCapabilitiesProvider { public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest request) { string cacheKey = "MyBrowserProvider_"+ request.UserAgent??"empty"; int cacheTimeout = 360; HttpBrowserCapabilities browserCaps = HttpContext.Current.Cache[cacheKey] as HttpBrowserCapabilities; if (browserCaps == null) { browserCaps = new HttpBrowserCapabilities(); Hashtable values = new Hashtable(20, StringComparer.OrdinalIgnoreCase); values["browser"] = request.UserAgent; values["tables"] = "true"; values["supportsRedirectWithCookie"] = "true"; values["cookies"] = "true"; values["ecmascriptversion"] = "3.0"; values["w3cdomversion"] = "1.0"; values["jscriptversion"] = "6.0"; values["tagwriter"] = "System.Web.UI.HtmlTextWriter"; values["IsIPhone"] = ((request.UserAgent ?? string.Empty).IndexOf("iphone") > -1).ToString(); browserCaps.Capabilities = values; HttpRuntime.Cache.Add(cacheKey, browserCaps, null, DateTime.Now.AddSeconds(cacheTimeout), TimeSpan.Zero, CacheItemPriority.Low, null); } return browserCaps; } } VB: Public Class MyBrowserProvider Inherits HttpCapabilitiesProvider Public Overloads Overrides Function GetBrowserCapabilities( ByVal request As HttpRequest) As HttpBrowserCapabilities Dim cacheKey As String = If("MyBrowserProvider_" & Listing 7.7 The custom browser capabilities provider Unique key for user agent Standard capabilities Custom capabilities 180 CHAPTER 7 Taking control of markup request.UserAgent, "empty") Dim cacheTimeout As Integer = 360 Dim browserCaps As HttpBrowserCapabilities = TryCast(HttpContext.Current.Cache(cacheKey), HttpBrowserCapabilities) If browserCaps Is Nothing Then browserCaps = New HttpBrowserCapabilities() Dim values As New Hashtable(20, StringComparer.OrdinalIgnoreCase) values("browser") = request.UserAgent values("tables") = "true" values("supportsRedirectWithCookie") = "true" values("cookies") = "true" values("ecmascriptversion") = "3.0" values("w3cdomversion") = "1.0" values("jscriptversion") = "6.0" values("tagwriter") = "System.Web.UI.HtmlTextWriter" values("IsIPhone") = ( ( If(request.UserAgent, String.Empty)).IndexOf("iphone") > -1) .ToString() browserCaps.Capabilities = values HttpRuntime.Cache.Add(cacheKey, browserCaps, Nothing, DateTime.Now.AddSeconds(cacheTimeout), TimeSpan.Zero, CacheItemPriority.Low, Nothing) End If Return browserCaps End Function End Class As you see in this listing, we’re defining a set of capabilities. The ones we’ve defined are the minimum you need to make the page work. They’ll instruct the server controls to use the most advanced markup and JavaScript code. Figure 7.4 contains the results of the default provider and of our custom provider. Unique key for user agent Standard capabilities Custom capabilities Figure 7.4 The new provider populates the properties according to its code. You can see the default provider using IE 8.0 on the left and the custom provider on the right. 181TECHNIQUE 44 Building a custom browser capabilities provider You can specify the provider you want to use in web.config, using this code: <configuration> <system.web> <browserCaps provider="ASPNET4InPractice.MyBrowserProvider, App_Code" /> </system.web> </configuration> Or, if you prefer, you can define the provider programmatically in global.asax, using the Application_Start event (or using an equivalent HttpModule ): C#: void Application_Start(object sender, EventArgs e) { HttpCapabilitiesBase.BrowserCapabilitiesProvider = new MyBrowserProvider(); } VB: Private Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) HttpCapabilitiesBase.BrowserCapabilitiesProvider = New MyBrowserProvider() End Sub You can define both standard and non-standard capabilities in your definition, and you can query them using a similar syntax: <ul> <li>IsMobile device: <%=Request.Browser.IsMobileDevice %></li> <li>Platform: <%=Request.Browser.Platform %></li> <li>IsIPhone: <%=(Request.Browser["IsIPhone"] as string)%></li> </ul> As we already noted, you can see the result of all this code in figure 7.4. Note that you should express the values as strings, even if the capabilities are then exposed as a boolean . This behavior is probably caused by the first implementation in ASP.NET 1.0, where text is mandatory (because it was based on XML tags), and you need to address this problem if you want to make the code work. DISCUSSION Browser capabilities providers are super useful when you want to add new properties or provide a new way to define the default capabilities. In its simplest form, a provider is composed of few lines of code, but, as you might have noticed in the case of the new IsIPhone property, you can also define new properties based on code evaluation. This solution has no drawbacks, because even the XML definition files are com- piled. You don’t need to worry about performance impacts—there aren’t any! Speaking of browser capabilities, the last scenario of this chapter addresses a com- mon problem: how to validate your markup against the World Wide Web Consortium ( W3C) Markup Validation Service. 182 CHAPTER 7 Taking control of markup Validating ASP.NET pages with the W3C validator Adaptive rendering can be both a joy and a pain. An example of the latter is certainly the absence of the W3C validator user agent from the default, recognized browsers. The W3C validator is a service from W3C (an international community that develops web standards) that aims to help web developers verify that their pages are using the right markup. The fact that this validator isn’t included can be a problem if you want to validate your page’s markup, mainly because the output generated for an unknown browser is a conservative HTML 3.2. PROBLEM If you try to validate the markup generated by an ASP.NET page with the W3C valida- tor, you’ll probably have trouble. ASP.NET doesn’t recognize the user agent and serves the least advanced markup that it can handle—HTML 3.2. This outcome isn’t a prob- lem per se, but it can become annoying if you want to validate the markup that’s likely to be served to most of the browsers. SOLUTION As we’ve mentioned before, ASP.NET uses the browser capabilities to produce specific output for specific browsers. If you need to produce better markup by default, you can use the example in technique 44, where a unique behavior is applied to all the requests. If you don’t want to override the default provider, you can define a custom file def- inition. The W3C validator user agent contains W3C_Validator in the sent string. To identify it, all you need is to produce a rule, which is shown in the following listing. <browsers> <browser id="W3C_Validator" parentID="default"> <identification> <userAgent match="^W3C_Validator" /> </identification> <capabilities> <capability name="browser" value="W3C Validator" /> <capability name="ecmaScriptVersion" value="1.2" /> <capability name="javascript" value="true" /> <capability name="supportsCss" value="true" /> <capability name="tables" value="true" /> <capability name="w3cdomversion" value="1.0" /> <capability name="tagWriter" value="System.Web.UI.HtmlTextWriter" /> </capabilities> </browser> </browsers> As you can see in this listing, by specifying HtmlTextWriter instead of Html32TextWriter , you can produce XHTML/HTML 4.01 markup, instead of HTML 3.2. The other properties will do the rest to enable DOM, JavaScript, and CSS support. Listing 7.8 The .browser file to support WC3 validator user agent TECHNIQUE 45 RegEx intercepts browser Tag writer 183Summary You can register the adapter globally or locally by saving this file as w3c.browser in your \App_Browsers\ folder. DISCUSSION ASP.NET 4.0 provides great flexibility in terms of markup generation and browser capabilities. You can leverage the new features to enrich your applications with less effort than in the past. This last scenario is a great example of how you can add more features by simply understanding how the infrastructure works. Even if these scenarios don’t fit in every application you’ll build, they can help you when you need a bit more control. 7.3 Summary Adaptive rendering and control adapters aren’t entirely new to ASP.NET 4.0, but they’re great examples of flexibility. You can control virtually any server control and alter the markup. As you learned in this chapter, generating a new markup and substituting the orig- inal one is pain-free. All you need to do is write a control adapter, register it, and then ASP.NET automatically performs the choice. Sometimes this isn’t easy (it depends on how complex the original control is), but the results are always interesting and worth the effort. On the other hand, browser capabilities do have new features in version 4.0. Now you can completely substitute the entire engine to define your own set of definitions. When you want to force a particular feature in your output, this capability is priceless. ASP.NET uses the browser capabilities to drive adaptive rendering, and to provide bet- ter output when the user agent is recognized and a specific markup profile is loaded. By controlling both adaptive rendering and browser capabilities, you can’t only produce better markup. You can also help put into practice a better web by imple- menting correct support for web standards and at the same time promoting accessibil- ity. You can even boost your old, existing applications by moving them to ASP.NET 4.0 Now that the story behind ASP.NET Web Forms is almost complete, we can take a look at how ASP.NET MVC lets you build the user interface in a way that’s quite differ- ent. The next chapter will focus on how you can use ASP.NET MVC even if you’re a nov- ice developer, by leveraging your ASP.NET Web Forms skills. [...]... website or ASP.NET MVC applications In ASP.NET MVC, routing plays a central role during the handling of an HTTP request It connects the URL coming from the browser to the specific controller and TECHNIQUE 48 201 Routing in ASP.NET MVC Routing was originally only an ASP.NET MVC peculiarity Routing in ASP.NET was originally part of the first release of ASP.NET MVC It signaled a break from the past, giving the...Part 3 ASP.NET MVC I n part 2, we took a look at ASP.NET Web Forms You might not know it, but using ASP.NET Web Forms isn’t the only way to produce the UI; in part 3, we’re going to investigate the option of building your UI with ASP.NET MVC ASP.NET MVC is a new option added in ASP.NET 3 .5 SP1 and directly integrated into ASP.NET 4.0 as ASP.NET MVC 2.0 It’s not the new Web... contained the axd extension When you’re building a view, if you want to create a link that points to another page, you can use the ActionLink or RouteLink HTML helpers, shown in the following listing Listing 8.7 HTML helpers for creating links to other controllers C#: Link text VB: Link text 204 CHAPTER 8 Introducing ASP.NET MVC You can use either ActionLink or RouteLink, depending on how you want to reference the linked page ActionLink works with the action (Index) and controller (Home)... programming Object Business Model model it provides, the risk of ending up having Layer monolithic pages with methods running for hundreds lines of code is quite high Data Access During the last few years, the need for writing Layer automated tests has gained popularity in the software industry Developers want a test suite Database that ensures their code is correct and will do its job Writing unit... you’re going to show to the UI, which often results in a composition of both business entities and interfacespecific objects In figure 8.6, we’ll consider once again the homepage mockup that you saw in figure 8 .5 This time we’ve highlighted the components that contribute to our page Putting it all together, we can represent them with a HomepageModel class like the one shown in the following listing and... giving the URLs a functional meaning instead of just being a physical path Routing gained a lot of popularity among developers and was easily portable to Web Forms, too, thanks to its open architecture The ASP.NET team decided to promote it as one of the core features in ASP.NET 3 .5 SP1 Today, it remains one of ASP.NET MVC’s pillars, as you’ll see the action, which are going to be executed to fulfill . feature by specifying the browser capabilities. Some new features in ASP. NET 4. 0 make this area more interesting than ever. 7.2 ASP. NET 4. 0 browser capabilities We’ve talked about ASP. NET browser. using ASP. NET Web Forms isn’t the only way to produce the UI; in part 3, we’re going to investigate the option of building your UI with ASP. NET MVC. ASP. NET MVC is a new option added in ASP. NET. you’re already acquainted with in ASP. NET Web Forms. Chapter 9 covers customizing and extending ASP. NET MVC to unlock its full potential. 187 Introducing ASP. NET MVC ASP. NET, and specifically

Ngày đăng: 12/08/2014, 15:23

Từ khóa liên quan

Mục lục

  • Part 2: ASP.NET Web Forms

    • Taking control of markup

      • 7.1 ASP.NET adaptive rendering

        • Technique 43: Build a table-less control adapter for the DataList

          • 7.1.1 Mobile controls and the Control Adapter Toolkit

          • 7.2 ASP.NET 4.0 browser capabilities

            • Technique 44: Building a custom browser capabilities provider

            • Technique 45: Validating ASP.NET pages with the W3C validator

            • 7.3 Summary

            • Part 3: ASP.NET MVC

              • Introducing ASP.NET MVC

                • 8.1 A new way to build web applications

                  • 8.1.1 The Model-View-Controller pattern

                  • 8.2 Your first experience with ASP.NET MVC

                    • Technique 46: The model

                    • Technique 47: The controller

                    • Technique 48: The view

                    • 8.3 Routing in ASP.NET MVC

                      • 8.3.1 Basic routing concepts in ASP.NET MVC

                        • Technique 49: Partitioning using Areas

                        • 8.4 Accepting user input

                          • Technique 50: Handling user input at the controller level

                          • Technique 51: Validating posted data

                          • 8.5 Summary

                          • Customizing and extending ASP.NET MVC

                            • 9.1 Building reusable elements in ASP.NET MVC

                              • 9.1.1 Using templates to represent data

                                • Technique 52: Building customized data templates

Tài liệu cùng người dùng

Tài liệu liên quan