CHAPTER 18

image

Sending Email

One way to usefully extend your application is to add email support. With email, you can deliver alerts and notifications. You can also build application features that users can use to send messages directly from a LightSwitch screen. In this chapter, I’ll show you how to do the following:

  • send notifications from the server
  • create an email service to allow users to send messages from screens
  • use client code to automate Microsoft Outlook

To demonstrate how to add notification capabilities to your application, I’ll show you how to send a message when the status of an issue changes to “closed.” Next, I’ll show you how to build an email service with WCF (Windows Communication Foundation). I’ll then describe the corresponding code you can use to call the service from your screens. The technique I’ll show you is useful, because you can extend it to call other third-party web services. For example, you could modify the code I show you to add stock prices or currency conversion rates to your application.

Overview to Sending Email

In this chapter, I’ll describe three techniques to send email from your applications. The first technique initiates a message when a change in data occurs. You can use this technique to send email notifications and alerts. For example, you could apply this technique to an order-processing system to send automated emails whenever the status of an order changes.

In many other scenarios, you might want to add the ability to send messages through actions that are not associated with a change in data. To cater to these situations, I’ll show you to develop an email service that you can call from your desktop and HTML client screens.

In the final part of this chapter, I’ll show you how to send emails with Microsoft Outlook integration. This method works well for users who spend a lot of time in Outlook. A benefit of this technique is that any messages you send in this way will appear in the user’s Sent Items folder. You can also carry out additional Outlook tasks when you create the message. This could include workflow items such as creating tasks, calendar items, or contacts.

Sending Email Notifications

To begin, I’ll show you how to send email messages when a change in data occurs—we’ll send an email notification when the status of issue record changes to “closed.”

Before I describe this technique, there are some preparatory tasks you need to carry out. To send emails, you need to have access to an SMTP Service. Within an organization, a system administrator can often provide you with access to such a service. Alternatively, you could use the SMTP service that your email provider or ISP (Internet Service Provider) provides. Failing that, you can install your own SMTP service. IIS includes an in-built SMTP service, which you can install through the Windows Features section of the Control Panel.

There are a few remaining steps. First, I’ll describe a technique you can use to store SMTP credentials in your application. Next, I’ll show you how to build a reusable email library to maximize code reuse. Finally, I’ll describe the code that sends the actual message.

Using Configuration Settings to Save Credentials

Your SMTP details can change over time, so it makes good sense to save the settings in a place that you can easily modify after you deploy your application. One option is to store these settings in a user-defined table. Another way is to store your settings in a configuration file. With this approach, you can set these values by editing your application’s Web.config file after you have deployed your application. You can find this file in the root of your published application.

To create application settings, right-click your Server project and open the properties window for your project. Switch to the Settings tab and create a set of application-scoped settings to store your email credentials, as shown in Figure 18-1.

9781484207673_Fig18-01.jpg

Figure 18-1. Creating configuration settings in your server project

The configuration file provides a safe place in which to store your credentials. ASP.NET provides a method you can use to encrypt any sensitive settings. For reference, you can use the aspnet_regiis utility with the pe switch on your deployment server to encrypt these settings. One thing to be aware of is that when you modify a web.config file on a live server, IIS will restart the application pool. When this happens, your application will respond more slowly when it receives the next request. Your application will also lose session-state information if you configure your IIS server to use the “in process” session option.

If you choose to store your configuration details in a table, the benefit is that users can change the configuration values without needing file-level access to the server.

Creating a Reusable Email Class

Let’s review the steps to create an email helper class to support the code in this chapter. The benefit of a helper class is that it saves you from duplicating code if there are several places in your application from which you want to send messages. Also, you can more easily reuse code in other .NET applications when you extract the logic into a separate class.

To add this class, create a new class in your server project. To help keep your project tidy, you can create this class in a folder called UserCode. Name your class SMTPMailHelper and add the code that’s shown in Listing 18-1.

