clyx studios

everything clicks with Clyx
welcome to clyx studios       sign in           
in Search

clyx development blog

Community Server and .NET 2.0 (Part 2)

In Part 1 of this series I talked about our experiences installing Community Server 2.0 on our production web host (ASP.NET 2.0, SQL Server 2000, Medium Trust environment).

In this part, I'll outline what we did to get emails working with our site. Before I start, keep in mind that Version 2.1 of Community Server is only weeks away, and it is highly likely that the new version will solve this issue once and for all. But in the interim, if you'd like to try a fairly straightforward workaround, read on...

Overview

The Problem

The site wasn't sending emails for new users, mass mailing, etc. The Email Job was failing with with an Iterator Failed message, there were security exceptions and "operation could destabilize the runtime" exceptions. An example message from the exceptions report:

Message Iterator Failed. Type CommunityServer.Components.EmailJob. Method SendQueuedEmailJob. Reason System.Security.Permissions.SecurityPermission
CommunityServer.Components.CSException: Iterator Failed. Type CommunityServer.Components.EmailJob. Method SendQueuedEmailJob. Reason System.Security.Permissions.SecurityPermission

The Options

  1. Check that it is not related to the SMTP settings.
  2. Look for a solution on the CS forums and the web.
  3. Rewrite the EmailQueueProvider and any dependencies to remove the problem.
  4. Replace the existing EmailQueueProvider with another compatible mechanism for sending emails.

The Assumptions

  • a temporary fix is all that is required given the imminent release of CS 2.1;
  • email traffic from the website is light;
  • you are not hosting multiple communities on the same CS installation;
  • you are using, or can use, the CS 2.0 SDK.

Solution

Option 1 looked the most likely so I put together a test ASP.NET page that sent an email back to me using hard-coded SMTP settings. I uploaded this to our host and ran it and it worked fine.


Option 2 was next so I grabbed the messages from the exceptions report and searched. It seems several other people were in the same boat with no solution in sight, and googling didn't help much either. Option 3 looked complicated and risked regression problems, plus with the 2.1 release just around the corner it wasn't worth the risks and effort.

So Option 4 was the answer. We took the code from our test ASP.NET page, adapted it to the CS Queue Provider model, and voila! the SendImmediatelyProvider was born. It does just what it says - as soon as an email is requested, it is sent. There is no queue. One assumption is particularly important here - you must only have light email traffic on your site to use this approach.

Here's what you need to do to use this class:

  • build the code (see below, or download it from the attachment at the end of this post) - either within the SDK (Components project, Provider folder) or as a separate assembly (if separate, change the namespaces accordingly);
  • remove the Emails job from communityserver.config (look for the <Jobs> element). (I first tried setting enabled=false but found that CS continued to execute the job even after recycling ASP.NET);
  • change the EmailQueueProvider under the providers element again in communityserver.config. Change it to read as follows (make the appropriate adjustments if you have compiled a separate assembly)

<add name= "EmailQueueProvider" type= "CommunityServer.Components.SendImmediatelyProvider, CommunityServer.Components"
connectionStringName= "SiteSqlServer"databaseOwnerStringName= "SiteSqlServerOwner" />

And here's the SendImmediatelyProvider code:

1 namespace CommunityServer.Components {

2 using System;

3 using System.Collections;

4 using System.Net;

5 using System.Net.Mail;

6 using System.Web.Mail;


Note that Community Server 2.0 uses the .NET 1.1 System.Web.Mail namespace. This is deprecated in ASPNET 2.0 so our class uses the new System.Net.Mail namespace. System.Web.Mail is still required for compatibility with CS method calls.


7

8 public class SendImmediatelyProvider : EmailQueueProvider {

9

10 #region Member variables

11

12 protected string databaseOwner = "dbo";

13 private string connectionString = null;

14 private ProviderHelper sqlHelper = null;

15

16 #endregion

17

18 #region Constructor

19

20 public SendImmediatelyProvider(string databaseOwner, string connectionString) {


The next three lines are not strictly necessary for our provider but are included here for completeness of the provider pattern.


21 this.connectionString = connectionString;

22 this.databaseOwner = databaseOwner;

23 sqlHelper = ProviderHelper.Instance();

24 }

25

26 #endregion

27

28 public override void DeleteQueuedEmail(Guid emailID) {}

29

30 public override ArrayList DequeueEmail(int settingsID) {

31 return new ArrayList();

32 }

33

34 public override void QueueEmail(System.Web.Mail.MailMessage message) {

35 SiteSettings site = SiteSettingsManager.GetSiteSettings(1000);

 

1000 is the default community ID - if you are hosting multiple communities and they have different SMTP settings, you'll need to modify this code.


36 SmtpClient smtpClient;


Note the use of the new SmtpClient from the 2.0 .NET Framework.


37 if (String.IsNullOrEmpty(site.SmtpPortNumber))

38 smtpClient = new SmtpClient(site.SmtpServer);

39 else

40 smtpClient = new SmtpClient(site.SmtpServer, Convert.ToInt32(site.SmtpPortNumber));

41

42 smtpClient.UseDefaultCredentials = false;

43 if (site.SmtpServerRequiredLogin) {

44 NetworkCredential credential = new NetworkCredential(site.SmtpServerUserName, site.SmtpServerPassword);

45 smtpClient.Credentials = credential;

46 }


This next chunk of code simply migrates the values from the deprecated System.Web.Mail.MailMessage object to a new System.Net.Mail.MailMessage object in preparation for sending via SmtpClient.


47 System.Net.Mail.MailMessage netMessage = new System.Net.Mail.MailMessage(message.From, message.To);

48 netMessage.Subject = message.Subject;

49 netMessage.Body = message.Body;

50 netMessage.IsBodyHtml = (message.BodyFormat == MailFormat.Html);

51 netMessage.BodyEncoding = message.BodyEncoding;

52 netMessage.Priority = System.Net.Mail.MailPriority.Normal;

53

54 smtpClient.Send(netMessage);

55 }

56

57 public override void QueueSendingFailure(ArrayList list, int failureInterval, int maxNumberOfTries) {}

58 }

59 }

Technorati : , ,

Published Tuesday, June 06, 2006 8:40 AM by Rohan
Attachment(s): SendImmediatelyProvider.cs

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Community Server Daily News said:

Ve have vays of making you talk. Efforts continue in providing more and better Community Server documentation
June 7, 2006 12:43 PM
 

Life, Universe and Everything according to Dirk said:

Some of you may have noticed that the email system of QuestMaster.NET hasn't been working properly for...
June 27, 2006 12:01 AM
 

Getting Started forum posts from CommunityServer.com said:

Hello, I am trying to override EmailQueueProvider and followed instructions as in the link below about

August 29, 2008 12:59 AM

Leave a Comment

(required) 
(optional)
(required) 
Submit