Feedback
 
Did this article resolve your question/issue?

   

Your feedback is appreciated.

Please tell us how we can make this article more useful. Please provide us a way to contact you, should we need clarification on the feedback provided or if you need further assistance.

Characters Remaining: 1025

 


Article

Configure Registration Widgets Email Sender Name

« Go Back

Information

 
Article Number000084224
EnvironmentProduct: Sitefinity
Version: 6.x, 7.x, 8.x, 9.x, 10.x
OS: All supported OS versions
Database: All supported Microsoft SQL Server versions
Question/Problem Description
How to configure the Registration Widgets Email Sender Name?
Restoration widget throws Exceptionis: InvalidOperationException - The current type, Telerik.Sitefinity.Web.Mail.IEmailSender, is an interface and cannot be constructed. Are you missing a type mapping?
 
Steps to ReproduceFeather widget:
1. Place widget on page,
2. Click advanced
3. Click model
4. Set a value in the EmailSenderName field.
5. Configure widget to send an email

WebForms widget:
1. Place widget on page,
2. Click advanced
3. Set a value in the EmailSenderName field.
5. Configure widget to send an email
Clarifying Information
Error MessageException occurred while: while resolving.
Exceptionis: InvalidOperationException - The current type, Telerik.Sitefinity.Web.Mail.IEmailSender, is an interface and cannot be constructed. Are you missing a type mapping?
-----------------------------------------------
At the time of the exception, the container was:

Resolving Telerik.Sitefinity.Web.Mail.IEmailSender,<Name Entered In the Email Sender Name Field>

Source : Telerik.Sitefinity.Utilities
Help link :
TypeRequested : IEmailSender
NameRequested : <Name Entered In the Email Sender Name Field>
Data : System.Collections.ListDictionaryInternal
Defect/Enhancement Number
Cause
Resolution
The EmailSenderName property is not Intended for a friendly email sender name (i.e. John Doe <john.doe@mail.com>). 
The EmailSenderName property is intended for getting a named instance of a custom implementation of the Telerik.Sitefinity.Web.Mail.IEmailSender interface, registered in Sitefinity's ObjectFactory.

1. Implementing a custom IEmailSender
using System;
using System.Net;
using System.Net.Mail;
using System.Security;
using System.Text;
using System.Web.UI.WebControls;
using Telerik.Sitefinity.Configuration;
using Telerik.Sitefinity.Localization;
using Telerik.Sitefinity.Services;
using Telerik.Sitefinity.Web.Mail;

namespace SitefinityWebApp.Custom
{
    public class EmailSenderCustom : IEmailSender
    {
        protected SmtpClient Client;

        protected SmtpElement SmtpSettings;

        protected const string Utf8 = "utf-8";


        #region IDisposable
        public void Dispose()
        {
            this.Sending = null;
            this.Sent = null;
            this.Error = null;
            this.Client.Dispose();
        }
        #endregion

        #region IEmailSender

        public EmailSenderCustom() { }

        public void Initialize()
        {
            if (this.Client == null)
            {
                this.SmtpSettings = this.GetSitefintiySmtpSettings();

                if (this.CheckIfHasSmtpPermissions())
                {
                    this.LastErrorMessage = string.Empty;

                    this.Client = this.GetDotNetSmtpClient(this.SmtpSettings.Host, this.SmtpSettings.Port);
                    if (!this.SmtpSettings.UserName.IsNullOrEmpty() || !this.SmtpSettings.Password.IsNullOrEmpty())
                    {
                        this.Client.Credentials = this.GetCredential(this.SmtpSettings.UserName, this.SmtpSettings.Password, this.SmtpSettings.Domain);
                    }
                    this.Client.DeliveryMethod = this.SmtpSettings.DeliveryMethod;
                    this.Client.EnableSsl = this.SmtpSettings.EnableSSL;
                    this.Client.PickupDirectoryLocation = this.SmtpSettings.PickupDirectoryLocation;
                    this.Client.Timeout = this.SmtpSettings.Timeout;
                }
            }
        }

        public void Send(MailMessage message)
        {
            if (this.Client == null)
                throw new InvalidOperationException(this.LastErrorMessage);

            if (message == null)
                throw new ArgumentNullException(nameof(message));

            if (this.RaiseSending(new MailMessageEventArgs(message)))
            {
                this.SendInternal(message);
                this.RaiseSent(new MailMessageEventArgs(message));
            }
        }