The SmtpMailHelper class defines a static method called SendMail, which is the method you would call to send an email message.

The code in this method creates a new instance of a MailMessage object image. This object represents an email message, and you can use it to set properties such as the recipient address, subject, and message body. Table 18-1 shows a list of properties you can set.

Table 18-1. MailMessage Object Properties

Name

Description

Attachments

Gets the collection used for storing file attachments

Bcc

Gets a collection of blind carbon copy (BCC) recipients

CC

Gets a collection of carbon copy (CC) recipients

DeliveryNotificationOptions

Gets or sets the delivery notifications

From

Gets or sets the from address

IsBodyHtml

Gets or sets a value indicating whether the message body is in HTML

Priority

Gets or sets the message priority

ReplyToList

Gets or sets the list of reply to addresses

Sender

Gets or sets the sender’s email address

The next section of code checks for the presence of an HTML tag in the message body image. If this test succeeds, the code sets the format of the email message to HTML image. This line of code allows you to author HTML emails by including an HTML tag at the start of your message body. The benefit of an HTML email is that you can apply custom styles, colors, and formatting to your message.

The helper class includes file-attachment support, and the next section of code defines the logic that implements this functionality image. The final part of the method sends the message by calling SmtpClient’s Send method image. The SmtpClient class represents the object that sends a message. You must initialize this object with the SMTP server address and port number. You can optionally set authentication credentials if your server requires this. The commented section shows the code you would use to supply a username and password value.

For the SMTP server setting, you can supply either a server name or an IP address. In addition to the Send method, the SmtpClient class also includes a method called SendAsync that you can call to send your message asynchronously.

To initialize the SmtpClient object with SMTP settings, this code calls methods in .NET’s System.Configuration namespace to retrieve the settings that you added earlier in this chapter. Note that with VB, you can more easily access configuration settings through the My.Settings object.

This completes the code for your email helper class. If you want to use this class in multiple LightSwitch projects, an effective way is to compile the code into a separate class library project. You can then use the code by referencing the library in your Server project.

Image Tip  If you have a Google Mail (or Gmail) account and want to use the SMTP service that Google provides, there are settings that you need to apply. The server name you need to use is smtp.gmail.com. The port number that Google uses is 465, rather than the standard SMTP port of 25. Next, set the DeliveryMethod attribute of SmtpClient object to SmtpDeliveryMethod.Network. To authenticate to the service, set the SmtpClientcredentials property with the credentials of your Google account.

Sending the Email

Now that you’ve created your email helper class, let’s review how to write the code that sends the message from your server. To demonstrate this technique, I’ll show you how to send an email message when the status of an issue record changes to “closed.” To implement this feature, we’ll add code in the Issue entity’s Updating method.

To create this example, open your Issue table in the table designer. Click the Write Code button and select the Updating method. Now, enter the code in Listing 18-2.

You can now run your application and test this logic. To do this, open an existing issue record and change the status to “closed.” At this point, the server should send an email message just before the server saves the record to the database.

The first part of the code checks whether the user has changed the issue status to “closed” image. It does this by checking that the original status isn’t “closed,” and then tests if the new status value is “closed.” Next, the code calls the SendMail method in the helper class to send the message.

Note that the SendMail method includes the capability to append a file attachment. If you want to include an attachment with your message, you can retrieve the data from a table. Alternatively, you could call the File.ReadAllBytes method from the System.IO namespace to attach a file from the file system of your server.

Image Tip  If your code fails to send the email, there are a few simple things that you can check. First, do you have any firewalls or antivirus applications that are blocking your SMTP traffic? Some antivirus programs protect against mass-mailing worms and block any outgoing SMTP traffic. Second, email servers such as Microsoft Exchange or the SMTP service that IIS provides may require you to specify the IP addresses of the devices that can access the service.

Initiating Emails from LightSwitch Clients

