SMS and MMS Notifications with C# and ASP.NET MVC

January 10, 2017
Written by
Jose Oliveros
Contributor
Opinions expressed by Twilio contributors are their own
Reviewed by
Kat King
Twilion
Paul Kamp
Twilion
Samuel Mendes
Contributor
Opinions expressed by Twilio contributors are their own
Hector Ortega
Contributor
Opinions expressed by Twilio contributors are their own

server-notifications-csharp-aspnet

Need to hail your server administrators when something goes wrong with your servers?  We've got you covered - today we'll cover adding notifications on server exceptions to your C# ASP.NET MVC application.  We'll cover all the key plumbing to make it happen!

Why wait? Click the button below to move to the next step of the tutorial.

List The Server Administrators - and Whomever Else to Contact

Here we create a list of administrators who should be notified if a server error occurs. The only essential piece of data we need is a PhoneNumber for each administrator.

Editor: this is a migrated tutorial. Find the original code at https://github.com/TwilioDevEd/server-notifications-csharp/

Name,PhoneNumber
Bob,+12025550135
Alice,+12025550181

With this list in hand, let's configure the Twilio REST client and see how we use it to send a notification on application exceptions.

Configure the Twilio C# REST Client

To send a message, we'll need to initialize the Twilio C# Helper Library. This requires reading our TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN defined at ServerNotifications.Web/Web.config

using System.Collections.Generic;
using System;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
using Twilio.Clients;
using System.Threading.Tasks;

namespace ServerNotifications.Web.Domain.Twilio
{
    public interface IRestClient
    {
        Task<MessageResource> SendMessage(string from, string to, string body, List<Uri> mediaUrl);
    }

    public class RestClient : IRestClient
    {
        private readonly ITwilioRestClient _client;

        public RestClient()
        {
            _client = new TwilioRestClient(
                Credentials.TwilioAccountSid,
                Credentials.TwilioAuthToken
            );
        }

        public RestClient(ITwilioRestClient client)
        {
            _client = client;
        }

        public async Task<MessageResource> SendMessage(string from, string to, string body, List<Uri> mediaUrl)
        {
            var toPhoneNumber = new PhoneNumber(to);
            return await MessageResource.CreateAsync(
                toPhoneNumber,
                from: new PhoneNumber(from),
                body: body,
                mediaUrl: mediaUrl,
                client: _client);
        }
    }
}

Now that we have our Twilio Client setup, let's see how to handle exceptions.

Handle All C# Application Exceptions

In an ASP.NET MVC application, we can handle errors at the application level. Note that any other exceptions caught in the code (using your own try/catch blocks) are not being captured and processed here.

using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using ServerNotifications.Web.Domain;
using ServerNotifications.Web.Models.Repository;

namespace ServerNotifications.Web
{
    public class MvcApplication : HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }

        protected async void Application_Error(object sender, EventArgs e)
        {
            var exception = Server.GetLastError();
            var message = string.Format("[This is a test] ALERT!" +
                "It appears the server is having issues." +
                "Exception: {0}. Go to: http://newrelic.com for more details.", exception.Message);

            var notifier = new Notifier(new AdministratorsRepository());
            await notifier.SendMessagesAsync(message);
        }
    }
}

Any uncaught exception will be handled here. Let's see how we can use this exception to hail our administrator list.

Creating a Custom Alert Message

Here we create an alert message to send out via text message. You might also decide to include a picture with your alert message... maybe a screenshot of the application when the crash happened?  A meme to calm everyone down?

using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using ServerNotifications.Web.Domain;
using ServerNotifications.Web.Models.Repository;

namespace ServerNotifications.Web
{
    public class MvcApplication : HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }

        protected async void Application_Error(object sender, EventArgs e)
        {
            var exception = Server.GetLastError();
            var message = string.Format("[This is a test] ALERT!" +
                "It appears the server is having issues." +
                "Exception: {0}. Go to: http://newrelic.com for more details.", exception.Message);

            var notifier = new Notifier(new AdministratorsRepository());
            await notifier.SendMessagesAsync(message);
        }
    }
}

The error handling is setup to capture application wide errors and forward them to all the lucky administrators.

Let’s take a closer look at how the Notifier forwards these errors to the administrators.

Read the Administrators from the CSV File

With CSVReader, we can open and parse our list of administrators from our CSV file. We use the method GetRecords to read all the records.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using CsvHelper;

namespace ServerNotifications.Web.Models.Repository
{
    public interface IAdministratorsRepository
    {
        IList<Administrator> All();
    }

    public class AdministratorsRepository : IAdministratorsRepository
    {
        public IList<Administrator> All()
        {
            using (var streamReader = new StreamReader(HttpContext.Current.Server.MapPath("~/App_Data/administrators.csv")))
            {
                var reader = new CsvReader(streamReader);
                return reader.GetRecords<Administrator>().ToList();
            }
        }
    }
}

We've seen how to load a list of administrators from a file. Now let's see how to send a message to each of them.

Send a Text Message Blast

There are the three parameters needed to send an SMS using the Twilio REST API: From, To, and Body.

US and Canadian phone numbers can also send an image with the message.  (Other countries can as well, but a shortened URL pointing to the image will be appended).

using System.Collections.Generic;
using System;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
using Twilio.Clients;
using System.Threading.Tasks;

namespace ServerNotifications.Web.Domain.Twilio
{
    public interface IRestClient
    {
        Task<MessageResource> SendMessage(string from, string to, string body, List<Uri> mediaUrl);
    }

    public class RestClient : IRestClient
    {
        private readonly ITwilioRestClient _client;

        public RestClient()
        {
            _client = new TwilioRestClient(
                Credentials.TwilioAccountSid,
                Credentials.TwilioAuthToken
            );
        }

        public RestClient(ITwilioRestClient client)
        {
            _client = client;
        }

        public async Task<MessageResource> SendMessage(string from, string to, string body, List<Uri> mediaUrl)
        {
            var toPhoneNumber = new PhoneNumber(to);
            return await MessageResource.CreateAsync(
                toPhoneNumber,
                from: new PhoneNumber(from),
                body: body,
                mediaUrl: mediaUrl,
                client: _client);
        }
    }
}

That's it! We've just implemented an automated server notification system that can send out C# ASP.NET MVC server alerts if anything goes wrong.

Let's see some other fine features you can add to your application, next.

Where to Next?

Twilio and C# are great together!  Here are two more ideas for useful features:

Two-Factor Authentication

Increase the security of your login system by verifying a user's mobile phone in addition to their password.

Appointment Reminders

Send your customers a text message when they have an upcoming appointment, this tutorial shows you how to do it from a background job.

Did this Help?

Thanks for checking out this tutorial! Tweet us @twilio to let us know what you've built... and what you're building.