C# & ADO.NET

Sending a test e-mail from ASP.NET through Gmail's SMTP server (C#)

C# & ADO.NET · · Published 2026-10-17

Sending a test message through a Gmail account is a quick way to check that an application's e-mail code works before you have a production mail server. The .NET part has barely changed in fifteen years; what has changed is Google's side: ordinary account passwords are no longer accepted by SMTP clients, so you need two-step verification and an app password.

Gmail's SMTP settings

SettingValue
Serversmtp.gmail.com
Port587 with STARTTLS (works with SmtpClient); 465 is implicit TLS, which SmtpClient does not support
AuthenticationYour full Gmail address and a 16-character app password
Sending limitsDaily limits apply to personal accounts; do not use one for bulk mail

Step 1: create an app password

  1. Turn on 2-Step Verification for the Google account (Google Account › Security).
  2. Open the "App passwords" page of the account and create one, for example named "ASP.NET test".
  3. Copy the 16 characters shown. Treat them like a password: anyone with them can send mail as you.

Google stopped accepting a plain account password from "less secure apps" in 2022 for most accounts. If you see "5.7.8 Username and Password not accepted", an app password is the usual fix. Google Workspace administrators can disable app passwords for their organisation.

Step 2: store the settings outside the code

System.Net.Mail reads defaults from web.config, so the code needs no server name or credentials:

<configuration>
  <system.net>
    <mailSettings>
      <smtp from="yourname@gmail.com" deliveryMethod="Network">
        <network host="smtp.gmail.com" port="587" enableSsl="true"
                 userName="yourname@gmail.com" password="abcdefghijklmnop"
                 defaultCredentials="false" />
      </smtp>
    </mailSettings>
  </system.net>
</configuration>

Do not commit this file with a real password to source control. Use a web.Release.config transform, an external config file referenced with configSource, or protected configuration (aspnet_regiis -pe) on the server.

During development you can avoid sending anything at all: deliveryMethod="SpecifiedPickupDirectory" with <specifiedPickupDirectory pickupDirectoryLocation="C:\mail" /> writes each message as an .eml file you can open in a mail client.

Step 3: the page

<asp:Label runat="server" AssociatedControlID="txtTo" Text="Send a test message to" />
<asp:TextBox ID="txtTo" runat="server" TextMode="Email" />
<asp:RequiredFieldValidator runat="server" ControlToValidate="txtTo" ErrorMessage="Required" />
<asp:Button ID="btnSend" runat="server" Text="Send test mail" OnClick="btnSend_Click" />
<asp:Label ID="lblStatus" runat="server" />
using System;
using System.Net;
using System.Net.Mail;
using System.Web.UI;

namespace Demo
{
    public partial class TestMail : Page
    {
        protected void btnSend_Click(object sender, EventArgs e)
        {
            if (!IsValid) return;

            MailAddress to;
            try { to = new MailAddress(txtTo.Text.Trim()); }
            catch (FormatException) { lblStatus.Text = "That address is not valid."; return; }

            using (var message = new MailMessage())
            using (var client = new SmtpClient()) // host, port, SSL and credentials from web.config
            {
                message.To.Add(to);
                message.Subject = "Test message from " + Request.Url.Host;
                message.Body = "<p>This is a test sent at " + DateTime.UtcNow.ToString("u") + " (UTC).</p>";
                message.IsBodyHtml = true;

                try
                {
                    client.Send(message);
                    lblStatus.Text = "Sent.";
                }
                catch (SmtpException ex)
                {
                    lblStatus.Text = "Sending failed: " + Server.HtmlEncode(ex.StatusCode + " " + ex.Message);
                }
            }
        }
    }
}

The From address comes from the from attribute in configuration when the message does not set one. Gmail rewrites the sender to the authenticated account anyway, unless you have added another address as a verified "Send mail as" alias.

Without web.config

using (var client = new SmtpClient("smtp.gmail.com", 587))
{
    client.EnableSsl = true;
    client.DeliveryMethod = SmtpDeliveryMethod.Network;
    client.UseDefaultCredentials = false; // set before Credentials
    client.Credentials = new NetworkCredential("yourname@gmail.com", appPassword);
    client.Send(message);
}

The order matters: setting UseDefaultCredentials after Credentials resets the credentials.

TLS 1.2

Google requires TLS 1.2 or later. Applications targeting .NET Framework 4.7 or later use the operating system's defaults, which include TLS 1.2 on supported Windows versions. Older applications (target 4.5–4.6.x) may try TLS 1.0 and fail with "The SMTP server requires a secure connection" or an authentication exception. The clean fix is to retarget to 4.8 (<httpRuntime targetFramework="4.8" />). As a stopgap you can add ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12; in Application_Start.

Attachments and HTML

message.Attachments.Add(new Attachment(Server.MapPath("~/App_Data/report.pdf"), "application/pdf"));

// Plain-text alternative for clients that do not render HTML
var plain = AlternateView.CreateAlternateViewFromString("This is a test.", null, "text/plain");
message.AlternateViews.Add(plain);

Sending the contents of a GridView as an HTML table is shown in Send a GridView by e-mail, and a whole page in Send an HTML page as e-mail.

Common errors

ErrorWhat to check
5.7.8 Username and Password not accepted / 5.7.0 Authentication RequiredUse an app password; check UseDefaultCredentials=false and the full e-mail address as user name.
The SMTP server requires a secure connectionenableSsl="true", port 587, TLS 1.2 available.
Unable to connect to the remote server / timeoutThe host or a firewall blocks outbound 587. Many shared hosts only allow their own relay.
Mailbox unavailableRecipient address wrong, or the message was rejected as spam.

For production, use something else

A personal Gmail account is fine for testing. For a live site, use your organisation's mail server or a transactional e-mail service, publish SPF, DKIM and DMARC records for your domain, and send from an address on that domain. Microsoft also notes that SmtpClient is not recommended for new development because it does not support many modern protocols; for new code the MailKit library is the commonly recommended replacement. Existing Web Forms applications can keep using SmtpClient with STARTTLS as shown here.

Testing without sending real mail

Automated tests and development machines rarely need to deliver mail. Besides the pickup directory option above, a local SMTP capture tool (several open-source ones exist) accepts messages on localhost and shows them in a web interface; point <network host="localhost" port="…"> at it in your development configuration. This keeps your Gmail account's sending limits for real tests and avoids sending messages to real customers from a test database.

Official documentation