The technique that I just showed you relies on changes to data. Most likely, there will be scenarios in which you want to send an email regardless of a change to data. In this section, I’ll show you how to build this functionality.

I’ll show you how to build a WCF web service that sends SMTP mail messages. Once you build this service, you can call it from both your HTML client and desktop applications.

The service that we’ll build includes two variations of the same method. The first method is a REST (Representational State Transfer)-based method that returns data in JSON (JavaScript Object Notation) format. This method supports HTML client applications, where you can easily call REST-based web services with AJAX.

The second method uses SOAP (Simple Object Access Protocol) and returns data in XML format. The purpose of the SOAP method is to support desktop clients. Although you can connect to REST-based web services from Silverlight, you cannot create a service reference to a REST service. A service reference provides you with a client proxy that exposes typed objects that you can use to access your web service. It makes it easier for you to program your application, because the code editor provides IntelliSense suggestions for your web-service methods, and Visual Studio won’t compile your application if you fail to specify the correct arguments for a method.

Although the primary purpose of this section is to demonstrate how to send email, a secondary objective is to show you how to call a web service from your application. With web services, you can incorporate many value-added features into your application. For example, you could connect to an SMS gateway to send text messages, or you could connect to web services that return stock prices, currency conversion rates, or postal-code lookups. You can carry out a web search on “Free WebService” in order to find web services you can use, or, alternatively, you can visit a site such as http://www.webservicex.net/ws/default.aspx.

Building an Email service

Let’s now write the code to build our email service. The first step is to add a WCF web service to your LightSwitch application. To do this, right-click your Server project, click Add image New Item, and select the “WCF Service” option, as shown in Figure 18-2. Name your service MailService.svc.

9781484207673_Fig18-02.jpg

Figure 18-2. Adding a new WCF web service

The WCF service template creates two files in your project. The first file contains the interface, and the second file includes the implementation. The interface defines the architecture of your web service. It defines the method names, parameters, and return types of your web methods. To build a SOAP-based method that you can access from a Silverlight client, you need to define an interface in order for the underlying connectivity to work. But for a purely REST-based web service, you don’t need to define an interface if you don’t want to.

Listing 18-3 shows the content you need add to your interface file. In order to apply the correct code decorations, you need to add a reference to the System.ServiceModel.Web.dll assembly and add using or import statements that reference the System.ServiceModel.Web namespace at the top of your code file.

The code in Listing 18-3 defines the two web service methods. You can configure each method by applying the WebInvoke attribute. The Method property defines the HTTP verb that the caller must supply in order to invoke the web method image. The verbs that developers most often use are GET and POST. You should use the value GET for web methods that return data. For web methods that insert and update data, you should set this value to POST. When a client issues a HTTP POST request, servers and clients will not cache the result of the web method. Therefore, you should use the GET verb if your method always returns the result for a given set of input values. The technical term that describes this behavior is an idempotent operation. An important point here is that you must specify the method value in uppercase. If you enter the value post in lowercase, the server will return a 404 error when you try to call the web service. In normal circumstances, you often encounter 404 errors when the resource is missing on the server or when you enter an incorrect web address. If you encounter this error by using lowercase for the HTTP verb, you can waste hours investigating before working out the exact cause of the problem.

The ResponseFormat property specifies the data format of the message that the method returns image. For a SOAP-based method, the return data is in XML, whereas for a REST-based method, the return type is JSON.

For VB.NET, make sure that you specify the LightSwitchApplication namespace at the top of your code file. When the WCF service template creates your initial interface file, it doesn’t specify a namespace for your interface. If you don’t specify a namespace, you won’t be able to refer to the interface in the endpoint section of your web.config file. The inability to do this will prevent your service from working correctly.

After you define your interface, the next step is to add the code that defines the implementation. To do this, add the code in Listing 18-4 to your MailService.svc.cs or MailService.svc.vb file.

