Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

How To Create A Dynamic Email Signature

  a simple dynamic signature, an image that aggregates news from an RSS 2.0 (Rich Site Summary) syndication feed and auto-updates itself." After reading this article, you too will be able to build your own email signature that can be optionally used together with text. In addition, it can be used in any HTML document.
Paul-Valentin Borza

Difficulty: Easy
Time Required: 1-3 hours
Cost: Free
Software: Visual Studio Express Editions,Microsoft Office Outlook 2003
Hardware:
Download:
A short description of what follows would be "a simple dynamic signature, an image that aggregates news from an RSS 2.0 (Rich Site Summary) syndication feed and auto-updates itself."

After reading this article, you too will be able to build your own email signature that can be optionally used together with text. In addition, it can be used in any HTML document. So... do you own an email address? Probably... then you are perfect for learning how you can enrich your mailing experience.

Although something like this already exists on the market, it is interesting to build it yourself. One of the advantages is that the entire solution can be built with Microsoft Visual Studio 2005 Express Editions and Microsoft Office Outlook 2003. The sample code can be downloaded in both Visual Basic and Visual C#.

Prerequisites

Now that we have the general idea in mind, we have to start designing two simple images: one for the basic purpose, which is, displaying the latest posts; and another one in case an exception occurs. The following code sample uses the PNG (Portable Network Graphics) format. You can use any available software to design your images, as long as you are pleased with the result. I have created my own images that are 128x256 pixels:

And

The second thing that we need is an RSS Feed. For best purposes, use your own blog's RSS 2.0 Feed URL. As a sample we will use http://msdn.microsoft.com/rss.xml which is the URL for "MSDN Just Published". You can observe that I have designed the basic image such that there is enough space for drawing the title in the first half of the image, and enough space for drawing the latest three posts in the second half of the image. The exception image should be a simple one.

How to code the signature

Here, we'll be focusing on a lot of interesting features of the .NET Framework. Just to enumerate some: web requests, web handlers, graphics, caching, section handlers etc. My purpose was to create a solution that can be easily customized and extended by others.

Looking at the prerequisites

By having such a purpose, I have decided to provide most of the settings in the "web.config" file, as follows:

<configSections>
<sectionGroup name="RSSGraphics">
<section name="Channel" type="RSSBitmap.RSSGraphics.GeneralSectionHandler"
allowLocation="true" allowDefinition="Everywhere"
restartOnExternalChanges="true" />
</sectionGroup>
</configSections>

 

As you might have noticed I have created a custom section handler. The sample code includes the handler and is pretty much self explanatory, so we will not get into further details on this. However, I would like to explain the structure of the section. It contains a title and exception node that describes how to draw the title, and respectively the exception in case it occurs. It also contains an items node, which acts as a collection; it provides us the possibility to specify how to draw unlimited posts (if they exist) on the surface of the image. I have chosen to draw only the latest three. Note that the structure is similar with the RSS 2.0 standard.

<RSSGraphics>
<!-- Channel -->
<Channel>
<!-- Title -->
<title drawRectangle="5, 20, 117, 65"
drawFont="Verdana, 10.5pt"
drawColor="194, 71, 11"
drawBorder="false" />
<!-- Exception -->
<exception drawRectangle="5, 5, 118, 246"
drawFont="Verdana, 9pt"
drawColor="255, 0, 0"
drawBorder="false" />
<!-- Items -->
<items>
<clear/>
<add Name="1"
drawRectangle="5, 110, 117, 28"
drawFont="Verdana, 8pt"
drawColor="255, 55, 0"
drawBorder="false">
<pubDate MoreText="Published on: "
drawRectangle="5, 140, 117, 12"
drawFont="Verdana, 6pt"
drawColor="0, 0, 0"
drawBorder="false"/>
</add>
<add Name="2"
drawRectangle="5, 155, 117, 28"
drawFont="Verdana, 8pt"
drawColor="255, 55, 0"
drawBorder="false">
<pubDate MoreText="Published on: "
drawRectangle="5, 185, 117, 12"
drawFont="Verdana, 6pt"
drawColor="0, 0, 0"
drawBorder="false"/>
</add>
<add Name="3"
drawRectangle="5, 200, 117, 28"
drawFont="Verdana, 8pt"
drawColor="255, 55, 0"
drawBorder="false">
<pubDate MoreText="Published on: "
drawRectangle="5, 230, 117, 12"
drawFont="Verdana, 6pt"
drawColor="0, 0, 0"
drawBorder="false"/>
</add>
<!--<remove Name="2"/>-->
</items>
</Channel>
</RSSGraphics>

 The RSS Feed URL can also be easily modified by the following lines of code:

 <appSettings>
<clear/>
<add key="RSSFeedURL" value="http://msdn.microsoft.com/rss.xml"/>
</appSettings>
The basic and exception images are provided as resources in "WebResources.resx" and are linked at compile time. 
Coding the task

By collecting all these prerequisites, we now have everything we need to get started. We begin by creating a new ASP.NET Web Site. The task is to respond to a request with an image (our own dynamic image). It may seem a little odd at the first glance, but it can be achieved by using a Generic Handler. The Generic Handler is built upon a basic asynchronous handler, which is standard, and we'll be focusing only on the asynchronous task.

The following code represents the header of the asynchronous procedure and the declarations within, which are going to be used throughout the procedure.

Visual C#   

    HttpRequest objRequest = MyContext.Request;
HttpResponse objResponse = MyContext.Response;
Cache objCache = MyContext.Cache;
NameValueCollection objAppSettings = null;
GeneralSectionHandler objConfig = null;

Bitmap objImage = null;
objResponse.ContentType = "image/png";
objResponse.Clear();

Visual Basic

    Private Sub StartAsyncTask(ByVal workItemState As [Object])
Dim objRequest As HttpRequest = MyContext.Request
Dim objResponse As HttpResponse = MyContext.Response
Dim objCache As Cache = MyContext.Cache
Dim objAppSettings As NameValueCollection = Nothing
Dim objConfig As RSSGraphics.GeneralSectionHandler = Nothing
Dim objImage As Bitmap = Nothing
objResponse.ContentType = "image/png"
objResponse.Clear()

The featured line requires attention in the sense that it specifies the type of response, which is an image in PNG format.

Visual C#