        public void Send(string @from, string to, string subject, string message)
        {
            if (from.IsNullOrWhitespace() ||
                to.IsNullOrWhitespace() ||
                subject.IsNullOrWhitespace() ||
                message.IsNullOrWhitespace())
            {
                throw new ArgumentException();
            }

            MailMessage msg = this.GetMailMessage();
            msg.From = this.GetMailAddress(from);
            string[] recipients = to.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string recipient in recipients)
            {
                msg.To.Add(this.GetMailAddress(recipient.Trim()));
            }
            msg.Subject = subject;
            msg.Body = message;
            msg.IsBodyHtml = true;
            this.Send(msg);
        }

        public void SendAsync(string @from, string recipients, string subject, string body, object userToken)
        {
            if (this.Client == null)
                throw new InvalidOperationException(this.LastErrorMessage);

            if (from.IsNullOrWhitespace() ||
                recipients.IsNullOrWhitespace() ||
                subject.IsNullOrWhitespace() ||
                body.IsNullOrWhitespace())
            {
                throw new ArgumentException();
            }

            this.Client.Send(from, recipients, subject, body);
        }

        public void SendAsync(MailMessage message, object userToken)
        {
            if (this.Client == null)
                throw new InvalidOperationException(this.LastErrorMessage);
            if (message == null)
                throw new ArgumentNullException(nameof(message));

            this.Client.Send(message);
        }

        public bool TrySend(MailMessage message)
        {
            try
            {
                this.Send(message);
                return true;
            }
            catch (Exception error)
            {
                this.RaiseError(new SendMailErrorEventArgs(error));
                return false;
            }
        }

        public bool TrySend(string @from, string to, string subject, string message)
        {
            try
            {
                this.Send(from, to, subject, message);
                return true;
            }
            catch (Exception error)
            {
                this.RaiseError(new SendMailErrorEventArgs(error));
                return false;
            }
        }

        public bool CheckIfHasSmtpPermissions()
        {
            try
            {
                string clientHost;
                if (this.SmtpSettings != null && !string.IsNullOrEmpty(this.SmtpSettings.Host))
                    clientHost = this.SmtpSettings.Host;
                else
                {
                    this.LastErrorMessage = this.GetResource("ErrorMessages", "SmtpSettingsAreNotSet");
                    return false;
                }

                bool connectPermissions = this.IsSystemPermissionGranted(new WebPermission(NetworkAccess.Connect, clientHost));
                if (!connectPermissions)
                {
                    this.LastErrorMessage =
                        string.Format(this.GetResource("ErrorMessages", "NoWebPermissionToConnectToHost"), clientHost);
                    return false;
                }

                bool granted = this.IsSystemPermissionGranted(new SmtpPermission(SmtpAccess.Connect));
                if (!granted)
                {
                    this.LastErrorMessage = this.GetResource("ErrorMessages", "NoSmtpConnectPermissionGranted");
                    return false;
                }

                int clientPort = this.SmtpSettings.Port;
                if (clientPort != 25)
                {
                    granted = this.IsSystemPermissionGranted(new SmtpPermission(SmtpAccess.ConnectToUnrestrictedPort));
                    if (!granted)
                    {
                        this.LastErrorMessage = this.GetResource("ErrorMessages", "NoSmtpPermissionGrantedForNonDefaultPort");
                        return false;
                    }
                }

                return true;
            }
            catch (SecurityException securityException)
            {
                this.LastErrorMessage = securityException.Message;
                return false;
            }
        }

        #endregion

        #region Events

        public event EventHandler<MailMessageEventArgs> Sending;
        public event EventHandler<MailMessageEventArgs> Sent;
        public event EventHandler<SendMailErrorEventArgs> Error;


        /// <summary>
        /// Raises the <see cref="Sending"/> event
        /// </summary>
        /// <param name="args">Event arguemtns</param>
        /// <returns>true if event was not cancelled, false if the event was cancelled</returns>
        /// <exception cref="ArgumentNullException">When <paramref name="args"/> is <c>null</c></exception>
        protected internal virtual bool RaiseSending(MailMessageEventArgs args)
        {
            if (args == null)
                throw new ArgumentNullException(nameof(args));

            if (this.Sending != null)
            {
                args.Cancel = false;
                this.Sending(this, args);
                return !args.Cancel;
            }

            return true;
        }

        /// <summary>
        /// Raises the <see cref="Error"/> event
        /// </summary>
        /// <param name="args">Event arguments</param>
        /// /// <exception cref="ArgumentNullException">When <paramref name="args"/> is <c>null</c></exception>
        protected internal virtual void RaiseError(SendMailErrorEventArgs args)
        {
            if (args == null)
                throw new ArgumentNullException(nameof(args));

            this.Error?.Invoke(this, args);
        }

