<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Web</title>
        <link>http://geekswithblogs.net/robp/category/6420.aspx</link>
        <description>That which deals with ASP.NET, Web, AJAX, or some other 'Net-related development technology</description>
        <language>en-US</language>
        <copyright>Robert Paveza</copyright>
        <managingEditor>robp@terralever.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>Outlook 2007 and the Battle for Backgrounds, Part 1</title>
            <link>http://geekswithblogs.net/robp/archive/2007/03/22/109538.aspx</link>
            <description>&lt;p&gt;&lt;font face="Tahoma"&gt;As a web marketing firm, my company manages to generate quite a bit of e-mail for our clients (all opt-in, of course), and one of the ways that we do that is by templating out the entire HTML e-mail into a user control.&amp;nbsp; The nice advantage to this is, of course, that we're able to pull in whatever kind of data we need and basically treat the e-mail like a page.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Tahoma"&gt;Our production team can generate some really great artwork and layout, and up until this point it's worked great.&amp;nbsp; They've been doing extensive testing to make sure that our generated e-mails work in Outlook/Outlook Express/Thunderbird/Gmail/Hotmail/etc., and generally things have worked great.&amp;nbsp; It wasn't until we started using Outlook 2007 that things were mucked up.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Tahoma"&gt;For those who don't know, Outlook 2007 no longer uses the Internet Explorer HTML rendering engine, which is probably a positive thing from a security standpoint.&amp;nbsp; It uses the Word 2007 rendering engine, which &lt;a href="http://msdn2.microsoft.com/en-us/library/aa338201.aspx"&gt;severely cuts back its HTML and CSS rendering capabilities&lt;/a&gt;.&amp;nbsp; Among the problematic rendering logic is Outlook's inability to render background images, something that has been crucial to our placing of dynamically-generated text into e-mails (for instance, a "Send to Friend" feature might include a note to the recipient).&amp;nbsp; Static text would be no problem - our graphic artists would simply include the copy in the final image.&amp;nbsp; But for dynamic text, we were left with a question of functionality - do we simply not include dynamic text, or do we put it over a solid background?&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Tahoma"&gt;Dynamically generating images with ASP.NET has been common since it was first released, and for a short time (through Beta 1), ASP.NET 2.0 was going to handle it natively with a new file type, *.asix (it was removed due to architectural difficulties).&amp;nbsp; Especially for low-volume e-mails (such as one that wasn't likely to generate tens of thousands of simultaneous hits to the web server), this seemed like an elegant solution, and it would work in all e-mail clients equally-well.&amp;nbsp; The only real question was how to get the data to the server efficiently.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Tahoma"&gt;I opted out of storing the text in the database in this instance because, well, the dynamic text was an afterthought and I didn't really want to go back and modify the db schema (nor did I think that the text was worth storing).&amp;nbsp; Rather, I came up with a slightly roundabout way of having the client specify the message itself: since dynamic images are generally .aspx pages that send image data over the wire instead of markup, I simply include a query string as part of the image's URL (if we want to be even more creative and SEO-compliant, we can use PathInfo instead of QueryString).&amp;nbsp; The last question is how to get such data to the image without it looking funny (for instance, by having %20 encoded for spaces), and that is answered with &lt;a href="http://en.wikipedia.org/wiki/Base64"&gt;Base64&lt;/a&gt; encoding.&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Tahoma"&gt;Base64 encoding uses six bits to represent byte values, and so for every three bytes there are four Base64 characters.&amp;nbsp; Base64 is never garbled by browsers because it uses the 26 uppercase and lowercase characters and two standard characters + and / (note that if we used PathInfo instead of QueryString, we should replace the / character with something else such as - or _ so that we don't run into our web application believing we're running another page, in the event we're using PathInfo for URL rewriting techniques).&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font face="Tahoma"&gt;I've created a new control that can be used in our e-mail templates.&amp;nbsp; It's entirely code, and very brief:&lt;/font&gt;&lt;/p&gt;&lt;pre&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; DynamicTextImage : System.Web.UI.WebControls.Image
    {
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; m_msg;
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Message
        {
            &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;
            {
                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; m_msg;
            }
            &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;
            {
                m_msg = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;;
            }
        }
 
        &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnPreRender(EventArgs e)
        {
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Message != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Message.Length &amp;gt; 0)
            {
                &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[] msgBytes = Encoding.ASCII.GetBytes(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Message);
                &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; message64 = Convert.ToBase64String(msgBytes);
                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ImageUrl = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format("&lt;span style="color: #8b0000"&gt;{0}?t={1}&lt;/span&gt;", &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.ImageUrl, message64);
            }
 
            &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.OnPreRender(e);
        }
    }&lt;/pre&gt;
&lt;p&gt;&lt;font face="Tahoma"&gt;This allows the image to be inserted in the same way a standard &lt;font face="Courier New" size="2"&gt;&amp;lt;asp:Image&amp;gt;&lt;/font&gt; control is, with no additional markup required by our production team and very little code by the developer working on it (&lt;font face="Courier New" size="2"&gt;&lt;font color="#0000ff"&gt;this&lt;/font&gt;.dynamicImage1.Message = &lt;font color="#0000ff"&gt;this&lt;/font&gt;.txtMessage.Text;&lt;/font&gt;).&amp;nbsp; &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Tahoma"&gt;Part 2 of this article will discuss the code behind generating the dynamic image and sending it to the viewer.&amp;nbsp; I'm sure for those of you who have used dynamic images in the past, the wheels are already spinning as to how you can adapt this to be effective at your organization.&amp;nbsp; &lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=109538"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=109538" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/robp/aggbug/109538.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Robert Paveza</dc:creator>
            <guid>http://geekswithblogs.net/robp/archive/2007/03/22/109538.aspx</guid>
            <pubDate>Thu, 22 Mar 2007 19:51:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/robp/comments/109538.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/robp/archive/2007/03/22/109538.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/robp/comments/commentRss/109538.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/robp/services/trackbacks/109538.aspx</trackback:ping>
        </item>
    </channel>
</rss>