Blog Archives

Quick .Net Email Reference

I’ve done a bit of encapsulation here to abstract the concept into clearer functionality, IMO.

Make sure to add “using” reference directives for System.Threading and System.Net.Mail accordingly, when necessary.

Note usage of basic boolean “sync lock” style logic in place of static members for thread safety.

(This code is purely illustration of concept and functionality is not assured. Correctness of code is coincidental. 🙂 )

C#:

private Automailer mailer;

private void StartEmailAutomailer() {
      int interval = 100000;
                    System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient();
                    //set host, port, etc from your data layer
                    List<System.Net.Mail.MailAddress> recipients = DataAccess.MailInfo.recipients;

                    if (mailer == null)
                    {    
                        mailer = new Automailer(interval,client,recipients);
                    }
                    else
                    {
                        mailer.AccessMailInterval = interval;
                        mailer.AccessMailClient = client;
                        mailer.AccessMailRecipients = recipients;
                    }
                    mailer.Start();
}

//contain in job/agent type definitions
public class Automailer
    {
        private System.Timers.Timer mailerthread;

        public bool IsRunning { get; private set; }
        private bool sending { get; set; }

        public double AccessMailInterval
        {
            get
            {
                return mailerthread.Interval;
            }
            set
            {
                if (sending == false)
                {
                    mailerthread.Interval = AccessMailInterval;
                }
                else
                {
                    utils.cout("Cannot modify interval while mail cycle is processing.");
                }
            }
        }

        private SmtpClient MailClient;
        public SmtpClient AccessMailClient { 
            get {
                    return MailClient;
        }
            set
            {
                if (sending == false)
                {
                    MailClient = AccessMailClient;
                }
                else
                {
                    utils.cout("Cannot modify mail client while mail cycle is processing.");
                }
            }
        }

        private List<MailAddress> MailRecipients;
        public List<MailAddress> AccessMailRecipients { 
            get {
                    return MailRecipients;
        } 
            set {
                if (sending == false)
                {
                    MailRecipients = AccessMailRecipients;
                }
                else
                {
                    utils.cout("Cannot modify mail recipients while mail cycle is processing.");
                }

            } 
        }

        /// Must be manually started / stopped.
        public Automailer(double interval,SmtpClient client,List<MailAddress> recipients)
        {
            try
            {
                MailClient = client;
                MailRecipients = recipients;

                sending = false;
                mailerthread = new System.Timers.Timer(interval);
                mailerthread.Elapsed += new System.Timers.ElapsedEventHandler(SendMail);
            }
            catch (Exception ex)
            {
                utils.cout("Error sending email. Details:" + "\r\n" + ex.ToString());
            }
        }

        public void Start() {
            if (IsRunning)
            {
                utils.cout("Automailer agent already running.");
            }
            else
            {
                utils.cout("Starting automailer agent...");
                mailerthread.Start();
                IsRunning = true;
                utils.cout("Initialized.");
            }
        }
        
        public void Stop() {
            if (IsRunning)
            {
                utils.cout("Sending halt and exit command to automailer agent...");
                mailerthread.Stop();
                utils.cout("Stopped.");

                if (sending)
                {
                    utils.cout("Warning: automailer stopped during mail cycle.");
                }
            }
            else
            {
                utils.cout("Automailer agent is not running.");
            }
            
        }

        /// Fires on timer or can be called manually.
        public void SendMail(object source, System.Timers.ElapsedEventArgs e)
        {
            if (sending == false)
            {
                sending = true;
                int successcount = 0;
                try
                {
                    utils.cout("Starting mail cycle...");
                    int rollingcount = 0;
                    foreach (MailAddress address in MailRecipients)
                    {
                        rollingcount += 1;
                        utils.cout(String.Format("Sending email {0} of {1}.", rollingcount, MailRecipients.Count));

                        MailMessage message = new MailMessage();

                        try
                        {
                            message.Body = DataAccess.MailInfo.body;
                            message.IsBodyHtml = DataAccess.MailInfo.ishtml;
                        }
                        catch (Exception ex4)
                        {
                            utils.cout("Could not populate body from template. Message will be sent using defaults. Details:" + "\r\n" + ex4.ToString());
                            message.IsBodyHtml = true;
                            message.Body = String.Format("Thank-you! <br /><br /> \r\n \r\n - {0}",DataAccess.LicenseInfo.company);
                        }

                        try
                        {
                            message.To.Add(address);

                            try
                            {
                                MailClient.Send(message);
                                utils.cout(String.Format("Email sent to {0}.",address.Address));
                                successcount += 1;
                                //async can be used alternatively
                                //MailClient.SendAsync(message,)
                                //MailClient.SendCompleted += new SendCompletedEventHandler(SendMailComplete);
                            }
                            catch (Exception ex2)
                            {
                                utils.cout(String.Format("Could not send to {0}. Details:", address.Address) + "\r\n" + ex2.ToString());
                            }
                        }
                        catch (Exception ex3)
                        {
                            utils.cout(String.Format("Unable to add address {0} to the list. Details:", address.Address) + "\r\n" + ex3.ToString());
                        }

                        message.Dispose();
                    }
                   
                }
                catch (Exception ex)
                {
                    utils.cout("Error sending email. Details:" + "\r\n" + ex.ToString());
                }

                utils.cout(String.Format("Mail cycle complete. {0} sent successful, {1} failed to send.", successcount.ToString(), (MailRecipients.Count - successcount).ToString()));

                sending = false;
            }
        }

        //not used, can be used to engage on asyc calls
        private void SendMailComplete(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            
        }
    }

