Ready to send email in Amazon SES? Let’s Go!

First, consult with AWS and get your credentials:

http://docs.aws.amazon.com/ses/latest/DeveloperGuide/using-credentials.html
and
http://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-using-smtp-net.html

Secondly, let’s make a more easily updatable emailSettings section (encrypt it later, see here if you need help):

  <appSettings>
    <add key="MailFrom" value="donotreply@youremaildomain.com"/>
    <add key="MailTo" value="whoareyousendingto@theiremaildomain.com"/>
    <add key="MailHost" value="	email-smtp.youramazonseshost.com"/>
    <add key="MailPort" value="587"/>
    <add key="MailServerUserName" value="awsSESusername"/>
    <add key="MailServerPassword" value="awsSESpassword"/>
  </appSettings>

Then, include the reference:

	using System.Net.Mail;		

Finally, write your method:

	public static void sendEmail(string to, string from, string subject, string body)
	{
		try
		{
			// Initialize client and message
			using (SmtpClient mailclient = new SmtpClient(ConfigurationManager.AppSettings["MailHost"].ToString(), Convert.ToInt32(ConfigurationManager.AppSettings["MailPort"])))
			{
				// Create message
				mailclient.UseDefaultCredentials = false;
				mailclient.EnableSsl = true;
				mailclient.Credentials = new System.Net.NetworkCredential(ConfigurationManager.AppSettings["MailServerUserName"].ToString(), ConfigurationManager.AppSettings["MailServerPassword"].ToString());
				MailMessage message = new MailMessage(from, to);
				message.Subject = subject;
				message.Body = body;
				message.IsBodyHtml = true;
				mailclient.Send(message);
			}
		}
		catch (SmtpException ex)
		{                
			// Service was not available to send message keep trying
			if (ex.StatusCode.Equals(SmtpStatusCode.ServiceNotAvailable))
			{
				sendEmail(to, from, subject, body);
			}
		}
	}

Great! Now you can call it and send an email

string htmlBody = "<b>Hi! It's my message</b>";
sendEmail(ConfigurationManager.AppSettings["MailTo"].ToString(), ConfigurationManager.AppSettings["MailFrom"].ToString(), "Your Email Subject", htmlBody); 

You can always put whoever and whatever when you call the method using To, From, Subject and Body.

Enjoy! Questions are welcome.

Exporting asp:GridView Results To A Microsoft Excel Spreadsheet in VB/C#

I have received this requirement on more than one occasion so I thought it would benefit others if I posted these snippets. So here we go, let’s export a gridview as an excel file.

For starters let’s add a couple controls to the front-end aspx page:

 
<asp:Button ID="btnExport" runat="server" Text="Export Results To Excel" /> &amp;nbsp;&amp;nbsp;<br /><br />

<asp:GridView ID="grdSearch" runat="server" CellPadding="3" BackColor="White" BorderColor="#CCCCCC" BorderStyle="None" BorderWidth="1px">
 <FooterStyle BackColor="White" ForeColor="#000066" />
 <HeaderStyle BackColor="#006699" Font-Bold="True" ForeColor="White" />
 <PagerStyle BackColor="White" ForeColor="#000066" HorizontalAlign="Left" />
 <RowStyle ForeColor="#000066" />
 <SelectedRowStyle BackColor="#669999" Font-Bold="True" ForeColor="White" />
 <SortedAscendingCellStyle BackColor="#F1F1F1" />
 <SortedAscendingHeaderStyle BackColor="#007DBB" />
 <SortedDescendingCellStyle BackColor="#CAC9C9" />
 <SortedDescendingHeaderStyle BackColor="#00547E" />
 </asp:GridView>

I’m going to assume you know how to wire in your gridview to return results.

With that assumption in place here is the click event that performs the export (in VB):

You will need: Imports System.IO

