<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Software Sleuthing : Web Tools</title><link>http://blogs.msdn.com/joshpoley/archive/tags/Web+Tools/default.aspx</link><description>Tags: Web Tools</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Poor-Man’s ISAPI Filter</title><link>http://blogs.msdn.com/joshpoley/archive/2008/02/18/poor-man-s-isapi-filter.aspx</link><pubDate>Mon, 18 Feb 2008 20:39:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7777231</guid><dc:creator>joshpoley</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/joshpoley/comments/7777231.aspx</comments><wfw:commentRss>http://blogs.msdn.com/joshpoley/commentrss.aspx?PostID=7777231</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;On IIS, writing an ISAPI filter can give you flexible control over the URL path which users pass into your site. For example, normally when a user tries to hit http://server/path1/path2/filename, the virtual path must exist in some form on the server’s file system in order for the web server to resolve the page. But when using an ISAPI filter, you can remove this restriction and use the path as just another input into your application. So on the above URL, path1/path2/filename may not exist at all and are just used as a parameter to your ISAPI application to determine what content to serve back to the customer. This comes in handy when you want to provide easy to understand/remember URLs to your users but maintain the dynamic nature of handling diverse results from one application.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;The bad news is that writing and debugging a full blown ISAPI filter is often more work than is warranted for a small internal tool. The good news is that we can accomplish the same effect using old school ASP scripts and a custom 404-error page. This also works well if you are on a server or ISP which doesn't allow you to run custom ISAPI applications (but does give you control of 404 errors).&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;For the sake of an example, let’s assume that you are setting up a web site to display test results. It would be easier on the users (including non-technical managers) if the components being tested were organized in a tree structure and this was then represented back in the URL path, so a shortcut may take the form “http://server/testresults/UI/dialogFoo”. If we setup a custom 404-error page for this “testresults” site we can give the user the ability to utilize this free-form and dynamic URL.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Setting up a custom 404 error page is extremely easy, we just need to go into the site properties and under the "Custom Errors" tab we modify the 404 error to point the URL at our own ASP page ("/testresults/404.asp" in this case).&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true"&gt;&lt;IMG title="Custom Error Settings" style="WIDTH: 392px; HEIGHT: 205px" height=205 alt="Custom Error Settings" src="http://blogs.msdn.com/photos/joshpoley/images/7695325/original.aspx" width=392 mce_src="http://blogs.msdn.com/photos/joshpoley/images/7695325/original.aspx"&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Let's take a look at a simple 404.asp page which we create and add to the site:&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: #aaaaaa"&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New"&gt;&amp;lt;HTML&amp;gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New"&gt;&amp;lt;BODY&amp;gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa"&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;H1&amp;gt;&lt;/SPAN&gt;&lt;FONT color=#050505&gt;Custom 404 Page&lt;/FONT&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;/H1&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;o:p&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New"&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa"&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;FONT color=#050505&gt;=Request.ServerVariables(&lt;/FONT&gt;&lt;SPAN style="COLOR: #700000"&gt;"QUERY_STRING"&lt;/SPAN&gt;&lt;FONT color=#050505&gt;)&lt;/FONT&gt;&lt;SPAN style="COLOR: blue"&gt;%&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New"&gt;&amp;lt;/BODY&amp;gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="COLOR: blue"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa"&gt;&lt;FONT face="Courier New"&gt;&amp;lt;/HTML&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Now let us go to testresults/test.asp (which doesn't exist) in a web browser and we will get an output like this:&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND: #aaaaaa; MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-SIZE: 16pt; COLOR: #050505; FONT-FAMILY: 'Times New Roman','serif'"&gt;Custom 404 Page&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="BACKGROUND: #aaaaaa; MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="COLOR: #050505; FONT-FAMILY: 'Times New Roman','serif'"&gt;404;http://server/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #050505"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: #050505; FONT-FAMILY: 'Times New Roman','serif'"&gt;testresults/test.asp&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;You will notice that the URL which the user attempted to access is just passed in as a parameter via the query string. So now it is just a matter of parsing this value to determine what content the user is interested in so you can provide a more meaningful response.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Since we are returning valid data it would be good of us to return a successful status code back to the browser (in the response HTTP header). On the other hand, just don’t forget to provide a code path to return a real 404 error if what the user is looking for truly doesn’t exist.&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa"&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;FONT color=#050505&gt; Response.Status = "200 OK" &lt;/FONT&gt;&lt;SPAN style="COLOR: blue"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Or&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa"&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR: blue"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;FONT color=#050505&gt; Response.Status = "404 File not found" &lt;/FONT&gt;&lt;SPAN style="COLOR: blue"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;In the failure case, it would also be nice of you to provide links to possible locations based on the input URL.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt" mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7777231" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/joshpoley/archive/tags/Web+Tools/default.aspx">Web Tools</category><category domain="http://blogs.msdn.com/joshpoley/archive/tags/Poor-Man/default.aspx">Poor-Man</category></item><item><title>Serving iCalendar from ASP</title><link>http://blogs.msdn.com/joshpoley/archive/2007/12/12/serving-icalendar-from-asp.aspx</link><pubDate>Wed, 12 Dec 2007 19:19:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:6748492</guid><dc:creator>joshpoley</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/joshpoley/comments/6748492.aspx</comments><wfw:commentRss>http://blogs.msdn.com/joshpoley/commentrss.aspx?PostID=6748492</wfw:commentRss><description>&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;As a follow up to the previous post (&lt;A href="http://blogs.msdn.com/joshpoley/archive/2007/12/10/creating-calendar-items.aspx"&gt;http://blogs.msdn.com/joshpoley/archive/2007/12/10/creating-calendar-items.aspx&lt;/A&gt;), we will show how to serve up custom iCalendar files via an IIS web server.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;The first thing to do is configure IIS to associate the .ICS file extension with the ASP script engine. This will allow us to create dynamic iCalendar files using our favorite scripting language. From the "Application Configuration" page (which is accessible from the web site's properties screen: on the "Home Directory" tab click on the "Configuration…" button) we can add a new file extension and associate it with asp.dll:&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt; TEXT-ALIGN: center" align=center&gt;&lt;o:p&gt;&lt;IMG title="IIS Configuration for serving ICS files" style="WIDTH: 429px; HEIGHT: 243px" height=243 alt="IIS Configuration for serving ICS files" src="http://blogs.msdn.com/photos/joshpoley/images/6748417/original.aspx" width=429 mce_src="http://blogs.msdn.com/photos/joshpoley/images/6748417/original.aspx"&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Now, when a user attempts to load up an .ics file, asp.dll will parse it first looking for script blocks. This gives us the ability to pass in arguments (such as the time and subject) and do any other processing we need.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="FONT-FAMILY: 'Courier New'"&gt;event.ics&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR: #aaaaaa"&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa"&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;FONT color=#050505&gt;@ Language=JavaScript EnableSessionState=False&lt;/FONT&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New"&gt;&amp;lt;%&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa"&gt;&lt;FONT face="Courier New"&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;Response.ContentType&lt;/SPAN&gt;&lt;FONT color=#050505&gt; = "text/calendar";&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa"&gt;&lt;FONT face="Courier New"&gt;%&amp;gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;BEGIN:VCALENDAR&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;VERSION:2.0&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;PRODID:Serving iCalendar from ASP, Josh Poley&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;BEGIN:VEVENT&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa"&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#050505&gt;SUMMARY:&lt;/FONT&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;FONT color=#050505&gt;=&lt;/FONT&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;Request&lt;/SPAN&gt;&lt;FONT color=#050505&gt;("s")&lt;/FONT&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa"&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#050505&gt;DTSTART;TZID=US-Pacific:&lt;/FONT&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;FONT color=#050505&gt;=&lt;/FONT&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;Request&lt;/SPAN&gt;&lt;FONT color=#050505&gt;("start")&lt;/FONT&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa"&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#050505&gt;DTEND;TZID=US-Pacific:&lt;/FONT&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;&amp;lt;%&lt;/SPAN&gt;&lt;FONT color=#050505&gt;=&lt;/FONT&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;Request&lt;/SPAN&gt;&lt;FONT color=#050505&gt;("end")&lt;/FONT&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;BEGIN:VALARM&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;TRIGGER:-PT15M&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;ACTION:DISPLAY&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;END:VALARM&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;END:VEVENT&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa" face="Courier New" color=#050505&gt;END:VCALENDAR&lt;/FONT&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;In the above sample, we first set the language to JavaScript (which is just a personal preference) and then disable "session state" cookies as we don't need them. The important statement is where we set the ContentType (which is the &lt;A href="http://en.wikipedia.org/wiki/Mime_type"&gt;MIME&lt;/A&gt; specifier for the data we are creating). This helps inform the web browser how to interpret the file: we don't want the browser to just display the text; instead it should pass it off to the operating system to handle (which typically results in an "open or save" dialog popping up).&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;We then take 3 inputs and use them to generate the iCalendar properties. So with the above code, if I hit the following URL in a web browser:&lt;/P&gt;
&lt;P class=Code style="MARGIN: 0in 0in 0pt 0.5in"&gt;&lt;FONT style="BACKGROUND-COLOR: #aaaaaa"&gt;&lt;FONT face="Courier New"&gt;&lt;FONT color=#050505&gt;event.ics?&lt;/FONT&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;s=&lt;/SPAN&gt;&lt;FONT color=#050505&gt;test%20it!&amp;amp;&lt;/FONT&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;start=&lt;/SPAN&gt;&lt;FONT color=#050505&gt;20071212T140000&amp;amp;&lt;/FONT&gt;&lt;SPAN style="COLOR: blue; mso-bidi-font-size: 9.0pt"&gt;end=&lt;/SPAN&gt;&lt;FONT color=#050505&gt;20071212T150000&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;I will receive a calendar entry for 2-3pm on December 12&lt;SUP&gt;th&lt;/SUP&gt; with the subject of "test it!"&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;Since we are within a scripting environment, we can also go in and add some more interesting logic, such as providing a default end time if none is supplied (for example, one hour from the start time), or use today's date if no date information is passed in… but, I will leave that as an exercise for the reader.&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;As an aside, this same mechanism can be used to generate a varying degree of content. For example, I’ve used it to generate custom bug queries on the fly, allowing users to just click on a URL to open up a specific bug in our tracking tool (the bug’s ID is the parameter passed into the ASP processor).&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=6748492" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/joshpoley/archive/tags/Web+Tools/default.aspx">Web Tools</category></item></channel></rss>