//data layer
public static class DataAccess {
public static class Mailinfo {
//contains static methods and properties for retrieving data from database or file, etc
}
}

//in a generic lib
public static class utils {
public static void cout(string outputtext) {
//output text to console, window, form, etc
}
}
Advertisement

Get Current URL in Javascript

JS (JQuery):

$(document).ready(function() {
    $(location).attr('href');
});

JS (standard):

function CurrentURL() {
    var currenturl = window.location.pathname;
return currenturl;
}

JQuery and Partial Postbacks

I recently came across an issue where JQuery bindings no longer functioned after a partial postback and stumbled upon some code that was helpful in most cases.

Javascript (JQuery):

Sys.Application.add_load(startJQuery); 

startJQuery() { 
//do JQ here
}

And alternatively..

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function(){});

This code will not always work however, as was the case in my particular scenario, so I resolved using an alternate method.

RegisterStartupScript is great functionality, and can be useful for loading javascript dynamically on an as-needed basis.

The example below, based on prior code selects the correct JS file to use, then loads it using the registerstartupscript function. This is all within a code block which calls an update panel

C#:


int scriptnumber = 1;
string FilePath = String.Format("~/Scripts/Script_{0}.js",scriptnumber.ToString());
System.IO.StreamReader sr = new System.IO.StreamReader(HttpContext.Current.Server.MapPath(FilePath));
            jqueryfileoutput = sr.ReadToEnd();

            upnlBodyContent.Update();

            ScriptManager.RegisterStartupScript(this, this.GetType(), "scriptname",
                "<script type=\"text/javascript\">" + jqueryfileoutput.ToString().Trim() + "</script>", false);

Using jQuery and ScriptManager to update dynamic page elements

I recently came across a situation where an element on the page was not updating dynamically after post backs.

It was quick and easy to add an update panel and the necessary logic to use the built in asp .Net ajax callbacks.

I simply added an update panel around the code that needed to be updated, and an invisible button within the update panel to trigger the postback. I then called this button using javascript click() event of the button.

However, this caused some conflicts with some other pre-existing ajax code and modal dialogs, so I turned to another solution.

Rather than re-work these controls and methods which were already functioning correctly and extensively implemented, I added a small snippet of code on page load for the content pages which I wanted to trigger a force reload. This did the trick.

VB:


ScriptManager.RegisterStartupScript(Me, Me.GetType(), "loadminicart", "$('#minicart').load('" & _
strRootSiteURL & "minicartdata.aspx');", False)

C#:


ScriptManager.RegisterStartupScript(this, this.GetType(), "loadminicart", "$('#minicart').load('" + strRootSiteURL + "minicartdata.aspx');", false);

“minicartdata.aspx” is a dynamic page with no masterpage, header, footer or body HTML tags specified – only div’s and content elements.

“minicart” is the id of the div which minicartdata.aspx will be loaded into.

In my specific instance, there were only two pages which I needed to force the minicart content to reload. As a requirement, I needed the reload to occur after an operation on these pages, so since there were only two pages, it was easy to specify this code in both.

In some cases, you may want to be able to easily trigger a refresh from code behind without having to place the above code in every page. For this I recommend simply creating a global function and placing the snippet above, then calling the global function from anywhere needed.

Another, more object oriented approach is to create your own type which inherits page, and use this as the base type for all your content pages. You could then place a function in your new type which contains the snippet above. This effectively has the same end result as using a global function.

Hope this information can be as useful to someone else as I found it to be. 😉

Get Current Page Name in ASP .NET

The code snippet below is a quick, easy to use function which allows you to get the current active page in an asp .net website/application.

There are similar functions for getting header information about a page, however, after some research I found the direct info I was looking for was much easier to retrieve using this method.

Enoy. 😉

VB .NET

Public Function GetCurrentPageName() As String
	Dim strPath As String = System.Web.HttpContext.Current.Request.Url.AbsolutePath
	Dim oInfo As New System.IO.FileInfo(strPath)
	Dim strPageName As String = oInfo.strPageName 
	Return strPageName
End Function

C#

public string GetCurrentPageName() 
{ 
    string spath = System.Web.HttpContext.Current.Request.Url.AbsolutePath; 
    System.IO.FileInfo oInfo = new System.IO.FileInfo(spath); 
    string spagename = oInfo.Name;
    return spagename;
}