This listing contains the code that implements your service. The SendMailREST and SendMailSOAP methods call the SendMail helper method that you created earlier in this chapter. These methods return a string result that indicates the result of the email procedure.

With VB.NET, make sure to add the code that sets the namespace to LightSwitchApplication. In conjunction with this change, you also need change the service attribute value from .MailService to LightSwitchApplication.MailService in the first line of your MailService.svc file. To open your MailService.svc file, right-click the file in Solution Explorer and select the “View Markup” menu item. Do not try to open the MailService.svc file directly by double-clicking it in Solution Explorer. When you double-click an SVC file, Visual Studio opens the code behind file rather than opening the actual SVC file.

The final step is to configure your service by modifying some of the settings beneath the system.serviceModel section of your web.config file, as shown in Listing 18-5.

There are three main things you need to set up in this file: the service, the service behavior, and the endpoint behavior.

The first section declares your service. The code in this section defines two endpoints for your service: a default REST-based endpoint and a SOAP-based endpoint. The address attribute specifies the endpoint address that the caller can use to access the server. In this example, the code sets the address to soap image. This configures the endpoint to listen on an address that is prefixed with the word soap. An example URL would be: http://webserver/soap/MailService.svc.

The service-behavior configuration turns on metadata publishing by setting the httpGetEnabled attribute to true image. When you set this value to true, it allows you to view the WSDL (Web Service Description Language) page for your web service. This page is important, because you can use it to check that your web service functions (at a basic level). For desktop client applications, you need to enable this setting so that you can add a service reference to your web service from Visual Studio. The next line configures the service to include the exception details in any error message that the service generates. This setting can assist you greatly when you debug your application. However, it’s good practice to disable this option when you deploy your application, for security reasons.

The final section defines an endpoint behavior that includes the webHttp element image. This is the endpoint behavior that you need to define in order to support a REST-based service.

At this point, your WCF service is complete, and you can carry out some preliminary checks. To do so, build and run your project. Next, open a web browser and browse to your service’s WSDL page. The web address you would use is the root URL for your server followed the name of your service followed by the question mark character. In this example, the address is http://localhost:49814/MailService.svc?.

If you now see the page that’s shown in Figure 18-3, you’ve successfully created your service. If not, you’ll probably see an error page with the exception details, which you can use to help fix your code. With WCF services, incorrect binding, endpoint, or security settings in your web.config file are the most likely causes of problems. To diagnose WCF errors, a good place to start is to use Windows Event viewer. IIS and IIS Express will log WCF errors in the Application event log.

9781484207673_Fig18-03.jpg

Figure 18-3. Opening your service in a web browser

Sending Messages from HTML Client Applications

Now that you have a working email service, let’s review how to call the service from an HTML client application. I’ll show you how to add an Email button to an issue screen. This feature will allow the user to click the button and to forward the issue details, as shown in Figure 18-4.

9781484207673_Fig18-04.jpg

Figure 18-4. Screenshot of final screen

To build this screen, create a View screen for the Issue entity. To enable the user to enter an email address, use the Add Data Item button to add an Email Address property to your screen. Uncheck the “Is Required” checkbox and name your property Recipient. Drag the Recipient property onto your screen and change the control type to be an email editor control. Next, add a button called Send Email.

To tidy the appearance of your screen, you can move the email controls to a separate tab. Figure 18-5 illustrates the design-time view of the screen. Now, add the code that handles the execute event, as shown in Listing 18-6.

9781484207673_Fig18-05.jpg

Figure 18-5. Design time view of screen

The code in this method returns a promise object. It does this by wrapping the logic in a call to the msls.promiseOperation method image. The promise object places the screen in a “busy” mode and prevents the user from interacting with the application while the call to the web service takes place.

The next part of this code builds the URL to your web service endpoint image. The SendMailREST method requires you to supply emailTo, subject, and body arguments. The next line of code builds a JavaScript object that represents the arguments that you’ll pass to the SendMailREST method image. The next section of code calls the stringify method to convert this JavaScript object to a JSON string image.

