the multipack presents: "wrestling with asp.net and web standards" by anthony williams
TRANSCRIPT
Image: c http://www.flickr.com/photos/kenmccown/220565863
Wrestling with ASP.NET and Web
StandardsAnthony Williams
Image: c Me
Hello!
Image: © Listers Group. Used with permission.
Work for a Car Dealer Group
Image: © Listers Group. Used with permission.
Work for a Car Dealer Group
I Work Here
Image: © http://www.bbc.co.uk/comedy/fastshow/wallpaper/images/swiss_1024.jpg
NOT a used car salesman
Image: © Microsoft
WindowsIIS
SQL ServerASP.NET
Image: c http://www.flickr.com/photos/planettelex/826864344
ASP ≠ ASP.NET
Image: c http://www.flickr.com/photos/wheatfields/515063339
Web Standards+
ASP.NET
Image: c http://www.flickr.com/photos/paix_et_amour/2398468615
Before we start...
Image: c http://www.flickr.com/photos/paix_et_amour/2398468615
★ .NET 3.5★ C#★ XHTML 1.0 Transitional
1
Image: c http://www.flickr.com/photos/z287marc/3189567558
Out of the box
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "‐//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1‐transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title></title></head><body> <form id="form1" runat="server"> <div> </div> </form></body></html>
<!DOCTYPE html PUBLIC "‐//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1‐transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>
</title></head><body> <form name="form1" method="post" action="Default.aspx" id="form1"><div><input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE2MTY2ODcyMjlkZCHkJbOA8HXUlbSk8AyRMGmtOpja" /></div> <div> </div> </form></body></html>
<!DOCTYPE html PUBLIC "‐//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1‐transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>
</title></head><body> <form name="form1" method="post" action="Default.aspx" id="form1"><div><input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE2MTY2ODcyMjlkZCHkJbOA8HXUlbSk8AyRMGmtOpja" /></div> <div> </div> </form></body></html>
Image: c http://www.flickr.com/photos/mikahiironniemi/76988191
XHTML Conformance
<system.web> <XhtmlConformance mode="Transitional" /></system.web>
<system.web> <XhtmlConformance mode="Strict" /></system.web>
mode="Strict"
<system.web> <XhtmlConformance mode="Strict" /></system.web>
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "‐//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1‐strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title></title></head><body> <form id="form1" runat="server"> <div> </div> </form></body></html>
<!DOCTYPE html PUBLIC "‐//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1‐transitional.dtd">
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "‐//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1‐strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head runat="server"> <title></title></head><body> <form id="form1" runat="server"> <div> </div> </form></body></html>
<!DOCTYPE html PUBLIC "‐//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1‐strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>
</title></head><body> <form name="form1" method="post" action="Default.aspx" id="form1"><div><input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE2MTY2ODcyMjlkZCHkJbOA8HXUlbSk8AyRMGmtOpja" /></div> <div> </div> </form></body></html>
<!DOCTYPE html PUBLIC "‐//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1‐strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>
</title></head><body> <form name="form1" method="post" action="Default.aspx" id="form1"><div><input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE2MTY2ODcyMjlkZCHkJbOA8HXUlbSk8AyRMGmtOpja" /></div> <div> </div> </form></body></html>
Won’t Validate
<!DOCTYPE html PUBLIC "‐//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1‐strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>
</title></head><body> <form method="post" action="Default.aspx" id="form1"><div><input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE2MTY2ODcyMjlkZCHkJbOA8HXUlbSk8AyRMGmtOpja" /></div> <div> </div> </form></body></html>
<system.web> <XhtmlConformance mode="Legacy" /></system.web>
mode="Legacy"
<system.web> <XhtmlConformance mode="Legacy" /></system.web>
2
Image: c http://www.flickr.com/photos/beatxm/2535486395
<asp:repeater />
<asp:repeater id="rptNavigationLinks" runat="server"> <headertemplate> <ul id="MainNavigation"> </headertemplate> <itemtemplate> <li <%# Eval("Link", "class=\"{0}\"") %>> <a href="<%# Eval("LinkUrl") %>"><% Eval("LinkTitle") %></a> </li> </itemtemplate> <footertemplate> </ul> </footertemplate></asp:repeater>
<ul id="MainNavigation"> <li class="Home"> <a href="/">Home</a> </li> <li> <a href="/New">New Cars</a> </li> <li> <a href="/Used">Used Cars</a> </li> <li> <a href="/Jobs">Jobs</a> </li> <li> <a href="/About">About Us</a> </li></ul>
<asp:repeater id="rptNavigationLinks" runat="server"> <headertemplate> <table id="DataTable"> <thead> <tr> <th> ... </th> <th> ... </th> </tr> </thead> <tbody> </headertemplate> <itemtemplate> <tr> <td> ... </td> <td> ... </td> </tr> </itemtemplate> <footertemplate> </tbody> </table> </footertemplate></asp:repeater>
<table id="DataTable"> <thead> <tr> <th>Letter</th> <th>Phonetic</th> </tr> </thead> <tbody> <tr> <td>A</td> <td>Alpha</td> </tr> <tr> <td>B</td> <td>Bravo</td> </tr> <tr> <td>C</td> <td>Charlie</td> </tr> </tbody></table>
3
Image: http://users.upwardaccess.com/plong/images/btvserver_treadmill.jpg
runat="server"
Image: c http://www.flickr.com/photos/antonystanley/3093398360
visible="false"
Image: c http://www.flickr.com/photos/antonystanley/3093398360
Image: c http://www.flickr.com/photos/antonystanley/3093398360
Image: c http://www.flickr.com/photos/antonystanley/3093398360
Image: c http://www.flickr.com/photos/antonystanley/3093398360
Image: c http://www.flickr.com/photos/antonystanley/3093398360
Image: c http://www.flickr.com/photos/antonystanley/3093398360
Image: c http://www.flickr.com/photos/antonystanley/3093398360
4
Image: c http://www.flickr.com/photos/wolfsoul/1368661325
Blank Alt Text
<asp:image runat="server" id="Image1" imageurl="~/accept.png" />
<img id="Image1" src="accept.png" style="border‐width:0px;" />
<img id="Image1" src="accept.png" style="border‐width:0px;" />style="border‐width:0px;"
<img id="Image1" src="accept.png" style="border‐width:0px;" />
<asp:image runat="server" id="Image1" imageurl="~/accept.png" alternatetext="" />
<img id="Image1" src="accept.png" style="border‐width:0px;" />alt="" />
<img id="Image1" src="accept.png" style="border‐width:0px;" />
<asp:image runat="server" id="Image1" imageurl="~/accept.png" alternatetext="" generateemptyalternatetext="true" />
<asp:image runat="server" id="Image1" imageurl="~/accept.png" alternatetext="" generateemptyalternatetext="true" />generateemptyalternatetext="true"
<asp:image runat="server" id="Image1" imageurl="~/accept.png" alternatetext="" generateemptyalternatetext="true" />
<img id="Image1" src="accept.png" style="border‐width:0px;" alt="" />alt="" />
<img id="Image1" src="accept.png" style="border‐width:0px;" alt="" />
<img id="Image1" src="accept.png" alt="" runat="server" />
<!‐‐ Original HTML ‐‐><img id="Image1" src="accept.png" />
<!‐‐ Original HTML ‐‐><img id="Image1" src="accept.png" />
// Add this to your code‐behind (C#)Image1.Attributes.Add("alt", "");
<!‐‐ Original HTML ‐‐><img id="Image1" src="accept.png" />
// Add this to your code‐behind (C#)Image1.Attributes.Add("alt", "");
<!‐‐ HTML after additional code‐behind ‐‐><img id="Image1" src="accept.png" alt="" />
// You’ll need .NET 3.0 (but seriously, use 3.5) for this to work, as well as needing to import// (using) the System.Linq and System.Collections.Generic namespaces in all code files that use this.
// Put the ControlHelper class somewhere in your solution ‐ not necessarily your page:public static class ControlHelper{ public static IEnumerable<Control> AllControls(this ControlCollection Controls) { foreach (Control CurrentControl in Controls) { foreach(var ChildControls in CurrentControl.Controls.AllControls()) { yield return ChildControls; } yield return CurrentControl; } }}
// Then run this code in your pages that have img elements with runat="server" attributes:IEnumerable<HtmlImage> ImageControls = Page.Controls .AllControls() .OfType<HtmlImage>() .Where(r => r.Attributes["alt"] == null);
foreach (HtmlImage ImageControl in ImageControls) ImageControl.Attributes.Add("alt", "");
5
Image: c http://www.flickr.com/photos/barnett/2836828090
Dealing with Submissions
Image: c http://www.flickr.com/photos/kristiand/3223920178
Content Editors
Sanitise user input
Image: c http://www.flickr.com/photos/herrolm/2699835587
Sanitise user input
Image: c http://www.flickr.com/photos/herrolm/2699835587
c http://xkcd.com/327/
Image: c http://www.flickr.com/photos/herrolm/2699835587
Image: c http://www.flickr.com/photos/herrolm/2699835587
Image: c http://www.flickr.com/photos/herrolm/2699835587
Exception Details: System.Web.HttpRequestValidationException
Image: c http://www.flickr.com/photos/herrolm/2699835587
!"#$%&'($)&*+,&-(.(/0(1-234&*1(3$"5!"#$%&'($)&*+,&-(.(/0(1-234&*1(3$"5
Image: c http://www.flickr.com/photos/herrolm/2699835587
!"#$%&'($)&*+,&-(.(/0(1-234&*1(3$"5!"#$%&'($)&*+,&-(.(/0(1-234&*1(3$"5
Image: c http://www.flickr.com/photos/herrolm/2699835587
!"#"$%&'(%)*
++++++!,-.%"+/-012-$%3%45%"$678-0"%7+9*
!9"#"$%&'(%)*
!"#"$%&'(%)*
++++++!,-.%"+/-012-$%3%45%"$678-0"%7+9*
!9"#"$%&'(%)*
Image: c http://www.flickr.com/photos/herrolm/2699835587
Image: c http://www.flickr.com/photos/herrolm/2699835587
Server.HtmlEncode
Image: c http://www.flickr.com/photos/herrolm/2699835587
Server.HtmlEncodeString.Replace()
Image: c http://www.flickr.com/photos/herrolm/2699835587
Server.HtmlEncodeString.Replace()
Regular Expressions
<h1>I can’t be bothered</h1><p>I’ve had enough. Balls to this.</p><p>Time to play havoc with the website:</p><style> * { display: none !important; }</style><p>Have fun!</p><script type="text/javascript"> alert("I wonder what's happened to the website? Tee‐hee.");</script>
<((script|style|iframe|object|embed)\b[^\>]*)>(.*?)\<\/\2>
<((script|style|iframe|object|embed)\b[^\>]*)>(.*?)\<\/\2>(script|style|iframe|object|embed)
// Create a string loaded with our HTMLString InputHtml = " ... ";
// Create a new regular expression, and make sure you treat the // entire input as a single line, so that you match \n in your// dot (.) matches.Regex re = new Regex( @"<((script|style|iframe|object|embed)\b[^\>]*)>(.*?)\<\/\2>", RegexOptions.Singleline);
// Create a new string which replaces any instance of ‘naughty’// code with a blank string.String OutputHtml = re.Replace(InputHtml, String.Empty);
<h1>I can’t be bothered</h1><p>I’ve had enough. Balls to this.</p><p>Time to play havoc with the website:</p>
<p>Have fun!</p>
Image: http://www.aharef.info/static/htmlgraph/?url=http://listersgroup.co.uk
Validating (X)HTML
Image: c http://www.flickr.com/photos/mattwright/237415989
Ampersands
Image: c http://www.flickr.com/photos/brullonulla/2971684462
Render it Yourself
&(?!(?:[a‐zA‐Z][a‐zA‐Z0‐9]*|#\d+);)(?!(?>(?:(?!<!\[CDATA\[|\]\]>).)*)\]\]>)
public override void Render(HtmlTextWriter writer){ using (HtmlTextWriter HtmlWriter = new HtmlTextWriter(new System.IO.StringWriter())) { base.Render(HtmlWriter); string Html = HtmlWriter.InnerWriter.ToString();
// Create the regular expression to find the un‐encoded ampersands... Regex re = new Regex( @"&(?!(?:[a‐zA‐Z][a‐zA‐Z0‐9]*|#\d+);)(?!(?>(?:(?!<!\[CDATA\[|\]\]>).)*)\]\]>)", RegexOptions.Multiline | RegexOptions.IgnoreCase );
// Use it to replace them with encoded ampersands (&) Html = re.Replace("&");
// Send the HTML to the browser HtmlWriter.Write(Html); }}
public override void Render(HtmlTextWriter writer){ using (HtmlTextWriter HtmlWriter = new HtmlTextWriter(new System.IO.StringWriter())) { base.Render(HtmlWriter); string Html = HtmlWriter.InnerWriter.ToString();
// Create the regular expression to find the un‐encoded ampersands... Regex re = new Regex( @"&(?!(?:[a‐zA‐Z][a‐zA‐Z0‐9]*|#\d+);)(?!(?>(?:(?!<!\[CDATA\[|\]\]>).)*)\]\]>)", RegexOptions.Multiline | RegexOptions.IgnoreCase );
// Use it to replace them with encoded ampersands (&) Html = re.Replace("&");
// Send the HTML to the browser HtmlWriter.Write(Html); }}
<p>Some HTML that will include some encoded ampersands & like that one, some double encoded ampersands like this one &amp; and some unencoded ampersands, like this one & and this one &. Unfortunately& this &ersand here could actually mean something else.</p>
<script type="text/javascript"> // <![CDATA[ if (a && b) doSomething("a & b & c"); // ]]></script>
<p>Some HTML that will include some encoded ampersands & like that one, some double encoded ampersands like this one &amp; and some unencoded ampersands, like this one & and this one &. Unfortunately& this &ampersand here could actually mean something else.</p>
<script type="text/javascript"> // <![CDATA[ if (a && b) doSomething("a & b & c"); // ]]></script>
public override void Render(HtmlTextWriter writer){ using (HtmlTextWriter HtmlWriter = new HtmlTextWriter(new System.IO.StringWriter())) { base.Render(HtmlWriter); string Html = HtmlWriter.InnerWriter.ToString();
// Create the regular expression to find the un‐encoded ampersands... Regex re = new Regex( @"&(?!(?:[a‐zA‐Z][a‐zA‐Z0‐9]*|#\d+);)(?!(?>(?:(?!<!\[CDATA\[|\]\]>).)*)\]\]>)", RegexOptions.Multiline | RegexOptions.IgnoreCase );
// Use it to replace them with encoded ampersands (&) Html = re.Replace("&");
// Send the HTML to the browser HtmlWriter.Write(Html); }}
public override void Render(HtmlTextWriter writer){ using (HtmlTextWriter HtmlWriter = new HtmlTextWriter(new System.IO.StringWriter())) { base.Render(HtmlWriter); string Html = HtmlWriter.InnerWriter.ToString();
// Create the regular expression to find the un‐encoded ampersands... Regex re = new Regex( @"&(?!(?:[a‐zA‐Z][a‐zA‐Z0‐9]*|#\d+);)(?!(?>(?:(?!<!\[CDATA\[|\]\]>).)*)\]\]>)", RegexOptions.Multiline | RegexOptions.IgnoreCase );
// Use it to replace them with encoded ampersands (&) Html = re.Replace("&");
// Send the HTML to the browser HtmlWriter.Write(Html); }}
Image: c http://www.flickr.com/photos/runneralan/3091055611
★ Standards out of the box★ Use the repeater control★ Use HTML controls (runat=”server”)★ Fix ASP.NET’s handling of alt=””★ Be careful with user submissions
Image: c http://www.flickr.com/photos/seandreilinger/2326448445
Questions?
Image: c http://www.flickr.com/photos/videocrab/116136642
Slides:http://slideshare.net/
abitgone
Image: c http://www.flickr.com/photos/videocrab/116136642
Videos:vimeo.com/channels/
multipackpresents