Most of you may have already read an earlier post on how to send emails from LightSwitch (seen here). This post extends what was learned in that previous post, and shows how to wire up a button to send an email on demand.That previous post showed a specific function that would send out an email when an entity was added to the database. A helper class was created in the Server project of the LightSwitch solution. Then, when the new record was created in the database, that server code was called and an email went out.
The whole process was pretty simple to implement, however it was a good exercise that helped me better understand how LightSwitch separates concerns. It was this knowledge and understanding that helped me implement a solution for another email challenge.
The challenge I have is this; I want functionality that will let me send an email on demand, via a button on a screen, and I don’t want to code some fancy WCF service or custom extension to do the job.
Here is the thing – you can’t call server code from the client. It is in the server code that the email processing occurs. Why? Because the client and common projects are Silverlight based projects and I can’t add the necessary System.Net reference to those projects – otherwise I would have used the System.Net.Mail namespace directly from the client.
But hey, the Server project is a .Net 4 class library project, and I can add the System.Net reference to that project. That is why the actual email processing has to occur in the Server project. Following me so far?
So, here is what I did…
In the Solution Explorer of my LightSwitch project, I switched to File View so that I can get at the Server project…
Knowing that I need to use an external (SMTP) email service to actually send out the email, I decided to store some static information that my email processing can use to process the email; such as stuff for the email service authentication. To do this, I opened the Server project settings.
Next, I added some Application scoped configuration settings…
…come on, you didn’t actually think that I would post my own credentials did ya…I learned from that mistake already
I made sure to save the updates.
Next, a folder is created within the Server project, and named the folder “UserCode”. Within that folder I created a new Class file and named it “EmailHelper.vb”.
This is the code I added to this file…
Imports System.Net
Imports System.Net.Mail
Namespace LightSwitchApplication
Public Class MailHelper
Private Property SMTPServer As String = My.Settings.SMTPServer
Private Property SMTPUserId As String = My.Settings.SMTPUserID
Private Property SMTPPassword As String = My.Settings.SMTPPassword
Private Property SMTPPort As Integer = My.Settings.SMTPPort
Private Property MailFrom As String
Private Property MailFromName As String
Private Property MailTo As String
Private Property MailToName As String
Private Property MailSubject As String
Private Property MailBody As String
Sub New(ByVal SendFrom As String,
ByVal SendFromName As String, _
ByVal SendTo As String, _
ByVal SendToName As String, _
ByVal Subject As String, _
ByVal Body As String)
_MailFrom = SendFrom
_MailFromName = SendFromName
_MailTo = SendTo
_MailToName = SendToName
_MailSubject = Subject
_MailBody = Body
End Sub
Public Sub SendMail()
Dim SMTPUserAddress = New MailAddress(_SMTPUserId)
Dim mail As New MailMessage
Dim mailFrom As New Mail.MailAddress(_MailFrom, _MailFromName)
Dim mailTo As New Mail.MailAddress(_MailTo, _MailToName)
With mail
.From = mailFrom
.To.Add(mailTo)
.Subject = _MailSubject
.Body = _MailBody
End With
Dim smtp As New SmtpClient(_SMTPServer, _SMTPPort)
smtp.EnableSsl = True
smtp.Credentials = New NetworkCredential(SMTPUserAddress.Address, _SMTPPassword)
smtp.Send(mail)
End Sub
End Class
End Namespace
So, this class contains some pretty simple code. Instantiating the class requires a bunch of parameters that are later used by the SendMail() method. The SendMail() methid is where the mail message gets created, configured, and sent using the a SmtpClient. As you can see, some class properties are defaulted to the values that are stored in the App.Config file of the Server project (which were added earlier).
Next, I go back into the logical view of the solution.
In the logical view, a new table is created. The table name is “ProxyEmail”, and it looks like this…
Now, with this table, I have essentially created a “Model” that I can use in my workaround. Remember, my challenge is to do all this with native LightSwitch features and functionality. I don’t want to create a fancy-smancy WCF service or custom extension for this. I just want to get the job done. By creating this entity, I have, in essence, created a business object that I am going to use to do what I want to do.
Here is the fun part! I can’t call the Server code directly from any screens, however I know that my “entity” can access the server code via its dependencies. For example, my ProxyEmail entity has a method called ProxyEmails_Inserted(), which runs on the server when an entity as added to the table (add to the collection of ProxyEmail entities).
So, I add some code to this method…
…and here is the code if you want…
Private Sub ProxyEmails_Inserted(entity As ProxyEmail)
' Write your code here.
Dim sSubject = "Test Email."
Dim carRtn = Environment.NewLine & Environment.NewLine
Dim sMessage = "The following email has come from a button on LightSwitch..." & carRtn
sMessage += "Testing 1, 2, 3!!"
' Create the MailHelper class created in the Server project.
Dim mailHelper As New MailHelper(entity.SenderEmailAddress, _
entity.RecipientName, _
entity.RecipientEmailAddress, _
entity.RecipientName, _
sSubject, _
sMessage)
' Let 'er rip!
mailHelper.SendMail()
End Sub
So, this is pretty much the same as the last post. Right, but here is how this similar stuff is used to create a feature that will allow you to send an email on demand, rather than relying only on updates to entities.
I create a new Screen and, using the New Data Screen template, name it “SendAnEmail”, but don’t assign any screen data to it…
In the screen designer for the new SendAnEmail screen, I click Add Data Item… and create a Method with a name of “SendMyEmailOnDemand”…
Back in the screen designer, I expand the Screen Command Bar, and drag and drop the SendMyEmailOnCommand method to the command bar.
I right click the newly added button, and select to Edit Execute Code.
I edit the method to this…
…and here is the actual code you can use…
Private Sub SendEmailOnCommand_Execute()
Dim newEmail = DataWorkspace.ApplicationData.ProxyEmails.AddNew()
With newEmail
.RecipientEmailAddress = "paulspatterson@hotmail.com"
.RecipientName = "Paul Patterson"
.SenderEmailAddress = "paul@selectsystems.ca"
.SenderName = "Paul Patterson (Select Systems)"
End With
DataWorkspace.ApplicationData.SaveChanges()
newEmail.Delete()
DataWorkspace.ApplicationData.SaveChanges()
End Sub
What this is doing is simply creating a new ProxyEmail entity, settings it’s properties, the committing the insert to the system. The SaveChanges after the setting the properties will cause the ProxyEmails collection to fire that ProxyEmails_Inserted() method that was wired up earlier, which then sends the email from the server code. After that, the newly added entity is deleted because I don’t need it any more.
So, I F5 to test it…
… and I click the Send Email On Demand button. Then I go and check my email, and presto…
Yes!
This may not be the super cool software code monkey way of doing things, but who cares! It does the job, and I did in no time at all.
Hope you find it useful!
Cheers




































Woderful!
Génial !!!!!!
Thank you…, À votre bon cœur !
Awesome stuff and a great blog. I've been using LightSwitch for a day (c# for few years) and this is just amazing to start off with. Too bad it's all VB.NET, but you can't have it all in life. I get it 100%, but it just looks awkward to me lol.
This is good One.
Hi Paul
Do you have any idea regarding, how to send attachment (e.g .pdf, .doc, etc) through email from lightswitch application.
Hmm. Good question.
I believe that an attachment can be included by adding it as an Attachment object (see here: http://msdn.microsoft.com/en-us/library/system.ne…
This is exactly what I was looking for. Many Thanks Paul !!
Glad this helped Francis.
Good to see that this article is still relevant today. Let us know how it works out.
Paul
This is great, thank you Is this available in C#
That is great and I have it working beautifully. However, I now have a slightly different related problem – maybe somone has some neat ideas? I want to send out a bulk emailing, so I modify the entity parameters to say what is needed and the server side code extracts all the relevant data from the database formats it and sends it. In order to return control I do all the collation and sending in a new thread. But then I need to be able to alert my user if one or more of the emails has failed – so how to get that information back to them. I had planned to add a status to a special table in the databse sothat there would also be a permanent record of every emailing and whether ot not it succeeded, BUT I cannot do a savechanges() on the databse from code started from the inserted() function as that original savechanges() is still in progress.
Any neat ideas?
please?
Hi Justin,
Leveraging a custom table for the status of the bulk email process is a great idea. I'll try a couple of ideas to see what might work for you. I'll keep you in the loop.
Paul
This has been very helpful. Thank you!!