The code then uses the jQuery ajax method to call your web service. This method allows you to supply a function that runs when the AJAX request succeeds image. The code that runs on success takes the screen out the “busy” mode by completing the promise operation. The code then calls the showMessageBox method to display the result from the web service.

If the server returns a “404 not found” message, or if the process encounters some other type of error, you can handle this condition by supplying an error function to your jQuery’s ajax call image. The definition of the error function contains three parameters. In the event of an error, the third parameter, errorThrown, allows you to access the textual part of the HTTP status such as “Internal Server Error” or “Not found.” The code in the error function calls the promise operation’s error method and passes control of your application back to the LightSwitch runtime.

Sending Messages from Desktop Applications

In this section, I’ll show you how to call the email service from a desktop application. I’ll describe how to recreate the Issue screen that I showed you in the HTML client sample. As before, this screen will allow the user to forward the contents of an issue record to an email recipient.

The first step is to add a service reference from your project. To do this, run your application so as to start your web service. Now, stop the debugger. When you do this, your web service will continue to run in the background. Now, right-click your client project and select the “Add Service Reference” option. When the Add Service Reference dialog opens, enter the URL to your web service and click on the Go button. The address you use should point to your SVC endpoint (for example, http://localhost:15340/MailService.svc). This populates the Services and Operations boxes that are shown in Figure 18-6. Set the value of the Namespace text box to MailService and click on the OK button.

9781484207673_Fig18-06.jpg

Figure 18-6. Adding a service reference

After you add a service reference, you can call your web service from .NET screen code. To build a screen that calls your web service, open (or create) a detail screen for the issue entity. Just like in the HTML client example, use the Add Data Item dialog to add a property called Recipient. Add a button called Send Email, and add the code that’s shown in Listing 18-7.

Just like the HTML sample, this code sets your web service’s endpoint address in code. This makes it easier for you to deploy your application, because there’ll be no need to configure the address of your service endpoint. The code accomplishes this by finding the address of your XAP file and stripping off the trailing part of the address that contains DesktopClient/HelpDesk.Client.xap image. It then uses the root part of the URL to build an address that points to your MailService.svc endpoint image. Notice how the address ends with the suffix soap. This is because endpoint value in the web.config file configures this address as a SOAP/XML-based endpoint.

The next line declares a proxy to your web service image. Next, the code defines the logic that runs when the web-service call succeeds image. Finally, the line toward the end of the method calls your web service’s SendMail method asynchronously image. This completes your screen, and you can now run your application. When you open an Issue screen, you can click the Email button to forward the contents of the record to an email recipient.

If your code fails to connect to your web service at runtime, try to create your proxy by calling the non-overloaded constructor (for example, New MailService.MailServiceClient()). This applies the endpoint address that you specified in the Add Service Reference dialog. This can help you diagnose the problem preventing you from establishing a connection. Another method you can use to diagnose problems is to enable application tracing and to view the trace results when your web-service connection fails. You can enable tracing by setting the Microsoft.LightSwitch.Trace.Enabled value to true in your web.config file. As I mentioned earlier, the Windows Event Viewer is another tool you can use to help diagnose errors.

Image Note  For desktop applications, you can only connect to web services that originate from the same web server. The default Silverlight client policy imposes this restriction for security reasons.

Sending Mail with Microsoft Outlook

In the final part of this chapter, I’ll show you how to send messages by automating Microsoft Outlook. This technique is entirely client based, and unlike the previous example, it requires no server-side coding.

In this example, I’ll show you how to add a button to an Issue Detail screen. When a user clicks this button, the code will create an Outlook message and use the issue data to compose the body of the message. The process leaves the Outlook message open on the screen and enables the user to review and send the message.

A benefit of this technique is that you can use the Outlook API to automate other features in Outlook. For example, you could create tasks, calendar items, and other workflow items at the same time as you create your message. Another useful feature is that any messages a user sends from Outlook will appear in the Sent Items folder.

Just as in the previous example, we’ll build a reusable class library that we can use throughout our application. To create the helper class, create a new class in your client project and add the code that’s shown in Listing 18-8. As before, you can add your code to a folder called UserCode to keep your project tidy.

This class defines a method called CreateEmail image. This is the method that you would call to create an Outlook message. COM automation works only for desktop applications, so the first part of the code checks that your application is configured to run as a desktop application, rather than as a browser application image.

The next part of the code obtains a reference to the Outlook application image. If Outlook is already open, it uses COM’s GetObject method to obtain a reference to the existing instance of Outlook. Otherwise, it uses the CreateObject method to create a new instance of Outlook.

The next part of the code calls the Outlook API’s CreateItem method to create a new mail message image. Just like the SMTP helper method that you created in Listing 18-1, the code tests for the existence of an HTML tag image. If this tag exists, the code sets the format of the mail message to HTML. The next section of code sets the message body, subject, and recipient address. Finally, the code saves the email message image and calls the Display method to show the message contents in a new message window image.

At this point, the user can review the message and manually click on the message’s Send button to complete the send. If you want to send the email without any user intervention, delete the call to the Display method and call the message’s Send method instead.

The final step that remains is to call your CreateEmail method from a screen. Open the IssueDetail screen from earlier and add a button called SendWithOutlook. This screen should include a local email address property called Recipient, which you added in the previous section. Now, add the code that’s shown in Listing 18-9.

This code in the SendWithOutlook method calls the CreateEmail method and supplies the email address, subject, and message body values that are shown on the screen image. This code also implements the SendWithOutlook_CanExecute method image. The purpose of this code is to disable the SendWithOutlook button if the application isn’t running on the desktop. Figure 18-7 illustrates how this screen appears at runtime.

9781484207673_Fig18-07.jpg

Figure 18-7. Clicking the Send Email button creates an Outlook Message

Image Tip  Although this chapter focuses on email, you can automate Outlook in many other ways. By using similar code, you could create some powerful applications. For example, you could create Outlook appointments, contacts, or tasks via your LightSwitch application.

Summary

This chapter showed you three ways to add email support to your LightSwitch application. I’ve showed you how to send email notifications, how to send emails from both desktop and HTML client screens, and how to automate Microsoft Outlook.

At the beginning of this chapter, I showed you how to create a reusable email method that you can use throughout your application. This method sends messages by calling the objects in the System.Net.Mail namespace. In order to send messages, you need access to a SMTP mail server. This technique requires you to store your email credentials somewhere in your application, and I showed you how to use configuration settings to store the values in your web.config file.

The first technique I showed you calls code to send messages when a change in data occurs. You can use this technique to send email notifications and alerts. To demonstrate this, I described how you can send a message when the status of an issue changes to “closed.” To implement this method, you would write code that handles the updating event of a record. The code you add here checks the status of the record and calls the helper method to send a message if appropriate.

Most likely, there will be scenarios when you want to send a message irrespective of changes to data. To handle this scenario, I showed you how to build a WCF web service to send email messages. I then showed you the corresponding code to call this service from HTML client and desktop applications.

This web service provides both SOAP- and REST-based methods. The REST-based method is designed for HTML client applications. With HTML client applications, you can easily call REST-based web services by using jQuery’s ajax method. With desktop applications, the SOAP-based method allows you to add a service reference to your web service from your client project. A service reference allows you to call web-service methods through a strongly typed proxy object that includes IntelliSense support.

In the final part of this book, I showed you how to create email messages by automating Microsoft Outlook. This technique is ideal for users who spend a lot of time in Outlook. By using COM automation, you can also assist the workflow process by creating tasks or calendar items in code.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset