Yesterday, I had a query from a customer willing to send events registration emails with embedded barcodes, so that the event attendees can self check-in at the event.
The whole solution finding ended opening my mind about .Net possibilities in a quite positive way, while it started rather poorly.
As we already had a custom code sending the registration emails with a confirmation PDF, I thought that was just a matter of changing the SSRS report generating the PDF so that we could use barcodes and barcodes being just fonts is should be pretty straighforward.
I downloaded a free Code39 font, installed it on the dev ssrs server,tried using it in SSRS and directly started having issues, as it was an open type font and .Net (and thus SSRS) only supports True Type fonts.
So, I got a TTF Code39 font, installed it and, hoorah, it was fine in preview. I then tried the PDF extract and all I got was garbage...
Now, I had my share of PDF rendering issues in SSRS, usually due to incompatibilities between the HTML and PDF languages, but that was the first time I saw it with fonts so I started browsing the web for similar problems and it seems SSRS 2005 (the version that the customer uses) doesn't handle very well extra fonts in PDF, and so I started playing with the idea of pushing an upgrade to SSRS2008 (not an SQL upgrade, just the SSRS part), when I spotted articles with related issues in SSRS 2008R2...
I was looking into how to generate barcodes with code when I found this marvellous article by Cody Konior which solves the problem once and for all.
The key part of the article is this piece of SSRS vb.net code whith create a bitmap image from a specific font generated string
Public Shared Function GenerateImage(ByVal fontName As String, ByVal stringText As String) As Byte()
Dim oGraphics As System.Drawing.Graphics
Dim barcodeSize As System.Drawing.SizeF
Dim ms As System.IO.MemoryStream
Using font As New System.Drawing.Font(New System.Drawing.FontFamily(fontName), 36)
Using tmpBitmap As New System.Drawing.Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
oGraphics = System.Drawing.Graphics.FromImage(tmpBitmap)
oGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel
barcodeSize = oGraphics.MeasureString(stringText, font)
Using newBitmap As New System.Drawing.Bitmap(barcodeSize.Width, barcodeSize.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
oGraphics = System.Drawing.Graphics.FromImage(newBitmap)
oGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel
Using oSolidBrushWhite As New System.Drawing.SolidBrush(System.Drawing.Color.White)
Using oSolidBrushBlack As New System.Drawing.SolidBrush(System.Drawing.Color.Black)
oGraphics.FillRectangle(oSolidBrushWhite, New System.Drawing.Rectangle(0, 0, barcodeSize.Width, barcodeSize.Height))
oGraphics.DrawString(stringText, font, oSolidBrushBlack, 0, 0)
ms = New System.IO.MemoryStream()
So by using the System.Drawing library, this seemingly complex task was reduced in a dozen lines of vb.net code.
Furthermore as the library is part of .net, the deployment of this SSRS "extension" to other environnments (ie: dev, staging, test, production) is just a matter of installing the RDL file as usual; no fancy registration, installation of whatever is needed.
Until now, I did never realized how having SSRS using the .Net stack was effectively allowing such easy extensions of daunting tasks; it opened my mind to a full range of new possibilities.
It's a bit like you always knew it was there but you have to see it to understand the full implications.
And the cherry on the cake ? This whole code was intended for SSRS 2008 but worked without a hitch in SSRS 2005 ;)
Here's a selection of current interesting news and articles:
Mitch Milam has released a free tool to extract CRM 4.0 plugins registered in the database and upgraded its CRM Migration Assistant to version 1.1
Rhett Clinto has enhanced its Metadata Browser with an export to excel function.
The CRM Software blog has an interesting article on how to include a webresource in the MSCRM form header.
Customer Effective explains how to implement a wysiwyg text editor into a crm textarea.
PowerObjects has a nice trick to use non supported filetypes in ressources (ie: flash files in that case).
Our dear friends of the EMEA support have a new blog post about a quite unknown feature of crm 2011 online, the CRM 2011 Online latency tool.
The url of the tool is https://<OrgURL>/tools/diagnostics/diag.aspx, the tool get most of the client performance measures, so it's really quite helpfull when you have a customer complaining about performance while using CRM 2011 Online.
You can read the full EMEA support post here
So what's new today ?
Brad Wilson (GM of Dynamics CRM) has written about the current SalesForce's worry about Microsoft.
Jamie Miley has a short article on entity creation via Silverlight, I will keep it in reference as I always have to remember the async call from Silverlight.
The SDK for CRM 2011 has just been updated to version 5.0.4, you can download it from here.
Version 5.0.5 is scheduled for end of July, but meanwhile here's a summary of the changes for this version.
New and updated topics
Description of changes
Updated the readme with new information.
Updated the assemblies for Microsoft Dynamics CRM Update Rollup 2. For Microsoft Dynamics CRM Online, updates are installed for you. For other deployment types, you can get update rollups from the Microsoft Download Center or from Microsoft Update.
Moved the location of the exported ribbon definitions from SDK\SampleCode\CS\Client\Ribbon\ExportRibbonXml\ExportedRibbonXml to SDK\Resources\ExportedRibbonXml.
Updated the following topics to reflect this change:
· Ribbons Available in Microsoft Dynamics CRM
· Export Ribbon Definitions
· Walkthrough: Add a Custom Button to an Existing Group for a Specific Entity
· Walkthrough: Add a Custom Group to an Existing Tab for a Specific Entity
· Walkthrough: Add a Custom Button to an Existing Group for all Entities
· Walkthrough: Hide Ribbon Elements
Added new images to this folder, which are available for use in customized applications.
Updated all three portal developer guide walkthrough solutions. For a complete list of changes, see the SDK readme file: Microsoft_Dynamics_CRM_2011_SDK_Readme.htm.
Changed the code in SystemUserProvider so that it does not attempt to create a user if the client application is connected to Microsoft Dynamics CRM Online. The changes to the SystemUserProvider class required changes to all the C# and VB samples that use that class. Only the changed C# samples are shown here for brevity. All changes are in the folders SDK\SampleCode\CS or SDK\SampleCode\VB.
Updated the SDK.MetaData.jsJScript library to address three issues:
· The DefaultFormValue property of option set attributes returned a Boolean rather than the integer value.
· The State property for StatusOptionMetadata was not returned.
· The StateOptionMetadataDefaultStatus and InvariantName properties were not returned.
Added VB.NET versions of the existing C# samples.
Updated the Metadata Browser to reflect changes to the SDK.MetaData.jsJScript library.
Active Directory and Claims-Based Authentication
Added information about the lifespan of a security token and how to refresh the token in applications that take a long time to run.
Create Custom Get Started Pane Content
Included a note that customizing the application Help content for Microsoft Dynamics CRM 2011 (On Premises) is not supported.
Create Early-Bound Entity Classes with the Code Generation Tool (CrmSvcUtil.exe)
Added a sample extension for the CrmSvcUtil program that generates early-bound types for custom entities.
CrmSvcUtil.exe Extension Usage and Command-line Parameters
Removed documentation for an invalid command-line parameter for the servicecontextprefix extension.
Customize Entity Forms in Microsoft Dynamics CRM
Added Microsoft Dynamics CRM for Microsoft Office Outlook Reading Pane section to describe how form customizations apply to the reading pane.
Privileges by Entity
Privileges by Message
Added detailed reference information for each entity and message, describing the privileges required. A small percentage of these topics are still marked as coming soon.
Quick Start: A Simple Program
Helper Code: ServerConnection Class
Added support for saving and re-using server configurations, making it easier to run the sample code repeatedly with minimal prompts.
Sample: Invoke Duplicate Detection for Creating and Updating Records
Added a new sample demonstrating how to invoke duplicate detection in create and update operations.
Sample: Instantiate an E-mail Using a Template
Added a new sample demonstrating the use of the InstantiateTemplateRequest message.
Sample: Send an E-mail
Added a new sample demonstrating the use of the SendEmailRequest message.
Sample: Use LINQ with Late Binding
Added a new sample that shows how to use LINQ with late bound entities.
Added a tip about a common exception when using the CrmSvcUtil.exe program.
Use Messages (Request and Response Classes) with the Execute Method
Pass Optional Parameters in Messages
Run Duplicate Detection
Indicated that passing the CalculateMatchCodeSynchronously optional parameter is not required any longer. The change was implemented in the Microsoft Dynamics CRM 2011 Update Rollup 1 and Microsoft Dynamics CRM Online April Service Update.
Use the REST Endpoint with Ajax and JScript Web Resources
Corrected information in the Working with Dates section and provided new information about additional tasks related to working with dates.
Write a Custom Azure-aware Plug-in
Clarified that a service endpoint ID must be passed to the plug-in at run time through