Protected Sub btnExport_Click(sender As Object, e As EventArgs) Handles btnExport.Click
        Try
            Response.Clear()
            Response.Buffer = True
            Response.ClearContent()
            Response.ClearHeaders()
            Response.Charset = ""
            Dim FileName As String = "filename" + DateTime.Now + ".xls"
            Dim strwritter As New StringWriter()
            Dim htmltextwrtter As New HtmlTextWriter(strwritter)
            Response.Cache.SetCacheability(HttpCacheability.NoCache)
            Response.ContentType = "application/vnd.ms-excel"
            Response.AddHeader("Content-Disposition", Convert.ToString("attachment;filename=") &amp; FileName)
            grdSearch.GridLines = GridLines.Both
            grdSearch.HeaderStyle.Font.Bold = True
            grdSearch.RenderControl(htmltextwrtter)
            Response.Write(strwritter.ToString())
            Response.[End]()
        Catch ex As Exception
            ' Do something important here if you expect strange results
        End Try
    End Sub

Now in C#:

You will need: using System.IO;

try {
	Response.Clear();
	Response.Buffer = true;
	Response.ClearContent();
	Response.ClearHeaders();
	Response.Charset = "";
	string FileName = "filename" + DateTime.Now + ".xls";
	StringWriter strwritter = new StringWriter();
	HtmlTextWriter htmltextwrtter = new HtmlTextWriter(strwritter);
	Response.Cache.SetCacheability(HttpCacheability.NoCache);
	Response.ContentType = "application/vnd.ms-excel";
	Response.AddHeader("Content-Disposition", Convert.ToString("attachment;filename=") + FileName);
	grdSearch.GridLines = GridLines.Both;
	grdSearch.HeaderStyle.Font.Bold = true;
	grdSearch.RenderControl(htmltextwrtter);
	Response.Write(strwritter.ToString());
	Response.End();
} catch (Exception ex) {
	// Do something important here if you expect strange results
}

I realize you may not need some of the formatting that I used in this example so remove the Gridview related property assignments in the export snippet. Also, depending on how you format your gridview on the aspx page will dictate some of the formatting you have on the spreadsheet. Hope this helps, questions are welcome.

Stuck On “Cannot Load php7apache2_4.dll into server: The specified module could not be found”? Try this…

I recently just performed a PHP upgrade from 5.6.15 to 7.0.1. After doing everything I had suspected I needed to do I received this error in my logs when trying to start Apache:

httpd.exe: Syntax error on line 569 of C:/Program Files (x86)/Apache Software Foundation/Apache24/conf/httpd.conf: Cannot load C:/Program Files (x86)/PHP.7.0.1/php7apache2_4.dll into server: The specified module could not be found.

Here is what I had in that block, bolding the item in question:

LoadModule php7_module "C:/Program Files (x86)/PHP.7.0.1/php7apache2_4.dll"
AddHandler application/x-httpd-php .php
PHPIniDir "C:/Program Files (x86)/PHP.7.0.1/"

Huh??? I checked and double checked and that file was there. After about 2 hours of scratching my head I then found a forum post that clicked for me. You may not be recognizing the .dll file because it has a dependency on the Visual C++ Redistributable for Visual Studio 2015. Once I downloaded and installed the exe files (located here) then after another restart I started seeing my pages again. Hope it helps.

Use No Captcha reCaptcha In ASP.Net Web Application Form Page With C#, JSON and JavaScript

Users are getting more and more tired of interpreting images with random numbers or letters that take 2-3 tries to get. Google has a new release of the reCaptcha to include a  “No Captcha” feature. You can read about that more here. Here are the steps that I took to include this newer version into a ASP.Net web application.

  • Obtain a google account and sign up for reCaptcha 
  • Create a Visual Studio C# based web forms application and create a page where you will have your reCaptcha to live
  • Download Json via NuGet (instructions are here)
  • Once you have reCaptcha information be sure to insert the following in the head section of your web page:
 
<script src="https://www.google.com/recaptcha/api.js" type="text/javascript"></script> 
  • Then place in your web page where you want the reCaptcha to live. Remember to replace “yoursitekey” with the Google reCaptcha site key:
<div class="g-recaptcha" data-sitekey="yoursitekey"></div>

 

  • Create a class in your web application called ReCaptchaClass (credit for class and credit for proxy) and put the following code into the class. Remember to replace “yoursecretkeygoeshere” with the Google reCaptcha secret key:
