Author: Derek

  • Integrating with Amazon Simple Email Service (SES)

    Amazon recently announced the release of their Simple Email Service for use by developers.  In doing so, Amazon opens up a pay-as-you-go email sending mechanism that is tailored for application developers.

    Sending system generated email messages has always proven to be a challenge for developers.  It’s not for lack of means to do so, it’s dealing with a multitude of anti-spam safeguards imposed by ISPs and hosting providers.  Some block outbound sending altogether, and many throttle the number of messages that can be send per day/hour/minute.

    Amazon’s SES provides a great deal of infrastructure, and uses a variety of proven methods to help ensure deliverability of your message.  Their quota system is dynamic, so the more you prove your messages are legitimate, the more you can send.

    Setting up your SES account.

    If you already have an Amazon Web Services account, adding on the Simple Email Service is pretty straightforward.  You’ll get a confirmation email from Amazon to click through and activate the service.  Initially, you’ll be set up in a Sandbox, and there is a process for requesting Production Access.

    Getting your Access Keys

    After you have enabled the service, you’ll need a set of credentials to use it.  Again, if you already have an AWS account, you’ve probably got your Access Keys set up already.  Like any credentials, keep them safe and secure.  If someone were to gain access to your AWS keys, they could send email through SES without your knowledge.

    Verifying an email address.

    Before you can send outbound messages through SES, you have to verify the source email address.  Amazon provides a small collection of scripts used to communicate via command line to the SES services.  Follow the Getting Started guide’s instruction to prepare a file containing your AWS Access Keys and verify a sending address.  SES will generate a response email to the address you are verifying, within which is a link you’ll have to click in order to complete the verification.

    Downloading the Amazon Web Services API.

    Amazon offers a couple of methods for leveraging the SES API.  You can use the scripts downloaded to verify your source address to also send messages.  I chose, however, to use their packaged .NET SDK library.  It contains wrappers for all of Amazon’s Web Services, including the SES.

    After downloading and unpacking the SDK, you can add a reference to the AWSSDK.dll assembly to your project.

    Using the SES API methods.

    Creating and sending email via the SDK then becomes a matter of setting up the outbound SES message object and sending it through the API.  The following method takes a standard .NET MailMessage object and translates it to a SES message, then sends it along.

    Public Function SendMessage(ByVal message As System.Net.Mail.MailMessage) As String Implements Core.DataInterfaces.IMailServer.SendMessage
    
                If String.IsNullOrEmpty(_accessKey) Or String.IsNullOrEmpty(_secretKey) Then Throw New Exception("API Credentials are required to use this provider.")
    
                Dim ses As New AmazonSimpleEmailServiceClient(_accessKey, _secretKey)
    
                Dim messageToSend As New Amazon.SimpleEmail.Model.SendEmailRequest
    
                'set up addresses
                messageToSend.Destination = New Amazon.SimpleEmail.Model.Destination
    
                For Each toAddress In message.To
                    messageToSend.Destination.ToAddresses.Add(toAddress.Address)
                Next
    
                For Each ccAddress In message.CC
                    messageToSend.Destination.CcAddresses.Add(ccAddress.Address)
                Next
    
                For Each bcAddress In message.Bcc
                    messageToSend.Destination.BccAddresses.Add(bcAddress.Address)
                Next
    
                'set reply to
                If message.ReplyTo IsNot Nothing Then
                    messageToSend.ReplyToAddresses.Add(message.ReplyTo.Address)
                End If
    
                'set subject line
                messageToSend.Message = New Amazon.SimpleEmail.Model.Message
                messageToSend.Message.Subject = New Amazon.SimpleEmail.Model.Content().WithData(message.Subject)
    
                'set message body
                If message.AlternateViews.Count > 0 Then
                    Dim messageBody As New Amazon.SimpleEmail.Model.Body()
    
                    For Each view In message.AlternateViews
                        Dim viewStream = view.ContentStream
                        Dim viewData(viewStream.Length) As Byte
                        Dim viewContent As String = System.Text.Encoding.ASCII.GetString(viewData, 0, viewStream.Read(viewData, 0, viewData.Length))
    
                        If view.ContentType.MediaType.Equals("text/html") Then
                            messageBody.Html = New Amazon.SimpleEmail.Model.Content(viewContent)
                        Else
                            messageBody.Text = New Amazon.SimpleEmail.Model.Content(viewContent)
    
                        End If
                    Next
    
                    messageToSend.Message.Body = messageBody
                Else
                    messageToSend.Message.Body = New Amazon.SimpleEmail.Model.Body(New Amazon.SimpleEmail.Model.Content(message.Body))
                End If
    
                'set from address
                messageToSend.Source = message.From.Address.ToString
    
                'send message
                Dim sendResponse As Amazon.SimpleEmail.Model.SendEmailResponse
    
                sendResponse = ses.SendEmail(messageToSend)
    
                Return sendResponse.SendEmailResult.MessageId
    
            End Function
        End Class

    Lessons Learned

    A few things I learned to keep in mind:

    1. The reply-to address also has to be verified, just like the sending address.
    2. As a new account with Production Access, you’ll have a 1,000 message per day quota.
    3. There is a Send Rate limiter for the number of messages per second.  You’ll have to account for this limit in your code to ensure that it doesn’t fail mid-way through your batch of messages.

    Amazon’s service is easy to use, economical, and capable.  I probably won’t replace every outbound message instance with SES, but definitely for cases where I need to generate larger batches (such as monthly newletters or maintenance reminders) I will leverage SES.

  • My Favorite Extension Methods: IsGuid

    In this third installment of my Favorite Extension methods series, I will show how to quickly evaluate a string to determine if it is the string representation of a Guid.

    I came upon the need for this method because I am using ASP.NET MVC for an application that uses a Guid to identify a record. In a case where my controller method is to retrieve a record, the controller’s parameter is a string.

    <Extension()> _
    Public Function IsGuid(ByVal value as String) As Boolean
      If String.IsNullOrEmpty(value) Then
        Return False
      Else
        Try
          Dim guid As New Guid(value)
          Return True
        Catch Ex As Exception
          Return False
        End Try
    End Function

    Using this extension method, I can ensure that a string represents a Guid and I won’t encounter any errors when trying to Cast that value into a Guid.

    If Not recordGuid.IsGuid Then Throw New ArgumentException("RecordGuid must contain a Guid string.")
  • My favorite extension methods: HtmlEncode shortcut

    This is the second installment in my series highlighting my personal favorite .NET extension methods.  We’ve already talked about a String.Format shortcut.  Now we’re on to making the HtmlEncode function readily accessible.
    Any time you are showing user-entered content as text on a web page, it is important to HtmlEncode the string so as to prevent execution of any rogue scripts.  The following is a two part implementation of the .NET HtmlEncode that makes this useful function much more accessible.
    Part 1 is a wrapper around the base .NET function with an overload to pass in your own value to display if the value to encode is empty.
    Public Shared Function HtmlEncode(ByVal value As String) As String
            Dim context As HttpContext = System.Web.HttpContext.Current
            If Not context Is Nothing Then
                Dim Server As HttpServerUtility = context.Server
                If value Is Nothing OrElse Trim(value) = "" Then
                    Return "{none}"
                Else
                    Dim sText As String = Server.HtmlEncode(value)
                    Dim sCRLF As String = vbCrLf
                    sText = Replace(sText, sCRLF, "<br>")
                    Return sText
                End If
            Else
                Throw New Exception("This function must be called from an ASP.Net application.")
            End If
        End Function
    
        Public Shared Function HtmlEncode(ByVal value As String, ByVal mapEmptyTo As String) As String
            Dim context As HttpContext = System.Web.HttpContext.Current
            If Not context Is Nothing Then
                Dim Server As HttpServerUtility = context.Server
                If value Is Nothing OrElse Trim(value) = "" Then
                    Return mapEmptyTo
                Else
                    Dim sText As String = Server.HtmlEncode(value)
                    Dim sCRLF As String = vbCrLf
                    sText = Replace(sText, sCRLF, "<br>")
                    Return sText
                End If
            Else
                Throw New Exception("This function must be called from an ASP.Net application.")
            End If
        End Function
    The second part is an extension method to let you call the HtmlEncode function from any string, again with an overload to let you pass in your own empty value text.
       <Extension()> _
       Public Function HtmlEncode(ByVal value As String) As String
           Return Functions.HtmlEncode(value, "{none}")
       End Function
       <Extension()> _
       Public Function HtmlEncode(ByVal value As String, ByVal mapEmptyTo As String) As String
           Return Functions.HtmlEncode(value, mapEmptyTo)
       End Function
  • My favorite Extension methods: String.Format shortcut

    This is the first entry in a short series highlighting some of my favorite extension methods.

    It’s a generally accepted best practice to use the String.Format() method to assemble string values that merge text and variables.

    Using an Extension Method (.NET 3.5 or greater) makes accessing the String.Format function even easier.

    Now, for any string value, you can simply use the following

    "The quick brown fox {0}".Fmt("jumped over the lazy dog.")

    Here’s the code for the extension method and various overloads:

    <Extension()>_
    Public Function Fmt(ByVal format As String, ByVal arg0 As Object) As String
      Return String.Format(format, arg0)
    End Function
    
    <Extension()>_
    Public Function Fmt(ByVal format As String, ByVal arg0 As Object, ByVal arg1 As Object) As String
      Return String.Format(format, arg0, arg1)
    End Function
    
    <Extension()>_
    Public Function Fmt(ByVal format As String, ByVal arg0 As Object, ByVal arg1 As Object, ByVal arg2 As Object) As String
      Return String.Format(format, arg0, arg1, arg2)
    End Function
    
    <Extension()>_
    Public Function Fmt(ByVal format As String, ByVal ParamArray args() As Object) As String
      Return String.Format(format, args)
    End Function
  • Career Retrospective 2010

    One of the tenants of the Agile methodology for software development is the Retrospective.  Essentially, the Retrospective is a time when a team can look back on the last body of effort, and ask themselves the some variant of the following three questions:

    • What did we do well?
    • What did we do not so well?
    • What can we do to improve?

    I must give some credit to Ben Griswald at JohnnyCoder.com for the idea, but it seemed quite relevant at the end of the year to apply the principle of Retrospective to my career as a software developer.  Moving forward, I will try to post a Career Retrospective on at least a quarterly basis.

    What did I do well in 2010?

    My first instinctive response was simply “I stayed employed.”  I don’t mean to suggest that I have a hard time holding down a job, but more so acknowledge that in the current economic state of our country, there are a lot of software developers who do not have jobs.

    Further, in 2010, I got a new job, which means at the very least that I successfully stood out from other candidates in the eyes of my new employer.

    I started this blog. As I mentioned in my inaugural post, my hope is that this venue will let me talk about the craft of software development and the things that are important to me in that space.

    I launched a new product. The second iteration in the HomeSpot line is HomeSpot AgentPro, which went live this month.  There will (hopefully) be many posts in 2011 about the outcome of that effort.

    What did I do not so well in 2010?

    I’ve been thinking through this question a lot.  It’s always hard to find negative or imperfect patterns or trends in one’s own life.  That I am willing to be introspective at all is somewhat significant.

    In light of all my work in 2010 being as a contractor, I have found that I lacked a certain passion about the work to which I was contributing.  Contractors are by nature transient, and while I did not hold any specific fear of arriving at the office one day and being shown the door, I always held the job to be temporary.  When coupled with my own venture taking time in the evenings, I think the net result was my job became one of duty, not of passion.

    I know that I cut corners in some of the coding and design I delivered.  Sometimes it was due to time constraints.  Sometimes because the client had simply not asked for what I felt was the ‘complete’ solution to a problem.  But either way, as one who stands up to say that the craft of software development is rooted in quality and pride, taking shortcuts is not the pattern I want to find myself adopting.

    What can I improve in 2011?

    I have always considered myself a goal setter.  Perhaps not always as much of a goal achiever as I would prefer, but it is in my nature to establish a target outcome and work to move towards it.

    Thus, in identifying areas of improvement for the year ahead, I certainly look first to those spots where I didn’t do so well – namely passion and quality.

    For Passion, I need to move past thinking of a ‘day job’ as a necessary evil while I do other things.  Rather, every opportunity to get my hands on code – no matter who wrote it, what it does, or who it is for – should be embraced. I have always believed that all learning is cumulative – that we do not unlearn.  Consequently, every chance to see, critique and improve code serves me as an education.  Rather than trying to muster passion for my particular employer or client, my passion should reside in becoming the absolute best software developer I can be.  From there the excitement about some client’s particular issue will inevitably flow.

    Secondly, in as much as I have time and opportunity, I want to expand my particular skillset.  The simplest approach this can take is learning a new language, but even within my area of primary proficiency (that being the .NET platform) I know there is a great deal more I can learn and master.  One approach I have considered to this end is working towards earning a professional certification, not so much for the credential, but rather as a structured way to move towards mastery.

    Finally, in 2011 I want to be more deliberate about participating in the larger community of developers, namely through participation in my local user groups, but also through venues such as Stack Overflow, Linked In Questions and other forums.  Putting myself around other like-minded individuals will benefit me as a developer and professional in many ways.

    And so, here’s to 2011 being a new year of quality, passion, community and progress.

  • Launched! HomeSpot AgentPro goes live.

    Countless late nights are behind me as I joyfully announce the launch of our newest HomeSpot product, AgentPro.

    https://www.HomeSpotAgentPro.com

    AgentPro allows professionals in the real estate and home improvement industries to leverage our consumer product HomeSpot HQ as an economical and value-adding marketing platform.

    Do you know a real estate agent who’s looking for a creative new way to stay in front of their clients in 2011?  Tell them about AgentPro today.

  • A video every serious developer should watch.

    If you have ever inherited somebody else handiwork and the code therein, you’ll appreciate what Robert C. Martin has to say in this keynote speech at the QCon London 2010 conference earlier this year.  It is well worth the hour.

    https://www.infoq.com/presentations/Robert-C.-Martin-Bad-Code

  • Datasets are not Business Objects.

    Programmers are notoriously stricken with pride when it comes to the design and coding of a solution.  Inevitably, each developer will believe that their particular approach is a) right, b) best, and c) unworthy of scrutiny.  I certainly am guilty of this kind of thinking.

    Thus, often established patterns or best practices fly in the face of the individual developer’s “I know best” mentality.  We rationalize our approach, and invent reasons why it’s better than the industry adopted standard or recognized method.  Consequently, we miss out on the benefit of the collective skills, experience and talent of the larger development community, and our products suffer from the unsupportability of highly idiosyncratic code.

    I use this preface to provide context to the following rant about a trend often seen in .NET development: using DataSets as business domain objects. 

    Object oriented programming has its strength in being able to accurately describe an piece of the world in a way that is predictable and reliable.  More recently, the separation of an object definition (that is, its properties) and object manipulation (that is, methods that operate on an object) has brought forth the trend to have distinctly define domain classes.

    A DataSet, while a suitable container for values pulled from a database table, is not a distinctly defined domain class.  It lacks structure, strong typing, and predictability.  Yet, it is an easy shortcut to connecting our application data to a set of business rules.

    Here are my objections to using DataSets in the place of Domain Objects:

    1. They are unpredictable. 

    Since a DataSet is based on the results of a query, it may at any point in time contain different fields even though it is named the same.  For instance, if two different stored procedures are used to retrieve a Customer record, but one has more (or less) fields selected, then I as a consumer of that data cannot reliably know what fields are available to me.  Does the query return First Name and Last Name, or does it concatenate them together as Full Name?  I don’t know until I try to reference a field that doesn’t exist.

    Contrasted with a Domain Object that explicitely defines the values for a business entity, such that I can always know what values are available to read or write, a DataSet inevitably leads to exception based development.

    2. They are not strongly typed.

    When I define a Domain Object, I explicitly declare each field and its data type.  If I try to assign a value that doesn’t match, I get an exception.  There is an intrinsic level of control that accompanies the strong typing of a well written Domain object.  A DataSet, however, is not explicitly typed. 

    3. They are undocumented.

    In writing a Domain object class, at least with .NET, I have the opportunity to annotate my properties with API style documentation that will be immediately available to any consumer of that class via the Visual Studio IDE.  I can tell my fellow developers about any nuances or rules affecting that class.  Further, the Visual Studio Intellisense auto-completion mechanism will allow a developer to see all of the properties available for that object. 

    A DataSet is a dumb container.  When I ask for a value from the DataSet, it gives me no context, guidance or insight to what that value is or represents.

    To be fair, a DataSet is certainly useful for in-memory representations of data.  But they fall flat when it comes to accurately modeling a domain or representing an entity.

    Here is some additional commentary on this topic from people far more qualified to expound on the details of this discussion.

  • In Praise of Balsamiq

    I have a lot of reasons to like Balsamiq.

    1. They make a great product that is easy to use, provides real value, and does exactly what it says it is going to do.
    2. They are a small business, started by people who, according to their website are ” a small group of passionate individuals who believe work should be fun and that life is too short for bad software.”
    3. They use a lightweight company model I can appreciate, with most of their employees working from home and meeting via online tools.

    For those who don’t know, Balsamiq’s flagship product is called Mockups, and it allows you to readily build User Interface design mockups and prototypes.  If you are active in any sort of product or system design effort, Mockups is well worth the purchase price.

    Doing one thing well is a lesson so many companies can still learn.  My kudos to the Balsamiq team for staying focused.

  • Simple API Documentation guidelines

    This month’s issue of MSDN Magazine had a great article from Peter Gruenbaum titled A Coder’s Guide to Writing API Documentation.  Let’s face it, documentation of the code we write is typically an afterthough, rarely given the attention it deserves, and is the first thing we point to (when it is lacking, that is) to complain about the ramp up time required for supporting a system.

    I particularly liked one table Peter included in his article that laid out some basic guidelines for structuring documentation according to the type of code snippet we are annotating.  I think by following these simple guidelines, any developer can have a big impact on their codebase.

    Type Guideline Examples
    Class Start with a word like “Represents” “Represents a user’s photo album.”
    Methods and functions Start with a verb “Returns the number of contacts for the specified area.”

    “Pauses the video.”

    Properties Use a noun or start with verbs such as “Gets” or “Gets and sets” “The user’s tasks.”

    “Gets and sets a collection of the user’s tasks.”

    Events Start with a phrase such as “Raised when” or “Occurs when” “Raised when the response from server is received.”
    XML elements Use a noun-based phrase “The city’s postal code.”
    Boolean values For Boolean properties, start with “Indicates whether”; for Boolean return values on methods and functions, start with “Returns whether” “Indicates whether the control is visible.”

    “Returns whether two regions intersect.”

    I am a well documented fan and stickler for good commenting in code.  I have been in too many organizations that refuse to make time or priority to do the necessary effort, but then love to complain when it isn’t sufficient.  By using these basic guidelines, it seems reasonable that at least every public class, property and method can carry some descriptive notes that will aide the next developer who consumes those assets.

    Start small, and I’m sure you’ll find that it has a big impact later on.  Future ranks of developers who inherit your code will undoubtedly thank you for your diligence.