How to Send Asp.net Core Email With Sendgrid API

I remember a few months back I wrote a quick post on how I managed to send email using MailKit in one of the projects I was on. Well, as you know there are many different services out there making thing simple to send e-mails from application. Since, I like to test things out first before actually implementing it in a real application, I decided to give Sendgrid a try. Therefore, in this post I will walk you through the steps I took to send emails using the Sendgrid API. Are you ready? Let’s do it!!!

I need to create a brand new application for this post. I am currently using Visual Studio 2019 for this project but feel free to use any other version you may have.

Project Setup

  • First, create a new ASP.NET Core application with the following name “SendgridEmailInAspNetCore”
    “File” –> “New” –> “Project”
    Create new project in Visual Studio 2019
  • A “New Project” dialog will open where you can configure your project such as giving a name and location.
    Configure new project in Visual Studio 2019
  • Make sure the project build properly.
    Now that we have the project setup we need to add the Sendgrid Package using the NuGet Package manager tool.
    Open NuGet free and open-source package manager
    Search and Find the Sendgrid Library in NuGet

Add services folder

  • Let’s add a new folder to the project and called it “Services”. This folder will contain the interface that will be used to send the e-mail.
  • Next we need to add the interface called “IEmailSender.cs”
        using System.Collections.Generic;
        using System.Threading.Tasks;
    
         namespace SendgridEmailInAspNetCore.Services
         {
           public interface IEmailSender
           {
              Task SendEmailAsync(List emails, string subject, string message);
           }
         }
    
    
  • Add an Implementation class called “EmailSender.cs.
    using Microsoft.Extensions.Options;
    using SendGrid;
    using SendGrid.Helpers.Mail;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    namespace SendgridEmailInAspNetCore.Services
    {
        public class EmailSender:IEmailSender
        {
            public EmailSender(IOptions optionsAccessor)
            {
                Options = optionsAccessor.Value;
            }
    
            public EmailAuthOptions Options { get; } //set only via Secret Manager
    
            public Task SendEmailAsync(List emails, string subject, string message)
            {
                // return Execute(Options.SendGridKey, subject, message, email);//to try out later
                return Execute(Environment.GetEnvironmentVariable("SENDEMAILDEMO_ENVIRONMENT_SENDGRID_KEY"), subject, message, emails);
            }
    
            public Task Execute(string apiKey, string subject, string message, List emails)
            {
                var client = new SendGridClient(apiKey);
                var msg = new SendGridMessage()
                {
                    From = new EmailAddress("noreply@domain.com", "Bekenty Jean Baptiste"),
                    Subject = subject,
                    PlainTextContent = message,
                    HtmlContent = message
                };
    
                foreach (var email in emails)
                {
                    msg.AddTo(new EmailAddress(email));
                }
    
                Task response = client.SendEmailAsync(msg);
                return response;
            }
        }
    }
    
  • Next, we’ll add a new class in that same services folder called “EmailAuthOptions.cs” This will only contain the email secrets from sendgrid.

    namespace SendgridEmailInAspNetCore.Services
    {
        public class EmailAuthOptions
        {
            public string SendGridUser { get; set; }
            public string SendGridKey { get; set; }
        }
    }
    

Register the services

  • Find the Startup.cs file, and the ConfigureServices method. Then, add the following two lines.

            services.Configure(Configuration);
            services.AddTransient<IEmailSender, EmailSender>();
    

Setup the Environment Variable

  • Right click on the project and go to the properties. Then, click the debug tab and add a new environment variable with the following key “SENDEMAILDEMO_ENVIRONMENT_SENDGRID_KEY”. set the value to what you have gotten from Sendgrid.
    Way to configure sendgrid api key