try
{
if (objCache["BitmapCache"] == null)
{

Visual Basic   

Try
If objCache.Item("BitmapCache") Is Nothing Then

In order to serve many simultaneous requests, I have used the cache to insert and retrieve the image, which I must say it increases the performance quite a bit. In the case that the image is not found in the cache, or it may have expired, a new request to the RSS Feed URL is made, and the xml document is loaded. Next, the basic image is loaded from the resources, and drawn on the surface of it using smooth anti-alias (just to get a nice looking response). At the end, the image is saved into the cache in order to be retrieved from it by the next request, if it happens within 15 minutes.

Visual C#  

	   objAppSettings = 
System.Web.Configuration.
WebConfigurationManager.AppSettings;
objConfig =
(GeneralSectionHandler)System.Configuration.
ConfigurationManager.GetSection("RSSGraphics/Channel");

string RSSFeedURL = objAppSettings["RSSFeedURL"];

HttpWebRequest rssFeed =
(HttpWebRequest)WebRequest.Create(RSSFeedURL);
XmlDocument rssDocument = new XmlDocument();
rssDocument.Load(rssFeed.GetResponse().GetResponseStream());

objImage = Resources.WebResources.RSS_Basic;
Graphics objGraphics = Graphics.FromImage(objImage);
objGraphics.SmoothingMode = SmoothingMode.AntiAlias;
objGraphics.TextRenderingHint =
System.Drawing.Text.TextRenderingHint.AntiAlias;

DrawChannel(rssDocument, objGraphics, objConfig);
DrawItems(rssDocument, objGraphics, objConfig);
objGraphics.Dispose();

//Insert bitmap in cache for 15 minutes
objCache.Insert("BitmapCache", objImage,
null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 15, 0));
}
else
{
//Retrieve bitmap from cache
objImage = (Bitmap)objCache["BitmapCache"];
}
}
catch (Exception ex)
{

Visual Basic           

	    objAppSettings = Web.Configuration.WebConfigurationManager.AppSettings
objConfig = System.Configuration.ConfigurationManager.GetSection("RSSGraphics/Channel")
Dim RSSFeedURL As String = objAppSettings.Item("RSSFeedURL")
Dim rssFeed As HttpWebRequest = DirectCast(WebRequest.Create(RSSFeedURL), HttpWebRequest)
Dim rssDocument As XmlDocument = New XmlDocument
rssDocument.Load(rssFeed.GetResponse.GetResponseStream())
objImage = CType(Resources.WebResources.RSS_Basic, Bitmap)
Dim objGraphics As Graphics = Graphics.FromImage(objImage)
With objGraphics
.SmoothingMode = SmoothingMode.AntiAlias
.TextRenderingHint = Text.TextRenderingHint.AntiAlias
End With
DrawChannel(rssDocument, objGraphics, objConfig)
DrawItems(rssDocument, objGraphics, objConfig)
objGraphics.Dispose()
'Insert bitmap in cache for 15 minutes
objCache.Insert("BitmapCache", objImage, Nothing, NoAbsoluteExpiration, New TimeSpan(0, 15, 0))
Else
'Retrieve bitmap from cache
objImage = CType(objCache.Item("BitmapCache"), Bitmap)
End If
Catch ex As Exception 'Exception

If an exception occurs, an image containing details about the exception is returned. The code that caches the exception is simple and similar.

Visual C#       

	objImage = Resources.WebResources.RSS_Exception;
Graphics objGraphics = Graphics.FromImage(objImage);
objGraphics.SmoothingMode = SmoothingMode.AntiAlias;
objGraphics.TextRenderingHint =
System.Drawing.Text.TextRenderingHint.AntiAlias;
DrawException(ex, objGraphics, objRequest, objConfig);
if (objGraphics != null)
{
objGraphics.Dispose();
}

}

Visual Basic       

	objImage = CType(Resources.WebResources.RSS_Exception, Bitmap)
Dim objGraphics As Graphics = Graphics.FromImage(objImage)
With objGraphics
.SmoothingMode = SmoothingMode.AntiAlias
.TextRenderingHint = Text.TextRenderingHint.AntiAlias
End With
DrawException(ex, objGraphics, objRequest, objConfig)
If Not objGraphics Is Nothing Then objGraphics.Dispose()
End Try

At this moment, no matter what, we have a response. All that is left to do is return it by writing the contents of the bitmap to a stream, in PNG format. Because PNG format cannot be written to a non-seekable stream, an intermediate memory stream object (which is seekable) is used.

Visual C#   

    MemoryStream objMemoryStream = new MemoryStream();
objImage.Save(objMemoryStream, ImageFormat.Png);
objMemoryStream.WriteTo(objResponse.OutputStream);
objMemoryStream.Dispose();
objResponse.Flush();
MyCompleted = true;
MyCallback(this);

Visual Basic   

    Dim objMemoryStream As MemoryStream = New MemoryStream
objImage.Save(objMemoryStream, ImageFormat.Png)
objMemoryStream.WriteTo(objResponse.OutputStream)
objMemoryStream.Dispose()
objResponse.Flush()
MyCompleted = True
MyCallback(Me)
End Sub 'StartAsyncTask
Drawing the task

Now we'll start painting using brushes, and we'll not get dirty; we are going to achieve this by code. Basically we have three procedures that are going to handle this task: one that is going to draw the exception details on the exception image; and two procedures that are going to draw the title and the latest posts on the basic image.

The first procedure is the one that draws the exception. Due to security issues, the exception message is drawn only if the request is made from the same computer where the solution resides; else a friendly message is displayed. A lot of conversions are made here from string to rectangle, font, color, etc. Be sure to enter them correctly in the "web.config", or else an exception is raised.

Visual C#

private void DrawException(Exception ex, Graphics drawGraphics, 
HttpRequest objRequest, GeneralSectionHandler objConfig)
{
try
{
string drawString = "Exception: ";

if (objRequest.IsLocal)
{
drawString += ex.Message;
}
else
{
drawString += "We are unable to serve your request.";
}

//Rectangle
RectangleConverter drawRectangleConverter =
new RectangleConverter();
Rectangle drawRectangle = new Rectangle();
drawRectangle =
(Rectangle)drawRectangleConverter.ConvertFrom(
objConfig.Exception.drawRectangle);

//Font
FontConverter drawFontConverter = new FontConverter();
Font drawFont;
drawFont =
(Font)drawFontConverter.ConvertFromString(
objConfig.Exception.drawFont);

//Brush
ColorConverter drawColorConverter = new ColorConverter();
Color drawColor = new Color();
drawColor =
(Color)drawColorConverter.ConvertFrom(
objConfig.Exception.drawColor);
SolidBrush drawBrush = new SolidBrush(drawColor);

//String format
StringFormat drawStringFormat = new StringFormat();
drawStringFormat.Alignment = StringAlignment.Near;
drawStringFormat.LineAlignment = StringAlignment.Center;
drawStringFormat.Trimming = StringTrimming.EllipsisWord;

//Border
if (Convert.ToBoolean(objConfig.Exception.drawBorder))
{
drawGraphics.DrawRectangle(Pens.Black, drawRectangle);
}
drawGraphics.DrawString(
drawString, drawFont, drawBrush,
drawRectangle, drawStringFormat);
}
catch
{
drawGraphics = null;
}
}

Visual Basic

Private Sub DrawException(ByVal ex As Exception, ByRef drawGraphics As Graphics,_
ByVal objRequest As HttpRequest, _
ByVal objConfig As RSSGraphics.GeneralSectionHandler)
Try
Dim drawString As String = "Exception: "
If objRequest.IsLocal Then
drawString += ex.Message.ToString
Else
drawString += "We are unable to serve your request."
End If
With objConfig.Exception
'Rectangle
Dim drawRectangleConverter As New RectangleConverter
Dim drawRectangle As New Rectangle
drawRectangle = drawRectangleConverter.ConvertFrom(.drawRectangle)
'Font
Dim drawFontConverter As New FontConverter
Dim drawFont As Font
drawFont = drawFontConverter.ConvertFromString(.drawFont)
'Brush
Dim drawColorConverter As New ColorConverter
Dim drawColor As New Color
drawColor = drawColorConverter.ConvertFrom(.drawColor)
Dim drawBrush As New SolidBrush(drawColor)
'String format
Dim drawStringFormat As StringFormat = New StringFormat()
With drawStringFormat
.Alignment = StringAlignment.Near
.LineAlignment = StringAlignment.Center
.Trimming = StringTrimming.EllipsisWord
End With
'Border
If CType(.drawBorder, Boolean) Then _
drawGraphics.DrawRectangle(Pens.Black, drawRectangle)
drawGraphics.DrawString(drawString, drawFont, drawBrush,
drawRectangle, drawStringFormat)
End With
Catch ex2 As Exception
drawGraphics = Nothing
End Try
End Sub

The second procedure is the one that draws the channel title, which is read from the XML document and then painted inside the rectangle with the specified font and color; simple and can be easily understood. In the case that the text will not fit in the given rectangle, a text trimming will occur. The rectangle border is drawn only if required attribute is set to true. Also, a lot of conversions are made, as in the previous sample, so be sure to enter them correctly.

Visual C#

private void DrawChannel(XmlDocument rssDocument, 
Graphics drawGraphics, GeneralSectionHandler objConfig)
{
XmlNode rssChannel =
rssDocument.SelectSingleNode("rss/channel");
string drawString = rssChannel["title"].InnerText;

//Rectangle
RectangleConverter drawRectangleConverter =
new RectangleConverter();
Rectangle drawRectangle = new Rectangle();
drawRectangle =
(Rectangle)drawRectangleConverter.ConvertFrom(
objConfig.Title.drawRectangle);

//Font
FontConverter drawFontConverter = new FontConverter();
Font drawFont;
drawFont =
(Font)drawFontConverter.ConvertFromString(
objConfig.Title.drawFont);

//Brush
ColorConverter drawColorConverter = new ColorConverter();
Color drawColor = new Color();
drawColor =
(Color)drawColorConverter.ConvertFrom(
objConfig.Title.drawColor);
SolidBrush drawBrush = new SolidBrush(drawColor);

//String format
StringFormat drawStringFormat = new StringFormat();
drawStringFormat.Alignment = StringAlignment.Near;
drawStringFormat.LineAlignment = StringAlignment.Center;
drawStringFormat.Trimming = StringTrimming.EllipsisWord;

//Border
if (Convert.ToBoolean(objConfig.Title.drawBorder))
{
drawGraphics.DrawRectangle(Pens.Black, drawRectangle);
}

drawGraphics.DrawString(
drawString, drawFont, drawBrush,
drawRectangle, drawStringFormat);
}

Visual Basic

Private Sub DrawChannel(ByVal rssDocument As XmlDocument,_ 
ByRef drawGraphics As Graphics,_
ByVal objConfig As RSSGraphics.GeneralSectionHandler)
Dim rssChannel As XmlNode = rssDocument.SelectSingleNode("rss/channel")
Dim drawString As String = rssChannel.Item("title").InnerText
With objConfig.Title
'Rectangle
Dim drawRectangleConverter As New RectangleConverter
Dim drawRectangle As New Rectangle
drawRectangle = drawRectangleConverter.ConvertFrom(.drawRectangle)
'Font
Dim drawFontConverter As New FontConverter
Dim drawFont As Font
drawFont = drawFontConverter.ConvertFromString(.drawFont)
'Brush
Dim drawColorConverter As New ColorConverter
Dim drawColor As New Color
drawColor = drawColorConverter.ConvertFrom(.drawColor)
Dim drawBrush As New SolidBrush(drawColor)
'String format
Dim drawStringFormat As StringFormat = New StringFormat()
With drawStringFormat
.Alignment = StringAlignment.Near
.LineAlignment = StringAlignment.Center
.Trimming = StringTrimming.EllipsisWord
End With
'Border
If CType(.drawBorder, Boolean) Then _
drawGraphics.DrawRectangle(Pens.Black, drawRectangle)
drawGraphics.DrawString(drawString, drawFont, drawBrush,_
drawRectangle, drawStringFormat)
    End With
End Sub


The third procedure is the one that draws the items. The drawing procedures are very similar, but in addition to the previous sample, I have used two enumerators, one containing items from the xml document and one containing the graphic description on how to draw them. In the case one gets to the end, then both of them will stop. The code draws only the title and the publication date of a post, but can be easily extended to also draw other properties of a post.

Visual C#

private void DrawItems(XmlDocument rssDocument, 
Graphics drawGraphics, GeneralSectionHandler objConfig)
{
XmlNodeList rssItems =
rssDocument.SelectNodes("rss/channel/item");
IEnumerator rssItemsEnum = rssItems.GetEnumerator();

ItemsConfigElemColl rssGraphicItems = objConfig.Items;
IEnumerator rssGraphicItemsEnum =
rssGraphicItems.GetEnumerator();

while ((rssItemsEnum.MoveNext()) &&
(rssGraphicItemsEnum.MoveNext()))
{
XmlNode rssItem = (XmlNode)rssItemsEnum.Current;

string drawString =
rssItem.SelectSingleNode("title").InnerText;
DateTime drawDate =
DateTime.Parse(rssItem.SelectSingleNode(
"pubDate").InnerText);

ItemConfigElem cItem =
(ItemConfigElem)rssGraphicItemsEnum.Current;
//Rectangle
RectangleConverter drawRectangleConverter =
new RectangleConverter();
Rectangle drawRectangle = new Rectangle();
drawRectangle =
(Rectangle)drawRectangleConverter.ConvertFrom(
cItem.drawRectangle);

Rectangle drawRectangle2 = new Rectangle();
drawRectangle2 =
(Rectangle)drawRectangleConverter.ConvertFrom(
cItem.pubDate.drawRectangle);

//Font
FontConverter drawFontConverter = new FontConverter();
Font drawFont;
drawFont =
(Font)drawFontConverter.ConvertFromString(cItem.drawFont);

Font drawFont2;
drawFont2 =
(Font)drawFontConverter.ConvertFromString(
cItem.pubDate.drawFont);

//Brush
ColorConverter drawColorConverter = new ColorConverter();
Color drawColor = new Color();
drawColor =
(Color)drawColorConverter.ConvertFrom(cItem.drawColor);
SolidBrush drawBrush = new SolidBrush(drawColor);

Color drawColor2 = new Color();
drawColor2 =
(Color)drawColorConverter.ConvertFrom(
cItem.pubDate.drawColor);
SolidBrush drawBrush2 = new SolidBrush(drawColor2);

//String format
StringFormat drawStringFormat = new StringFormat();
drawStringFormat.Alignment = StringAlignment.Near;
drawStringFormat.LineAlignment = StringAlignment.Center;
drawStringFormat.Trimming = StringTrimming.EllipsisWord;

//Border
if (Convert.ToBoolean(cItem.drawBorder))
{
drawGraphics.DrawRectangle(Pens.Black, drawRectangle);
}
if (Convert.ToBoolean(cItem.pubDate.drawBorder))
{
drawGraphics.DrawRectangle(Pens.Black, drawRectangle2);
}

drawGraphics.DrawString(
drawString, drawFont, drawBrush,
drawRectangle, drawStringFormat);
drawGraphics.DrawString(
cItem.pubDate.MoreText + drawDate.Date.ToString(),
drawFont2, drawBrush2, drawRectangle2, drawStringFormat);
}
}

Visual Basic

Private Sub DrawItems(ByVal rssDocument As XmlDocument,_
ByRef drawGraphics As Graphics,_
ByVal objConfig As RSSGraphics.GeneralSectionHandler)
Dim rssItems As XmlNodeList = rssDocument.SelectNodes("rss/channel/item")
Dim rssItemsEnum As IEnumerator = rssItems.GetEnumerator()
Dim rssGraphicItems As RSSGraphics.ItemsConfigElemColl = objConfig.Items
Dim rssGraphicItemsEnum As IEnumerator = rssGraphicItems.GetEnumerator
While rssItemsEnum.MoveNext And rssGraphicItemsEnum.MoveNext
Dim rssItem As XmlNode = CType(rssItemsEnum.Current, XmlNode)
Dim drawString As String = rssItem.SelectSingleNode("title").InnerText
Dim drawDate As DateTime = CType(rssItem.SelectSingleNode("pubDate").InnerText,_
DateTime)
Dim cItem As RSSGraphics.ItemConfigElem = rssGraphicItemsEnum.Current
With cItem
'Rectangle
Dim drawRectangleConverter As New RectangleConverter
Dim drawRectangle As New Rectangle
drawRectangle = drawRectangleConverter.ConvertFrom(.drawRectangle)
Dim drawRectangle2 As New Rectangle
drawRectangle2 = drawRectangleConverter.ConvertFrom(.pubDate.drawRectangle)
'Font
Dim drawFontConverter As New FontConverter
Dim drawFont As Font
drawFont = drawFontConverter.ConvertFromString(.drawFont)
Dim drawFont2 As Font
drawFont2 = drawFontConverter.ConvertFromString(.pubDate.drawFont)
'Brush
Dim drawColorConverter As New ColorConverter
Dim drawColor As New Color
drawColor = drawColorConverter.ConvertFrom(.drawColor)
Dim drawBrush As New SolidBrush(drawColor)
Dim drawColor2 As New Color
drawColor2 = drawColorConverter.ConvertFrom(.pubDate.drawColor)
Dim drawBrush2 As New SolidBrush(drawColor2)
'String format
Dim drawStringFormat As StringFormat = New StringFormat()
With drawStringFormat
.Alignment = StringAlignment.Near
.LineAlignment = StringAlignment.Center
.Trimming = StringTrimming.EllipsisWord
End With
'Border
If CType(.drawBorder, Boolean) Then_
drawGraphics.DrawRectangle(Pens.Black, drawRectangle)
If CType(.pubDate.drawBorder, Boolean) Then_
drawGraphics.DrawRectangle(Pens.Black, drawRectangle2)
drawGraphics.DrawString(drawString, drawFont, drawBrush,_
drawRectangle, drawStringFormat)
drawGraphics.DrawString(CType(.pubDate.MoreText, String) & drawDate.Date,_
drawFont2,drawBrush2, drawRectangle2, drawStringFormat)

        End With