        /// <summary>
        /// Raises the <see cref="Sent"/> event
        /// </summary>
        /// <param name="args">Event arguments</param>
        /// /// <exception cref="ArgumentNullException">When <paramref name="args"/> is <c>null</c></exception>
        protected internal virtual void RaiseSent(MailMessageEventArgs args)
        {
            if (args == null)
                throw new ArgumentNullException(nameof(args));

            this.Sent?.Invoke(this, args);
        }
        #endregion

        #region Protected Methods

        protected internal virtual SmtpElement GetSitefintiySmtpSettings()
        {
            return Config.Get<SystemConfig>().SmtpSettings;
        }

        protected internal virtual SmtpClient GetDotNetSmtpClient(string host, int port)
        {
            return new SmtpClient(host, port);
        }

        protected virtual NetworkCredential GetCredential(string user, string password, string domain)
        {
            if (domain.IsNullOrEmpty())
            {
                return new NetworkCredential(user, password);
            }

            return new NetworkCredential(user, password, domain);
        }

        protected internal virtual bool IsSystemPermissionGranted(IPermission permission)
        {
#pragma warning disable 618
            return SecurityManager.IsGranted(permission);
#pragma warning restore 618
        }

        protected internal virtual string GetResource(string classId, string msgId)
        {
            return Res.Get(classId, msgId);
        }

        protected internal virtual MailMessage GetMailMessage()
        {
            return new MailMessage();
        }

        protected internal virtual MailAddress GetMailAddress(string address)
        {
            return new MailAddress(address);
        }

        protected internal virtual void SetEncoding(MailMessage message)
        {
            string subjectEncodingName = this.SmtpSettings.EmailSubjectEncoding;

            if (String.IsNullOrEmpty(subjectEncodingName))
            {
                subjectEncodingName = Utf8;
            }

            message.SubjectEncoding = Encoding.GetEncoding(subjectEncodingName);

            string bodyEncodingName = this.SmtpSettings.EmailBodyEncoding;

            if (string.IsNullOrEmpty(bodyEncodingName))
            {
                bodyEncodingName = Utf8;
            }

            message.BodyEncoding = Encoding.GetEncoding(bodyEncodingName);
        }

        protected internal virtual void SendInternal(MailMessage message)
        {
            this.SetEncoding(message);
            this.Client.Send(message);
        }


        #endregion
        public string LastErrorMessage { get; set; }

        // this is hardcoded to false since when Sitefinity tries to execute the async operation the follwing exception is thrown:
        // Message (Inner Exception):
        // An asynchronous operation cannot be started at this time. Asynchronous operations may only
        // be started within an asynchronous handler or module or during certain events in the Page lifecycle. 
        // If this exception occurred while executing a Page, ensure that the Page is marked <%@ Page Async=\"true\" %>. 
        // This exception may also indicate an attempt to call an \"async void\" method, which is generally unsupported 
        // within ASP.NET request processing. Instead, the asynchronous method should return a Task, and the caller 
        // should await it.
        public bool SupportsAsyncSending
        {
            get { return false; }
        }
    }
}

2. Register the named instance in Sitefinity's ObjectFactory, this could be done in the Global Application Class
using System;
using SitefinityWebApp.Custom;
using Telerik.Microsoft.Practices.Unity;
using Telerik.Sitefinity.Abstractions;
using Telerik.Sitefinity.Web.Mail;

namespace SitefinityWebApp
{
    public class Global : System.Web.HttpApplication
    {

        protected void Application_Start(object sender, EventArgs e)
        {
            Bootstrapper.Bootstrapped += this.Bootstrapper_Bootstrapped;
        }

        protected void Bootstrapper_Bootstrapped(object sender, EventArgs e)
        {
            ObjectFactory.Container.RegisterType(typeof(IEmailSender), typeof(EmailSenderCustom), "NamedEmailSender",
                new TransientLifetimeManager());
        }
....


* At this point, the project must be built

3. To use this custom email sender class in the Feather (MVC) Registration widget:
3.1. Drop the Registration widget on the desired page
3.2. Click on the "Edit" button on the top right side of the widget
3.3. Click the Advanced button
3.4. Click the Model button
3.5. In the EmailSenderName field enter the name by which the custom IEmailSender class has been registered, in this example - NamedEmailSender
3.6. Click Save

Workaround
Notes
Attachment 
Last Modified Date4/24/2018 12:08 PM