Build E-mail Interace to capture message from user

  • Let’s add a new model called “EmailModel.cs” with the following properties.
    using System.ComponentModel.DataAnnotations;
    
    namespace SendgridEmailInAspNetCore.Models
    {
        public class EmailModel
        {
            [Required]
            [EmailAddress]
            public string Email { get; set; }
            [Required]
            public string Subject { get; set; }
            [Required]
            public string Message { get; set; }
        }
    }
    
  • Now, let’s add a new view called “SendEmail.cshtml” in the HOME folder with the following content.
          
    @model SendgridEmailInAspNetCore.Models.EmailModel
    
    @{
        ViewData["Title"] = "SendEmail";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    
    <h2>Send Email With Sendgrid in Asp.Net Core</h2>
    
    <hr />
    <div class="row">
        <div class="col-md-4">
            <form asp-action="SendEmail">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <div class="form-group">
                    <label asp-for="Email" class="control-label"></label>
                    <input asp-for="Email" class="form-control" />
                    <span asp-validation-for="Email" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Subject" class="control-label"></label>
                    <input asp-for="Subject" class="form-control" />
                    <span asp-validation-for="Subject" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="Message" class="control-label"></label>
                    <textarea asp-for="Message" class="form-control" cols="100"></textarea>
                    <span asp-validation-for="Message" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <input type="submit" value="Send" class="btn btn-default" />
                </div>
            </form>
        </div>
    </div>
    
    @section Scripts {
        @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    }
    
           
  • In order to be able to send the email in the controller we’ll need to inject the email service via the constructor so that we can have access to send the emails.
    start the start of the home controller we need to add the follow code snippet.

            private readonly IEmailSender _emailSender;
    
            public HomeController(IEmailSender emailSender)
            {
                _emailSender = emailSender;
            }
    
  • Now, we’re ready to add the email action methods to the controller.
            public IActionResult SendEmail()
            {
                return View();
            }
            public async Task SendEmail(EmailModel model)
            {
                if (ModelState.IsValid)
                {
                    await _emailSender.SendEmailAsync(model.Email, model.Subject, model.Message);
                }
                return View(model);
            }
    

Final Asp.net Core Email With Sendgrid

  • Now that we have everything in place let’s run the application and Test it out.
    Voila, the application loaded with no issues. Let’s navigate to the SendEmail page. Try to send email without entering anything, you should notice the validations.
    Testing the Asp.net Core Email With Sendgrid with empty inputs
  • Now, enter a valid email, subject, and a message, then click the send button.
    Send a valid email with Asp.net Core Email With Sendgrid
  • The moment of truth. Bingo, I got the e-mail in my inbox as shown below.
    Verify that the email was sent
    Verify that the email was received.

Delete Duplicate Entries In A Sql Server Table

Couple days ago I wrote a quick post demonstrating how to find duplicate records in a SQL server table. A colleague of mine read the post and asked me to show how to delete the duplicates  from the table. Therefore, I thought it would make sense I put this post together on how to delete duplicate entries in a table.

What does it take to remove duplicates from a table?

  • First, we need to validate the data to see the duplicates we are deleting.
    WITH student_cte AS (
        SELECT 
            First_Name, 
    		Last_Name,
    		Phone, 
            ROW_NUMBER() OVER(
                PARTITION BY 
                    First_Name, 
                    Last_Name, 
                    Phone
                ORDER BY 
                    First_Name, 
                    Last_Name, 
                    Phone
            ) rn
         FROM dbo.Students
    )
    select * from student_cte;
    
  • The picture below shows the records that are duplicates with the row count.
  • Now, in order to delete these record, I am going to show the best way to handle using that same CTE query above with a slight modification. I have deleted any instance with rn > 1.
    WITH student_cte AS (
        SELECT 
            First_Name, 
    		Last_Name,
    		Phone, 
            ROW_NUMBER() OVER(
                PARTITION BY 
                    First_Name, 
                    Last_Name, 
                    Phone
                ORDER BY 
                    First_Name, 
                    Last_Name, 
                    Phone
            ) rn
         FROM dbo.Students
    )
    DELETE FROM student_cte WHERE rn >1;
    
  • After running the query above, the duplicated records are now gone.

In this post, I showed how you can get rid of duplicate rows from a table in SQL Server. I hope after reading this article you will be able to use these tips. If you have questions or feedback, please share it with me. I’d like to know what you’re thinking. Please post your feedback, question, or comments about this article.

How To Get Sendgrid API Key To Send E-mails

In Sendgrid there are 3 different types of API keys that you can generate to use in your application. Which one to use depends on your requirements need. Therefore, in this post I am going to show how to setup a simple restricted API key to be used on my next e-mail demo.

Types of API KEYS Available

  • Full Access which allows the API key to access GET, PATCH, PUT, DELETE and POST endpoints for all parts of your account, excluding billing and Email Address Validation.
  • Restricted Access, this is a customized type where you can set levels of access for all parts of your account, excluding billing and Email Address Validation.
  • Billing Access which allows the API key to access billing endpoints for the account.

Steps to create new Sendgrid API Key

  • First, you need to head over to Sendgrid.com and create an account. Once you log into the application, it will take you to the dashboard area. Click on Setting on the left pane to expand it.
  • Next, click on the “API KEY” as shown below. That will open the page to allow you to create a new API KEY.
  • Now, click on the “Create API Key” button at the top right corner, it will open the 3 types of API Key to select and the different options you need to setup.
  • For the purpose of this tutorial, I am going to set this key for sending email only.
  • Once you’re done you will get a key. The API KEY generated and displayed to you just once. So be sure to copy and save it somewhere. After that only the subset key is displayed.

Last, some notes to keep in mind.

Sendgrid only allows 100 keys per account.

Once you delete a key, it can no longer be used to access SendGrid’s services.

 

How to create a simple Todo list Using Jquery

Yes, you heard it, a simple doto list using Jquery. We all know the famous hello world applications when we’re first learning a language. Now, it’s the todo app. In this post I am going to create a simple web todo application using HTML5, CSS3 and Javascript(jQuery).
You can develop this todo application in any text editor and debug in any browser. I’m using Plunker to code this due to its simplicity. You can follow along with using this Plunker demo link

Todo list Using Jquery – Project Setup

First things first, we need to set up our project. Let’s add a new index.html file to our plunker project as shown below.

  
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title></title>
    <link data-require="bootstrap@3.3.6" data-semver="4.1.3" rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" />
    <script data-require="bootstrap@3.3.6" data-semver="4.1.3" src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="jquery" data-semver="3.2.1" src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"></script>
    <script src="script.js"></script>
  </head>

  <body>
    <div class="col-md-12">
      <h1>Simple Todo Demo!</h1>
      <p>Click on row to delete newly added entry.</p>
      <div data-role="content">
        <ul class="list-group" id="taskListSection">
          <li class="list-group-item active">Todos</li>
          <li class="list-group-item ">1. Example of Existing task</li>
          <li class="list-group-item ">2. Example of Existing task</li>
        </ul>
        <br />
        <fieldset class="ui-grid-a">
          <div class="ui-block-a">
            <textarea placeholder="Enter task" id="taskInputText" cols="50" maxlength="128"></textarea>
          </div>
          <div class="ui-block-b">
            <input type="button" class="btn btn-success" value="Submit" id="taskBtn" />
          </div>
        </fieldset>
      </div>
    </div>
  </body>

</html>
  

Nothing too fancy in that html code. We have a heading and paragraph to let user know to click newly created task. Next is an unordered list group from bootstrap 4 showing 2 items to start with. Think of those two items as existing data from a database. Next is a simple textarea to allow user to type new task entry to add to the list. Last, we have a button which will fire the add operation when user click on it.

Add script to handle add and delete tasks


// Add your javascript here
$(function(){
  $("h1").animate({
    "margin-left": "100px"
  }, "slow");
  

$('#taskBtn').click(function() {
  
    var newTask = $('#taskInputText').val();

    if(newTask !== '') {
      
        var count = $("#taskListSection").children().length;
        
        $('#taskListSection').append('<li class="list-group-item deletetask bg-success">' + count + '. '+ newTask + '</li>');
       
        $('#taskInputText').val('');
        
        deleteTasks();
        
        setTimeout(function(){
          $('#taskListSection li.bg-success').removeClass('bg-success');
        },1000); 
      
    } else {
        alert('Come on, you\'re better than that');   
    }
});  
});

function deleteTasks(){
 $('.deletetask').click(function(){
    $(this).remove();
}); 

}

Again, a simple javascript file containing animation for the heading of the page upon loading. Then, I have a click event listener for when user wants to add a new task to the list. A one second delay is added after the new entry is added to the list and row is highlighted. Then, it is unhighlited after the one second is expired.
A delete function is in there as well to remove the item from the list. Very basic.

Find Duplicate Entries In A Sql Server Table Using CTE

In my last post, I showed how to find duplicate entries in a sql server table using group by which was pretty simple to pull off. I thought it would be a good idea to find the list of all the duplicate rows using CTE for those that are fan of it. We will be using the same table from our previous post on finding duplicate rows which you can read and follow.

What is CTE

A CTE which is short for Common Table Expression, is a temporary result set that you can reference within another query statement. They are used to simplify large queries.

Find duplicate rows CTE

   WITH student_cte AS(
        SELECT  First_Name, 
                Last_Name,
                Phone,  
                COUNT(*) Occurrences
        FROM dbo.students
        GROUP BY
                First_Name, 
                Last_Name,
	        Phone
       HAVING COUNT(*) > 1
  )
  SELECT	st.Id,
		st.First_Name, 
		st.Last_Name,
		st.Phone  		
 FROM dbo.students st
 INNER JOIN student_cte 
  ON student_cte.First_Name = st.First_Name
  AND student_cte.Last_Name = st.Last_Name;

Find duplicate entries result

Find duplicate entries using cte as query

Quick Way To Find Duplicate Rows In A Sql Server Table

If you are dealing with duplicate rows in a SQL server database, and you’re not sure how to find them, don’t panic. I had to deal with a similar situation recently.
Two weeks ago, I was working on a project where I had to import some data from a legacy system into a whole new table. After the data had been loaded and a report was generated with that data, we’ve noticed there were some duplicate entries. Therefore, I had to quickly figure out how to put together a quick query to find duplicate rows and removed them from the table.

In this post I will show simple steps to take in case you are facing the same issue. In order to get this post, I am going to create a new table and populate it with some seed data.

Create Database

DROP TABLE IF EXISTS Students;
CREATE TABLE Students (
    Id INT IDENTITY(1, 1), 
    First_Name  nvarchar(100), 
    Last_Name  nvarchar(100), 
    Phone nvarchar(12),
    PRIMARY KEY(id)
);

Populate the table with data

Now that we have our table added, I will proceed to populate it with some data for our demonstration.

   INSERT INTO dbo.Students
        (first_name,last_name,phone) 
   VALUES
        ('Mary','Allan','407-455-1414'),
	('John','Doe','407-445-5414'),
        ('Chirac','Paul','407-455-1814'),
	('John','Doe','407-445-5414'),
        ('Mela','Jil','407-787-6767'),
	('John','Doe','407-445-5414'),
        ('Mary','Allan','407-455-1414'),
	('John','Doe','407-445-5414'),
        ('Mary','Allan','407-455-1414'),
	('Chris','Tai','407-555-7777'),
	('Albert','Allan','321-455-9977'),
	('Jean','Doe','407-445-5414');

Ensure the data was inserted properly

Okay, we have the data we need in the table, let’s run a quick query to see if it match our criteria, in order words have some duplicates. Let’s run a simple select statement to retrieve the full data-set in the the table.

   SELECT Id, First_Name, Last_Name,Phone 
   FROM dbo.students
   ORDER BY First_Name, Last_Name desc;

Query result to find duplicate rows in table

Find duplicate rows in the table

As a matter of fact, there are many ways to find and return the duplicates. I ended up using group by to get my result, If you end up using some other method, please share it in the comment below.

 SELECT  First_Name, 
          Last_Name,
          Phone,  
          COUNT(*) Occurrences
  FROM dbo.students
  GROUP BY
    First_Name, 
    Last_Name,
    Phone
  HAVING 
    COUNT(*) > 1;


Last, below you can see the result of the duplicated rows found and the number of time.
Find duplicate rows in sql server table

ObjectDisposedException: Cannot access a disposed object

I am working on this application using In-Memory Cache feature in Asp.Net Core and got this error below.
I have dealt with this error multiple times before and it can be hard to debug sometimes because the cause could be different every time. In this one, I was caching some data that way I did not have to keep going to the database every request. To keep this short, I am going to show the piece of code that was causing the issue below.

Problem

As you can see the category object in code below was an IEnumerable type.


viewModelInfo.Categories = _repository.GetAllCategories().Where(x => x.Businesses.Count > 0).Select(x => new SelectListItem
{
Value = x.Name.ToString(),
Text = x.Name
});

“ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: ‘ApplicationDbContext’.”

Solution

Because of lazy-loading here, the query is not fully executed on the linq statement line. Therefore, adding .ToList() will force it to loop through and generate the category list needed.

Just as the error stated, I verify the ApplicationDbContext making sure Dispose() is not being called in there. Then, I place some breakpoints in the action in the controller and step through until I found the cause of my issue. Below is the final piece of code with the fix.


viewModelInfo.Categories = _repository.GetAllCategories().Where(x => x.Businesses.Count > 0).Select(x => new SelectListItem
{
Value = x.Name.ToString(),
Text = x.Name
}).ToList();

Render Razor View To String In ASP.NET Core To Send E-mail With MailKit

How To Render Razor View To String

This post is a continuation of the last post I wrote couple of days ago about How To Send E-mail In ASP.Net Core Using Mailkit.
From the last post, we were able to send a successful e-mail using MailKit with no problem. Therefore, in this post I’m going to cover how to use the RazorViewEngine to render Views, and get the string content to be used as an email template.
Since we’ll be using the same solution, let’s download it from github first and make sure it’s build properly.

Add HTML View Template

First we’ll need to add a new view called “Welcome” as shown below.
Adding the welcome view to be used in the html email template
Next, we’ll use the following html as the template for the email. If you are planning on using this template for more than one type of emails, the best thing would be to create a layout and use that with the views. But since this is just to demonstrate how to render the view into a string to send the html content we’ll keep it simple with just welcome view.


  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Demystifying Email Design</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>


<body style="margin: 0; padding: 0;">
    <table  class=" table table-hover" align="center" cellpadding="0" cellspacing="0" width="1200">
        <tr>
            <td align="center" style="padding: 40px 0 30px 0; background-color:cadetblue">
                <img src="https://pngimage.net/wp-content/uploads/2018/06/sample-logo-png-transparent-background-4.png" alt="Creating Email Magic" width="300" height="230" style="display: block; text-align:center" />
            </td>
        </tr>
        <tr>
            <td bgcolor="#ffffff">
                <table  class=" table table-hover" cellpadding="0" cellspacing="0" width="100%">
                    <tr>
                        <td width="260" valign="top">
                            <h3>How to get more customers online?</h3>
                            <p>
                                <img src="https://www.tibco.com/blog/wp-content/uploads/2014/09/shutterstock_1674174502.jpg" />
                                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget orci rhoncus, iaculis nulla vel, lobortis neque. Vivamus sodales dui eu ante aliquet, eu venenatis nisi vehicula. Donec id sollicitudin diam. Vivamus sodales odio in consectetur ultricies. Vestibulum sollicitudin id lectus quis sollicitudin. Sed lorem neque, tincidunt ut risus ac, aliquam laoreet lectus. Proin dictum risus volutpat, tincidunt elit sit amet, ornare lacus. Pellentesque et purus eu est aliquam dignissim. Donec commodo semper mauris sit amet ultricies. Cras et hendrerit elit, at interdum nulla. Ut at varius est. Aenean luctus interdum lorem ac dignissim.
                            </p>
                        </td>
                        <td style="font-size: 0; line-height: 0; border-left:solid 4px; color:#e5e4e4" width="20">
                            &nbsp;
                        </td>
                        <td width="260" valign="top">
                            <h3>How to attract new customers?</h3>
                            <p>
                                <img src="https://biz-architect.com/wp-content/uploads/2016/05/Customers.png" />
                                Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed eget orci rhoncus, iaculis nulla vel, lobortis neque. Vivamus sodales dui eu ante aliquet, eu venenatis nisi vehicula. Donec id sollicitudin diam. Vivamus sodales odio in consectetur ultricies. Vestibulum sollicitudin id lectus quis sollicitudin. Sed lorem neque, tincidunt ut risus ac, aliquam laoreet lectus. Proin dictum risus volutpat, tincidunt elit sit amet, ornare lacus. Pellentesque et purus eu est aliquam dignissim. Donec commodo semper mauris sit amet ultricies. Cras et hendrerit elit, at interdum nulla. Ut at varius est. Aenean luctus interdum lorem ac dignissim.
                            </p>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
        <tr>
            <td style="background-color:#b4b2b2">


                <table  class=" table table-hover" cellpadding="0" cellspacing="0" width="100%">
                    <tr>
                        <td style="color: #ffffff; font-family: Arial, sans-serif; font-size: 14px;">
                            &reg; Company, Copyright 2019<br />
                            <a href="#" style="color: #ffffff;"><font color="#ffffff">Unsubscribe</font></a> to this newsletter instantly
                        </td>
                        <td>
                            <table  class=" table table-hover" border="0" cellpadding="0" cellspacing="0">
                                <tr>
                                    <td>
                                        <a href="http://www.twitter.com/">
                                            <img src="http://assets.stickpng.com/thumbs/580b57fcd9996e24bc43c53e.png" alt="Twitter" width="38" height="38" style="display: block;" border="0" />
                                        </a>
                                    </td>
                                    <td style="font-size: 0; line-height: 0;" width="20">&nbsp;</td>
                                    <td>
                                        <a href="http://www.Facebook.com/">
                                            <img src="http://www.transparentpng.com/thumb/facebook-logo-png/background-facebook-logo-5.png" alt="Facebook" width="38" height="38" style="display: block;" border="0" />
                                        </a>
                                    </td>
                                </tr>
                            </table>
                        </td>
                    </tr>
                </table>
            </td>
        </tr>
    </table>
</body>
</html>

Now that we have the view in place, make sure to add the action method for that view in the home controller class as shown below.

      public IActionResult Welcome()
        {
            return View();
        }

Add helper to render view into string

  • Right click on the solution and add a new folder called “Helpers”
    Adding new helper folder for rendering html view to string
  • Next, let’s add a new class called “ViewsToStringOutputHelper.cs” and copy and paste the following code snippet into it.
    Adding new RenderRazorViewToString

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.Rendering;
    using Microsoft.AspNetCore.Mvc.ViewEngines;
    using Microsoft.AspNetCore.Mvc.ViewFeatures;
    using System.IO;
    
    namespace SendEmailInAspNetCore.Helpers
    {
        public class ViewsToStringOutputHelper
        {
            public static string RenderRazorViewToString(Controller controller, string viewName, object model)
            {
                controller.ViewData.ModelState.Clear();
                controller.ViewData.Model = model;
    
                using (var sw = new StringWriter())
                {
                    ViewEngineResult viewResult = null;
                    var engine = controller.HttpContext.RequestServices.GetService(typeof(ICompositeViewEngine)) as ICompositeViewEngine;
    
                    viewResult = engine.FindView(controller.ControllerContext, viewName, false);
    
                    var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw, new HtmlHelperOptions());
                    viewResult.View.RenderAsync(viewContext);
    
                    return sw.GetStringBuilder().ToString();
                }
            }
        }
    }
    

Render the view into a string

  • Next, let’s modified the Contact action method to use the new helper to render the view into a string.
  • First, I need a new variable for the email body string object and another flag to determine whether to use the email template or not
                        string emailBody = string.Empty;
                        bool useEmailTemplate = false;
         
  • Then, let’s add a new condition to determine if we should use the template or not as shown below
                        if (useEmailTemplate)
                        {
                            emailBody = ViewsToStringOutputHelper.RenderRazorViewToString(this, "Welcome", null);
                        }
                        else
                        {
                            emailBody = contactViewModel.Message + " Message was sent by: " + contactViewModel.Name + " E-mail: " + contactViewModel.Email;
    
                        }
                        message.Body = new TextPart(TextFormat.Html)
                        {
                            Text = emailBody
                        };      
    

Sending a new email using a rendered view to string template

  • First, we’ll send an email with the useEmailTemplate flag set to false and then another with it set to true. As you can see below, the new html template indeed used in the second email.
    Final email showing both html email template and plain text

How To Send E-mail In ASP.Net Core Using Mailkit

Send E-mail In ASP.Net Core

I am working on this new project where I need to implement a way for us to send newsletters to users on a weekly basis which requires some sort of ways to sending html content in the email.
Well, I’ve always wanted to use this library called Mailkit, so I thought it would be a good opportunity to put a quick post together and sample application to try it first before implementing it in the project. Of course, if you don’t want to use MailKit, you could always make use of the .Net Core SMTP Client.