End While
End Sub


Tips and Tricks

At this point, I wanted to emphasize that it is not easy to position the rectangles where the text is drawn, especially if you have created your own image. So, we are going to use "drawBorder", which is a Boolean property, and I'm going to set it to true in all nodes, to get the following:

Note that the above image is not updated; it is taken from an RSS Feed a few days ago.

Another thing that you should take care is to try to see what happens if an exception occurs. Running the solution from another computer (not from the local computer) you should get:

Result

Congratulations! If you have followed the steps closely, you should be able to have something like:

We now have a dynamic image, but there are still some steps that have to be completed to get a dynamic email signature, that will be ready for use.

How to use the signature

In order to use the solution as an email signature, the following steps must be done:

  • Step 1
    • Launch Microsoft Office Outlook. Go to "Tools" > "Options" > "Mail Format".
  • Step 2
    • Click on "Signatures". Create a new signature by clicking on "New…" and rename it to "RSS Bitmap Signature". Click on "Next". Click on "Advanced Edit…".
    • Microsoft Office Word will be launched. Type your name or text signature here, for example: "Best, MSDN Just Published".
    • Go to "View" > "HTML Source". Microsoft Script Editor will be launched. Navigate to find your typed text, and insert the following code next to it:
      <a href="http://msdn.microsoft.com" target="_blank"><img style="border: 0px" src="http://localhost/RSSBitmap_VB/LatestNewsAsync.ashx" alt="MSDN Just Published" /></a>

    Note that the above code uses the local IIS, I recommend publishing the solution to a web domain.

    • Go to "File" > "Save". Close Microsoft Script Editor.
    • Go to "File" > "Save". Close Microsoft Office Word.
    • Return in the "Create signature" window, and click "Ok".
    • Be sure to select the proper signature for your email account (new messages, replies and forwards).
  • Step 3 (optional)
    • As default, Microsoft Office Outlook, when an HTML message contains pictures located on the Internet, sends a copy of the picture, instead of the reference to their location. However, this can be changed.
    • You should now be in the "Options" window on the "Mail Format" tab. Click on "Internet Format…" and uncheck the check box from "HTML Options".
Consequences

The signature can be static or referenced. What do I mean by these? Depending on what you decided to do on step 3, here are the consequences. If you have not completed the last step, the inserted image from the signature will display only the latest posts published in the moment you have sent the email (the signature will never update itself again). If you have completed the last step, the image is not inserted in the email, only its reference. So, the image will always display the latest posts. However, Outlook prevents downloading of such images and displays the following message: "Click here to download pictures. To help protect your privacy, Outlook prevented automatic download of some pictures in this message."

Taking into consideration that a user reads an email a few times, and reads it during a short period of time (let's say days), you should probably adopt the first (static) solution. It's up to you.

Conclusion

You should now be able to send emails having a dynamic signature. You can now drop me an email to show me how you further innovated and extended the solution at: valentin.borza@studentconsultant.org.

To me, it was an interesting and fun way of creating something useful that everybody can use from now on. Thanks to the Microsoft Academic Program Team Romania for support.

Follow the Discussion

  • the spark and the pioneerthe spark and the pioneer

    The Coding4Fun Web Site has been redesigned and reorganized. For you! From what I have seen so...

  • NicholasNicholas

    Is there any way to make this work with Outlook 2007 since they appear to have removed HTML signatures?

  • Pavan KumarPavan Kumar

    Its really a very good tutorial... Nice one... Thanks author...

  • aaronaaron

    I agree, if there are any ways to do this within Outlook 2007 without simply editing the signature file in a text editor I would also like to know.

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.