using Newtonsoft.Json;
    public class ReCaptchaClass
    {
        public static string Validate(string EncodedResponse)
        {
            var client = new System.Net.WebClient();
            IWebProxy defaultWebProxy = WebRequest.DefaultWebProxy;
            defaultWebProxy.Credentials = CredentialCache.DefaultCredentials;
            client.Proxy = defaultWebProxy;
            string PrivateKey = "yoursecretkeygoeshere";
            var GoogleReply = client.DownloadString(string.Format("https://www.google.com/recaptcha/api/siteverify?secret={0}&amp;response={1}", PrivateKey, EncodedResponse));
            var captchaResponse = Newtonsoft.Json.JsonConvert.DeserializeObject(GoogleReply);
            return captchaResponse.Success;
        }
        [JsonProperty("success")]
        public string Success
        {
            get { return m_Success; }
            set { m_Success = value; }
        }

        private string m_Success;
        [JsonProperty("error-codes")]
        public List ErrorCodes
        {
            get { return m_ErrorCodes; }
            set { m_ErrorCodes = value; }
        }
        private List m_ErrorCodes;
    }
  • Once the class is created place the following snippet in the code behind of your page (likely in a button click event of some kind):
string EncodedResponse = Request.Form["g-Recaptcha-Response"];
bool IsCaptchaValid = (ReCaptchaClass.Validate(EncodedResponse) == "True" ? true : false);

if (IsCaptchaValid) {
    //Valid Request
}

That’s it! Easy enough, right? I hope it helps. Questions are always welcome.

Write a JavaScript/HTML Form Submit Post From C# APSX Code Behind

There may be a case where you are taking information from a form and need to post it to a web site somewhere else. One quick method of performing that post is to execute it from the code behind using C# (via context.response) and JavaScript. This is a scaled down example of a case where I was submitting a POST from the code behind of a web part control:

A couple things to note:

  • You can add as many fields as you wish to post, I am only using two
  • You can use string.Format to get C# variables to put directly in the POST
protected string value1;
protected string value2;

value1 = "something";
value2 = "something else";

Context.Response.Write("&lt;form name='Form1' id='Form1' method='post' action='https://www.mywebsitetopostto.com/example'&gt;");
Context.Response.Write("&lt;input type='hidden' name='__VIEWSTATE' id='__VIEWSTATE' value='' /&gt;");
Context.Response.Write(string.Format("&lt;input type='hidden' name='txtValue1' id='txtValue1' runat='server' value='{0}' /&gt;", value1));
Context.Response.Write(string.Format("&lt;input type='hidden' name='txtValue2' id='txtValue2' runat='server' value='{0}' /&gt;", value2));
Context.Response.Write("&lt;/form&gt;");
Context.Response.Write("document.Form1.submit();");
Context.Response.Flush();
Context.Response.End();

Ideally you would use this in a case where you are posting content and the page you are posting to will process and serve something after the form that receives your post processes what you sent. Please do not use this snippet and blame me for a blank page 🙂

Convert A Links List To A DropDownList By A Web Part In SharePoint 2013 (C#)

So I have been enjoying the benefit of Mike Smith’s article for a while now (http://techtrainingnotes.blogspot.com/2010/12/sharepoint-convert-links-list-to.html). A client I did a project for was wanting to carry this functionality forward to 2013. The problem: this method didn’t work in 2013.

So I took a programmatic approach to lose the JavaScript dependency. It also will sort the dropdown names by what you type as the description by using the sortedlist in the code behind. It’s fairly simple, here’s what I did:

  • Created a links list and populated some URLs and Descriptions (!!! You need both for below to work, otherwise remove the description dependency in my code !!!)
  • Create a SharePoint 2013 Visual Web Part project
  • Add the dropdownlist control to the control

In the .ascx control I have:

<asp:DropDownList ID="linkDropDown" runat="server" Font-Names="Arial" Font-Size="10pt"
Width="300px" OnSelectedIndexChanged="linkDropDown_SelectedIndexChanged" AutoPostBack="true" EnableViewState="true">
<asp:ListItem Text="Link to ..." Value="#"></asp:ListItem>
</asp:DropDownList>
  • Add the code to the code behind of the control

Now the code behind, here’s my using statements:

using System;
using System.ComponentModel;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using System.Collections;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

and here is what I have in the Page_Load and the SelectedIndexChanged event

protected void linkDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
Context.Response.Redirect(linkDropDown.SelectedValue.ToString());
}

protected void Page_Load(object sender, EventArgs e)
{
SortedList sortedLists = new SortedList();

using (SPSite siteCol = new SPSite("http://mysharepoint2013site/"))
{
using (SPWeb web = siteCol.RootWeb)
{
SPList list = web.GetList("/Lists/NameOfLinksList");
SPListItemCollection items = list.GetItems();

foreach (SPListItem it in items)
{
SPFieldUrlValue fieldValue = new SPFieldUrlValue(it["URL"].ToString());
string description = fieldValue.Description;
string url = fieldValue.Url;
sortedLists.Add(description, url);
}
}

IDictionaryEnumerator enumerator = sortedLists.GetEnumerator();
while (enumerator.MoveNext())
{
ListItem listitem = new ListItem();
listitem.Text = enumerator.Key.ToString();
listitem.Value = enumerator.Value.ToString();
linkDropDown.Items.Add(new ListItem(listitem.Text.ToString(), listitem.Value.ToString()));
}
}

Deploy and enjoy!

Sluggish Sitecore Development Environment? Here’s An Easy Method To Disable Sitecore Analytics

When you install a new 8.0 instance of Sitecore you will find the site can be laggy and sluggish to load. To speed up your dev environment I would recommend this easy fix.

First create a folder called z in your app config sitecore path: C:\inetpub\wwwroot\yoursitecore\Website\App_Config\z

Then, create a file called zwoa.config and paste the following in:

<configuration xmlns:patch="<a href="http://www.sitecore.net/xmlconfig/">http://www.sitecore.net/xmlconfig/</a>">
 <sitecore>
 <pipelines>
 <initialize>
 <processor type="Sitecore.Pipelines.Initialize.PrecompileSpeakViews, Sitecore.Speak.Clientpro" >
 <patch:delete />
 </processor>
 <processor type="Sitecore.ContentTesting.Pipelines.Initialize.RegisterContentTestingCommandRoute, Sitecore.ContentTesting" >
 <patch:delete />
 </processor>
 <processor type="Sitecore.Pipelines.Initialize.PrecompileSpeakViews, Sitecore.Speak.Client" use="ContentTesting" >
 <patch:delete />
 </processor>
 </initialize>
 <mvc.renderPageExtenders>
 <processor patch:after="processor[@type='Sitecore.Mvc.ExperienceEditor.Pipelines.RenderPageExtenders.RenderExtendersContainer, Sitecore.Mvc.ExperienceEditor']" type="Sitecore.Mvc.ExperienceEditor.Pipelines.RenderPageExtenders.RenderPageEditorExtender, Sitecore.Mvc.ExperienceEditor"></processor>
 <processor patch:after="processor[@type='Sitecore.Mvc.ExperienceEditor.Pipelines.RenderPageExtenders.RenderExtendersContainer, Sitecore.Mvc.ExperienceEditor']" type="Sitecore.Mvc.ExperienceEditor.Pipelines.RenderPageExtenders.RenderPreviewExtender, Sitecore.Mvc.ExperienceEditor"></processor>
 <processor patch:after="processor[@type='Sitecore.Mvc.ExperienceEditor.Pipelines.RenderPageExtenders.RenderExtendersContainer, Sitecore.Mvc.ExperienceEditor']" type="Sitecore.Mvc.ExperienceEditor.Pipelines.RenderPageExtenders.RenderDebugExtender, Sitecore.Mvc.ExperienceEditor"></processor>
 <processor type=""Sitecore.Mvc.ExperienceEditor.Pipelines.RenderPageExtenders.SpeakRibbon.RenderPageEditorSpeakExtender, Sitecore.Mvc.ExperienceEditor" >
 <patch:delete />
 </processor>
 </mvc.renderPageExtenders>
 </pipelines>
 <settings>
 <setting name="Analytics.Enabled" > <patch:attribute name="value" value="false" />
 </setting>
 </settings>
 </sitecore>
 </configuration>

Refresh your Sitecore in a web browser and watch it go!