For simplicity, I’ll keep this post short and focus solely on how to send the e-mail in .NET Core using MailKit.

  • First, create a new ASP.NET Core application with the following name “SendEmailInAspNetCore”
    “File” –>”New” –>”Project”
  • A “New Project” dialog will open. Select “.NET Core” in the left panel inside the Visual C# menu.
    Create send email project to send E-mail In ASP.Net Core
  • Next, select the Web Application (Model-View-Controller) template as shown below.
    Select the right template for the project to send E-mail In ASP.Net Core
  • Once the project is created, make sure to build it and verify that there’s no error before you proceed further.
  • Now, that we know we have a working project to start with, let’s use NuGet to add the “Mailkit” library to the project.
  • Add a new class in the Model folder called “ContactViewModel.cs. In it, we’ll have the following properties to collect the email form data.
    using System.ComponentModel.DataAnnotations;
    
    namespace SendEmailInAspNetCore.Models
    {
        public class ContactViewModel
        {
            [Required]
            [StringLength(60, MinimumLength = 5)]
            public string Name { get; set; }
            [Required]
            [EmailAddress]
            public string Email { get; set; }
            [Required]
            public string Subject { get; set; }
            [Required]
            public string Message { get; set; }
        }
    }
    
    
  • To keep this simple, let’s update the contact view with a simple contact form as shown below.
    
    @model SendEmailInAspNetCore.Models.ContactViewModel
    @{
        ViewData["Title"] = "Contact";
    }
    <h3>Send E-mail In ASP.Net Core 2.1 Using MailKit</h3>
    
    <div class="has-error" col-md-12>
        <form method="post">
            <div class="row">
                <div class="form-group col-md-4">
                    <label asp-for="Name">Name:</label>
                    <input asp-for="Name" class="form-control" />
                    <span asp-validation-for="Name" class="text-muted"></span>
                </div>
            </div>
            <div class="row">
                <div class="form-group col-md-4">
                    <label asp-for="Email">Email:</label>
                    <input asp-for="Email" class="form-control" />
                    <span asp-validation-for="Email" class="text-muted"></span>
                </div>
            </div>
            <div class="row">
                <div class="form-group col-md-4">
                    <label asp-for="Subject">Subject:</label>
                    <input asp-for="Subject" class="form-control" />
                    <span asp-validation-for="Subject" class="text-muted"></span>
                </div>
            </div>
            <div class="row">
                <div class="form-group col-md-6">
                    <label asp-for="Message">Message:</label>
                    <textarea rows="8" cols="20" asp-for="Message" class="form-control"></textarea>
                    <span asp-validation-for="Message" class="text-muted"></span>
                </div>
            </div>
            <div>
                <button type="submit" class="btn btn-success">Send Message</button>
            </div>
        </form>
    </div>
    
    
  • Let’s update the controller to add a new action to post the contact form to.
     [HttpPost]
     public IActionResult Contact(ContactViewModel contactViewModel)
     {
       if (ModelState.IsValid)
       {
         try
            {
              //instantiate a new MimeMessage
              var message = new MimeMessage();
              //Setting the To e-mail address
              message.To.Add(new MailboxAddress("E-mail Recipient Name", "recipient@domail.com"));
              //Setting the From e-mail address
              message.From.Add(new MailboxAddress("E-mail From Name", "from@domain.com"));
              //E-mail subject 
              message.Subject = contactViewModel.Subject;
              //E-mail message body
              message.Body = new TextPart(TextFormat.Html)
              {
                Text = contactViewModel.Message + " Message was sent by: " + contactViewModel.Name + " E-mail: " + contactViewModel.Email
              };
    
              //Configure the e-mail
              using (var emailClient = new SmtpClient())
              {
                emailClient.Connect("smtp.gmail.com", 587, false);
                emailClient.Authenticate("emailaddress@gmail.com", "password");
                emailClient.Send(message);
                emailClient.Disconnect(true);
               }
            }
            catch (Exception ex)
            {
              ModelState.Clear();
              ViewBag.Message = $" Oops! We have a problem here {ex.Message}";
            }
        }
        return View();
     }
    
  • Let’s run the application now, click on the contact menu item
  • Below is an example error when trying to send the email with a bad credentials.
    Displaying the error message in E-mail In ASP.Net Core
  • Let’s try to send a valid email now. As you can see below the e-mail was received with no problem.
    Showing how message was successfully sent out in the project E-mail In ASP.Net Core

Source Code is available for download on GitHub

51 Business Listing Websites For Local Businesses

If you are a business owner, you should know and understand the importance of having your business listed in the top major search engines on the internet. With the competition being so fierce, those business owners who understand and take action will always win. Therefore, I have compiled a list of all the major platforms for you to list your business and start growing your fan base.

I come up with this list and started using it on some local businesses that I have worked with in the past. Since most of them provide free submission, I thought others would be interest in making use of them to bring more visibility to their business. Getting your business listed on as many online local directories as possible is the best and quickest way to make sure potential new customers find you when searching for products and services related to your business.

Before I start by sharing this list with you. I want you to know that this will not be an easy or quick task. It will require some effort and time on your part to go to each of those website and submit your business information.

Promote on search engines for Local Businesses

Basic checklist to follow when submitting your business those platform

  • NAP – Some of those platforms will on require the basic NAP for your business which is your business’s Name, Address & Phone number. Therefore, make sure that information is the same on all them.
  • Business Description – If you are allowed to submit a business description, take the time to make sure you write something meaningful about the services your business provide. DO NOT LEAVE IT BLANK. This is where you highlight your company’s history and services offered. BE CREATIVE!
  • Website Link – This one of the most important piece of information you MUST provide if your company has a website. This is a great way to drive more traffic to your website and help people who want to learn about your business discover what you have to offer.
  • Pictures And Videos – Majority of listing platforms allow businesses to post pictures and short videos about their services. Take on the opportunity and showcase your business best. Let the world know why they should care about your services or products.
  1. Upamile
  2. Google
  3. Bing
  4. Yelp
  5. Facebook
  6. Better Business Bureau
  7. Angie’s List
  8. Merchant Circle
  9. LinkedIn
  10. YP.com
  11. Whitepages
  12. Superpages.com
  13. Yellowbook
  14. CitySearch
  15. MapQuest/Yext
  16. Local.com
  17. Foursquare
  18. CitySlick
  19. USDirectory.com
  20. BizJournals.com
  21. TeleAtlas
  22. Discover Our Town
  23. EZ Local
  24. CityVoter
  25. Manta
  26. UsCity
  27. InfoUSA
  28. Infignos
  29. Get Fave
  30. My Huckleberry
  31. Yellowee
  32. Brownbook
  33. Magic Yellow
  34. CitySquares
  35. Map Creator
  36. Judy’s Book
  37. TripAdvisor
  38. Thumbtack
  39. YellowPagesGoesGreen.org
  40. Home Advisor
  41. ShowMeLocal
  42. ChamberofCommerce.com
  43. Yellowbot
  44. Hotfrog
  45. Brownbook
  46. InsiderPages
  47. Bizwiki
  48. Business Local Pages
  49. iBegin
  50. Opendi
  51. Sitejabber