summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Example/ExampleCore.xproj21
-rw-r--r--src/Example/Program.cs131
-rw-r--r--src/Example/Properties/AssemblyInfo.cs19
-rw-r--r--src/Example/project.json26
-rw-r--r--src/SendGrid.nuspec39
-rw-r--r--src/SendGrid/Client.cs318
-rw-r--r--src/SendGrid/Helpers/Mail/ASM.cs14
-rw-r--r--src/SendGrid/Helpers/Mail/Attachment.cs22
-rw-r--r--src/SendGrid/Helpers/Mail/BCCSettings.cs13
-rw-r--r--src/SendGrid/Helpers/Mail/BypassListManagement.cs10
-rw-r--r--src/SendGrid/Helpers/Mail/ClickTracking.cs13
-rw-r--r--src/SendGrid/Helpers/Mail/Content.cs23
-rw-r--r--src/SendGrid/Helpers/Mail/Email.cs23
-rw-r--r--src/SendGrid/Helpers/Mail/FooterSettings.cs16
-rw-r--r--src/SendGrid/Helpers/Mail/Ganalytics.cs25
-rw-r--r--src/SendGrid/Helpers/Mail/Mail.cs153
-rw-r--r--src/SendGrid/Helpers/Mail/MailSettings.cs22
-rw-r--r--src/SendGrid/Helpers/Mail/OpenTracking.cs13
-rw-r--r--src/SendGrid/Helpers/Mail/Personalization.cs80
-rw-r--r--src/SendGrid/Helpers/Mail/README.md12
-rw-r--r--src/SendGrid/Helpers/Mail/SandboxMode.cs10
-rw-r--r--src/SendGrid/Helpers/Mail/SpamCheck.cs16
-rw-r--r--src/SendGrid/Helpers/Mail/SubscriptionTracking.cs19
-rw-r--r--src/SendGrid/Helpers/Mail/TrackingSettings.cs19
-rw-r--r--src/SendGrid/Properties/AssemblyInfo.cs19
-rw-r--r--src/SendGrid/SendGrid.xproj21
-rw-r--r--src/SendGrid/project.json46
27 files changed, 1143 insertions, 0 deletions
diff --git a/src/Example/ExampleCore.xproj b/src/Example/ExampleCore.xproj
new file mode 100644
index 0000000..4ef9c3c
--- /dev/null
+++ b/src/Example/ExampleCore.xproj
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>4bd07a97-8ad2-4134-848e-6a74eb992050</ProjectGuid>
+ <RootNamespace>Example</RootNamespace>
+ <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
+ <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
+ <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <SchemaVersion>2.0</SchemaVersion>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project>
diff --git a/src/Example/Program.cs b/src/Example/Program.cs
new file mode 100644
index 0000000..572ce7a
--- /dev/null
+++ b/src/Example/Program.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Threading.Tasks;
+using Newtonsoft.Json;
+using SendGrid;
+using SendGrid.Helpers.Mail;
+using System.Collections.Generic;
+
+namespace Example
+{
+ internal class Example
+ {
+ private static void Main()
+ {
+ Execute().Wait();
+ }
+
+ static async Task Execute()
+ {
+ string apiKey = Environment.GetEnvironmentVariable("SENDGRID_APIKEY");
+ Client client = new Client(apiKey);
+
+ string data = @"{
+ 'personalizations': [
+ {
+ 'to': [
+ {
+ 'email': 'elmer@sendgrid.com'
+ }
+ ],
+ 'subject': 'Hello World from the SendGrid C# Library!'
+ }
+ ],
+ 'from': {
+ 'email': 'dx@sendgrid.com'
+ },
+ 'content': [
+ {
+ 'type': 'text/plain',
+ 'value': 'Hello, Email!'
+ }
+ ]
+ }";
+ Object json = JsonConvert.DeserializeObject<Object>(data);
+ Response response = await client.RequestAsync(Client.Methods.POST,
+ json.ToString(),
+ urlPath: "mail/send");
+ Console.WriteLine(response.StatusCode);
+ Console.WriteLine(response.Body.ReadAsStringAsync().Result);
+ Console.WriteLine(response.Headers);
+ Console.ReadLine();
+
+ Email from = new Email("dx@sendgrid");
+ string subject = "Hello World from the SendGrid CSharp Library Helper!";
+ Email to = new Email("elmer@sendgrid.com");
+ Content content = new Content("text/plain", "Hello, Email from the helper!");
+ Mail mail = new Mail(from, subject, to, content);
+
+ response = await client.RequestAsync(Client.Methods.POST,
+ mail.Get(),
+ urlPath: "mail/send");
+ Console.WriteLine(response.StatusCode);
+ Console.WriteLine(response.Body.ReadAsStringAsync().Result);
+ Console.WriteLine(response.Headers);
+ Console.ReadLine();
+
+ // GET Collection
+ string queryParams = @"{
+ 'limit': 100
+ }";
+ response = await client.RequestAsync(method: Client.Methods.GET,
+ urlPath: "asm/groups",
+ queryParams: queryParams);
+ Console.WriteLine(response.StatusCode);
+ Console.WriteLine(response.Body.ReadAsStringAsync().Result);
+ Console.WriteLine(response.Headers.ToString());
+ Console.WriteLine("\n\nPress any key to continue to POST.");
+ Console.ReadLine();
+
+ // POST
+ string requestBody = @"{
+ 'description': 'Suggestions for products our users might like.',
+ 'is_default': false,
+ 'name': 'Magic Products'
+ }";
+ json = JsonConvert.DeserializeObject<object>(requestBody);
+ response = await client.RequestAsync(method: Client.Methods.POST,
+ urlPath: "asm/groups",
+ requestBody: json.ToString());
+ var ds_response = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(response.Body.ReadAsStringAsync().Result);
+ string group_id = ds_response["id"].ToString();
+ Console.WriteLine(response.StatusCode);
+ Console.WriteLine(response.Body.ReadAsStringAsync().Result);
+ Console.WriteLine(response.Headers.ToString());
+ Console.WriteLine("\n\nPress any key to continue to GET single.");
+ Console.ReadLine();
+
+ // GET Single
+ response = await client.RequestAsync(method: Client.Methods.GET,
+ urlPath: string.Format("asm/groups/{0}", group_id));
+ Console.WriteLine(response.StatusCode);
+ Console.WriteLine(response.Body.ReadAsStringAsync().Result);
+ Console.WriteLine(response.Headers.ToString());
+ Console.WriteLine("\n\nPress any key to continue to PATCH.");
+ Console.ReadLine();
+
+ // PATCH
+ requestBody = @"{
+ 'name': 'Cool Magic Products'
+ }";
+ json = JsonConvert.DeserializeObject<object>(requestBody);
+
+ response = await client.RequestAsync(method: Client.Methods.PATCH,
+ urlPath: string.Format("asm/groups/{0}", group_id),
+ requestBody: json.ToString());
+ Console.WriteLine(response.StatusCode);
+ Console.WriteLine(response.Body.ReadAsStringAsync().Result);
+ Console.WriteLine(response.Headers.ToString());
+
+ Console.WriteLine("\n\nPress any key to continue to PUT.");
+ Console.ReadLine();
+
+ // DELETE
+ response = await client.RequestAsync(method: Client.Methods.DELETE,
+ urlPath: string.Format("asm/groups/{0}", group_id));
+ Console.WriteLine(response.StatusCode);
+ Console.WriteLine(response.Headers.ToString());
+ Console.WriteLine("\n\nPress any key to exit.");
+ Console.ReadLine();
+ }
+ }
+}
diff --git a/src/Example/Properties/AssemblyInfo.cs b/src/Example/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c798857
--- /dev/null
+++ b/src/Example/Properties/AssemblyInfo.cs
@@ -0,0 +1,19 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Example")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("4bd07a97-8ad2-4134-848e-6a74eb992050")]
diff --git a/src/Example/project.json b/src/Example/project.json
new file mode 100644
index 0000000..b39530d
--- /dev/null
+++ b/src/Example/project.json
@@ -0,0 +1,26 @@
+{
+ "version": "1.0.0-*",
+ "buildOptions": {
+ "emitEntryPoint": true
+ },
+
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "type": "platform",
+ "version": "1.0.1"
+ },
+ "SendGrid": "9.0.0-*"
+ },
+
+ "frameworks": {
+ "netcoreapp1.0": {
+ "imports": "dnxcore50",
+ "dependencies": {
+ "NETStandard.Library": "1.6.1",
+ "Newtonsoft.Json": "9.0.1",
+ "System.Net.Http": "4.3.0",
+ "WinInsider.System.Net.Http.Formatting": "1.0.1"
+ }
+ }
+ }
+}
diff --git a/src/SendGrid.nuspec b/src/SendGrid.nuspec
new file mode 100644
index 0000000..6d2241c
--- /dev/null
+++ b/src/SendGrid.nuspec
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<package xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <metadata xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
+ <id>SendGridv9beta</id>
+ <title>SendGridv9beta</title>
+ <version>0.0.0</version>
+ <authors>Elmer Thomas</authors>
+ <owners>SendGrid</owners>
+ <description>v9beta .NET Core and .NET 4.5.X and up support</description>
+ <summary>v9beta .NET Core and .NET 4.5.X and up support</summary>
+ <licenseUrl>https://github.com/sendgrid/sendgrid-csharp/blob/master/LICENSE.txt</licenseUrl>
+ <projectUrl>https://github.com/sendgrid/sendgrid-csharp</projectUrl>
+ <requireLicenseAcceptance>false</requireLicenseAcceptance>
+ <copyright>Copyright 2016 (c) SendGrid</copyright>
+ <language>en-US</language>
+ <tags>SendGrid</tags>
+ <dependencies>
+ <group targetFramework="net452">
+ <dependency id="Newtonsoft.Json" version="9.0.1" />
+ <dependency id="System.Net.Http" version="4.0.0" />
+ </group>
+ <group targetFramework=".NETStandard1.3">
+ <dependency id="NETStandard.Library" version="1.6.1" />
+ <dependency id="Newtonsoft.Json" version="9.0.1" />
+ <dependency id="System.ComponentModel.Primitives" version="4.1.0" />
+ <dependency id="System.Reflection.TypeExtensions" version="4.1.0" />
+ <dependency id="WinInsider.System.Net.Http.Formatting" version="1.0.1" />
+ </group>
+ </dependencies>
+ </metadata>
+ <files>
+ <file src="SendGrid/bin/Release/net452/SendGrid.dll" target="lib/net452" />
+ <file src="SendGrid/bin/Release/net452/SendGrid.pdb" target="lib/net452" />
+ <file src="SendGrid/bin/Release/net452/SendGrid.xml" target="lib/net452" />
+ <file src="SendGrid/bin/Release/netstandard1.3/SendGrid.dll" target="lib/netstandard1.3" />
+ <file src="SendGrid/bin/Release/netstandard1.3/SendGrid.pdb" target="lib/netstandard1.3" />
+ <file src="SendGrid/bin/Release/netstandard1.3/SendGrid.xml" target="lib/netstandard1.3" />
+ </files>
+</package> \ No newline at end of file
diff --git a/src/SendGrid/Client.cs b/src/SendGrid/Client.cs
new file mode 100644
index 0000000..2cb20a0
--- /dev/null
+++ b/src/SendGrid/Client.cs
@@ -0,0 +1,318 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SendGrid
+{
+ public class Response
+ {
+ public HttpStatusCode StatusCode;
+ public HttpContent Body;
+ public HttpResponseHeaders Headers;
+
+ /// <summary>
+ /// Holds the response from an API call.
+ /// </summary>
+ /// <param name="statusCode">https://msdn.microsoft.com/en-us/library/system.net.httpstatuscode(v=vs.110).aspx</param>
+ /// <param name="responseBody">https://msdn.microsoft.com/en-us/library/system.net.http.httpcontent(v=vs.118).aspx</param>
+ /// <param name="responseHeaders">https://msdn.microsoft.com/en-us/library/system.net.http.headers.httpresponseheaders(v=vs.118).aspx</param>
+ public Response(HttpStatusCode statusCode, HttpContent responseBody, HttpResponseHeaders responseHeaders)
+ {
+ StatusCode = statusCode;
+ Body = responseBody;
+ Headers = responseHeaders;
+ }
+
+ /// <summary>
+ /// Converts string formatted response body to a Dictionary.
+ /// </summary>
+ /// <param name="content">https://msdn.microsoft.com/en-us/library/system.net.http.httpcontent(v=vs.118).aspx</param>
+ /// <returns>Dictionary object representation of HttpContent</returns>
+ public virtual Dictionary<string, dynamic> DeserializeResponseBody(HttpContent content)
+ {
+ var dsContent = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(content.ReadAsStringAsync().Result);
+ return dsContent;
+ }
+
+ /// <summary>
+ /// Converts string formatted response headers to a Dictionary.
+ /// </summary>
+ /// <param name="content">https://msdn.microsoft.com/en-us/library/system.net.http.headers.httpresponseheaders(v=vs.118).aspx</param>
+ /// <returns>Dictionary object representation of HttpRepsonseHeaders</returns>
+ public virtual Dictionary<string, string> DeserializeResponseHeaders(HttpResponseHeaders content)
+ {
+ var dsContent = new Dictionary<string, string>();
+ foreach (var pair in content)
+ {
+ dsContent.Add(pair.Key, pair.Value.First());
+ }
+ return dsContent;
+ }
+ }
+
+ public class Client
+ {
+ public string Host;
+ public Dictionary<string, string> RequestHeaders;
+ public string Version;
+ public string UrlPath;
+ public string MediaType;
+ public IWebProxy WebProxy;
+ public enum Methods
+ {
+ DELETE, GET, PATCH, POST, PUT
+ }
+
+
+ /// <summary>
+ /// REST API client.
+ /// </summary>
+ /// <param name="host">Base url (e.g. https://api.sendgrid.com)</param>
+ /// <param name="requestHeaders">A dictionary of request headers</param>
+ /// <param name="version">API version, override AddVersion to customize</param>
+ /// <param name="urlPath">Path to endpoint (e.g. /path/to/endpoint)</param>
+ /// <returns>Interface to the SendGrid REST API</returns>
+ public Client(IWebProxy webProxy, string apiKey, string host = "https://api.sendgrid.com", Dictionary<string, string> requestHeaders = null, string version = "v3", string urlPath = null)
+ : this(apiKey, host, requestHeaders, version, urlPath)
+ {
+ WebProxy = webProxy;
+ }
+
+ /// <summary>
+ /// REST API client.
+ /// </summary>
+ /// <param name="host">Base url (e.g. https://api.sendgrid.com)</param>
+ /// <param name="requestHeaders">A dictionary of request headers</param>
+ /// <param name="version">API version, override AddVersion to customize</param>
+ /// <param name="urlPath">Path to endpoint (e.g. /path/to/endpoint)</param>
+ /// <returns>Interface to the SendGrid REST API</returns>
+ public Client(string apiKey, string host = "https://api.sendgrid.com", Dictionary<string, string> requestHeaders = null, string version = "v3", string urlPath = null)
+ {
+ Host = host;
+ this.GetType().GetTypeInfo().Assembly.GetName().Version.ToString();
+ Dictionary<string, string> defaultHeaders = new Dictionary<string, string>();
+ defaultHeaders.Add("Authorization", "Bearer " + apiKey);
+ defaultHeaders.Add("Content-Type", "application/json");
+ defaultHeaders.Add("User-Agent", "sendgrid/" + Version + " csharp");
+ defaultHeaders.Add("Accept", "application/json");
+ AddRequestHeader(defaultHeaders);
+ if (requestHeaders != null)
+ {
+ AddRequestHeader(requestHeaders);
+ }
+ SetVersion(version);
+ SetUrlPath(urlPath);
+ }
+
+ /// <summary>
+ /// Add requestHeaders to the API call
+ /// </summary>
+ /// <param name="requestHeaders">A dictionary of request headers</param>
+ public void AddRequestHeader(Dictionary<string, string> requestHeaders)
+ {
+ RequestHeaders = (RequestHeaders != null)
+ ? RequestHeaders.Union(requestHeaders).ToDictionary(pair => pair.Key, pair => pair.Value) : requestHeaders;
+ }
+
+ /// <summary>
+ /// Set or update the UrlPath
+ /// </summary>
+ /// <param name="urlPath">The endpoint without a leading or trailing slash</param>
+ public void SetUrlPath(string urlPath)
+ {
+ UrlPath = urlPath;
+ }
+
+ /// <summary>
+ /// Get the urlPath to the API endpoint
+ /// </summary>
+ /// <returns>Url path to the API endpoint</returns>
+ public string GetUrlPath()
+ {
+ return UrlPath;
+ }
+
+ /// <summary>
+ /// Build the final URL
+ /// </summary>
+ /// <param name="queryParams">A string of JSON formatted query parameters (e.g {'param': 'param_value'})</param>
+ /// <returns>Final URL</returns>
+ private string BuildUrl(string queryParams = null)
+ {
+ string endpoint = null;
+
+ if (GetVersion() != null)
+ {
+ endpoint = Host + "/" + GetVersion() + "/" + UrlPath;
+ }
+ else
+ {
+ endpoint = Host + UrlPath;
+ }
+
+ if (queryParams != null)
+ {
+ var ds_query_params = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(queryParams);
+ var query = new Dictionary<string, string>();
+ foreach (var pair in ds_query_params)
+ {
+ query[pair.Key] = pair.Value.ToString();
+ }
+ string queryString = query.ToString();
+ endpoint = endpoint + "?" + queryString;
+ }
+
+ return endpoint;
+ }
+
+ /// <summary>
+ /// Factory method to return the right HttpClient settings.
+ /// </summary>
+ /// <returns>Instance of HttpClient</returns>
+ private HttpClient BuildHttpClient()
+ {
+ // Add the WebProxy if set
+ if (WebProxy != null)
+ {
+ var httpClientHandler = new HttpClientHandler()
+ {
+ Proxy = WebProxy,
+ PreAuthenticate = true,
+ UseDefaultCredentials = false,
+ };
+
+ return new HttpClient(httpClientHandler);
+ }
+
+ return new HttpClient();
+ }
+
+ /// <summary>
+ /// Add the authorization header, override to customize
+ /// </summary>
+ /// <param name="header">Authorization header</param>
+ /// <returns>Authorization value to add to the header</returns>
+ public virtual AuthenticationHeaderValue AddAuthorization(KeyValuePair<string, string> header)
+ {
+ string[] split = header.Value.Split(new char[0]);
+ return new AuthenticationHeaderValue(split[0], split[1]);
+ }
+
+ /// <summary>
+ /// Add the version of the API, override to customize
+ /// </summary>
+ /// <param name="version">Version string to add to the URL</param>
+ public void SetVersion(string version)
+ {
+ Version = version;
+ }
+
+ /// <summary>
+ /// Get the version of the API, override to customize
+ /// </summary>
+ /// <returns>Version of the API</param>
+ public string GetVersion()
+ {
+ return Version;
+ }
+
+ /// <summary>
+ /// Make the call to the API server, override for testing or customization
+ /// </summary>
+ /// <param name="client">Client object ready for communication with API</param>
+ /// <param name="request">The parameters for the API call</param>
+ /// <returns>Response object</returns>
+ public async virtual Task<Response> MakeRequest(HttpClient client, HttpRequestMessage request)
+ {
+ HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false);
+ return new Response(response.StatusCode, response.Content, response.Headers);
+ }
+
+ /// <summary>
+ /// Prepare for async call to the API server
+ /// </summary>
+ /// <param name="method">HTTP verb</param>
+ /// <param name="requestBody">JSON formatted string</param>
+ /// <param name="queryParams">JSON formatted query paramaters</param>
+ /// <returns>Response object</returns>
+ public async Task<Response> RequestAsync(Client.Methods method,
+ string requestBody = null,
+ Dictionary<string, string> requestHeaders = null,
+ string queryParams = null,
+ string urlPath = null)
+ {
+ using (var client = BuildHttpClient())
+ {
+ try
+ {
+ // Build the URL
+ client.BaseAddress = new Uri(Host);
+ if (urlPath != null)
+ {
+ SetUrlPath(urlPath);
+ }
+ string endpoint = BuildUrl(queryParams);
+
+ // Build the request headers
+ if (requestHeaders != null)
+ {
+ AddRequestHeader(requestHeaders);
+ }
+ client.DefaultRequestHeaders.Accept.Clear();
+ if (RequestHeaders != null)
+ {
+ foreach (KeyValuePair<string, string> header in RequestHeaders)
+ {
+ if (header.Key == "Authorization")
+ {
+ client.DefaultRequestHeaders.Authorization = AddAuthorization(header);
+ }
+ else if (header.Key == "Content-Type")
+ {
+ MediaType = header.Value;
+ client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaType));
+ }
+ else
+ {
+ client.DefaultRequestHeaders.Add(header.Key, header.Value);
+ }
+ }
+ }
+
+ // Build the request body
+ StringContent content = null;
+ if (requestBody != null)
+ {
+ content = new StringContent(requestBody, Encoding.UTF8, MediaType);
+ }
+
+ // Build the final request
+ HttpRequestMessage request = new HttpRequestMessage
+ {
+ Method = new HttpMethod(method.ToString()),
+ RequestUri = new Uri(endpoint),
+ Content = content
+ };
+ return await MakeRequest(client, request).ConfigureAwait(false);
+
+ }
+ catch (Exception ex)
+ {
+ HttpResponseMessage response = new HttpResponseMessage();
+ string message;
+ message = (ex is HttpRequestException) ? ".NET HttpRequestException" : ".NET Exception";
+ message = message + ", raw message: \n\n";
+ response.Content = new StringContent(message + ex.Message);
+ return new Response(response.StatusCode, response.Content, response.Headers);
+ }
+ }
+ }
+ }
+}
diff --git a/src/SendGrid/Helpers/Mail/ASM.cs b/src/SendGrid/Helpers/Mail/ASM.cs
new file mode 100644
index 0000000..f300780
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/ASM.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class ASM
+ {
+ [JsonProperty(PropertyName = "group_id")]
+ public int GroupId { get; set; }
+
+ [JsonProperty(PropertyName = "groups_to_display")]
+ public List<int> GroupsToDisplay { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/Attachment.cs b/src/SendGrid/Helpers/Mail/Attachment.cs
new file mode 100644
index 0000000..cc2bfd6
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/Attachment.cs
@@ -0,0 +1,22 @@
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class Attachment
+ {
+ [JsonProperty(PropertyName = "content")]
+ public string Content { get; set; }
+
+ [JsonProperty(PropertyName = "type")]
+ public string Type { get; set; }
+
+ [JsonProperty(PropertyName = "filename")]
+ public string Filename { get; set; }
+
+ [JsonProperty(PropertyName = "disposition")]
+ public string Disposition { get; set; }
+
+ [JsonProperty(PropertyName = "content_id")]
+ public string ContentId { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/BCCSettings.cs b/src/SendGrid/Helpers/Mail/BCCSettings.cs
new file mode 100644
index 0000000..79f989e
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/BCCSettings.cs
@@ -0,0 +1,13 @@
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class BCCSettings
+ {
+ [JsonProperty(PropertyName = "enable")]
+ public bool? Enable { get; set; }
+
+ [JsonProperty(PropertyName = "email")]
+ public string Email { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/BypassListManagement.cs b/src/SendGrid/Helpers/Mail/BypassListManagement.cs
new file mode 100644
index 0000000..cb4cfed
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/BypassListManagement.cs
@@ -0,0 +1,10 @@
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class BypassListManagement
+ {
+ [JsonProperty(PropertyName = "enable")]
+ public bool Enable { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/ClickTracking.cs b/src/SendGrid/Helpers/Mail/ClickTracking.cs
new file mode 100644
index 0000000..b8f82f5
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/ClickTracking.cs
@@ -0,0 +1,13 @@
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class ClickTracking
+ {
+ [JsonProperty(PropertyName = "enable")]
+ public bool? Enable { get; set; }
+
+ [JsonProperty(PropertyName = "enable_text")]
+ public bool? EnableText { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/Content.cs b/src/SendGrid/Helpers/Mail/Content.cs
new file mode 100644
index 0000000..68b01d3
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/Content.cs
@@ -0,0 +1,23 @@
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class Content
+ {
+ public Content()
+ {
+ }
+
+ public Content(string type, string value)
+ {
+ this.Type = type;
+ this.Value = value;
+ }
+
+ [JsonProperty(PropertyName = "type")]
+ public string Type { get; set; }
+
+ [JsonProperty(PropertyName = "value")]
+ public string Value { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/Email.cs b/src/SendGrid/Helpers/Mail/Email.cs
new file mode 100644
index 0000000..b4b4402
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/Email.cs
@@ -0,0 +1,23 @@
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class Email
+ {
+ public Email()
+ {
+ }
+
+ public Email(string email, string name = null)
+ {
+ this.Address = email;
+ this.Name = name;
+ }
+
+ [JsonProperty(PropertyName = "name")]
+ public string Name { get; set; }
+
+ [JsonProperty(PropertyName = "email")]
+ public string Address { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/FooterSettings.cs b/src/SendGrid/Helpers/Mail/FooterSettings.cs
new file mode 100644
index 0000000..5ef64f7
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/FooterSettings.cs
@@ -0,0 +1,16 @@
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class FooterSettings
+ {
+ [JsonProperty(PropertyName = "enable")]
+ public bool Enable { get; set; }
+
+ [JsonProperty(PropertyName = "text")]
+ public string Text { get; set; }
+
+ [JsonProperty(PropertyName = "html")]
+ public string Html { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/Ganalytics.cs b/src/SendGrid/Helpers/Mail/Ganalytics.cs
new file mode 100644
index 0000000..071da50
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/Ganalytics.cs
@@ -0,0 +1,25 @@
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class Ganalytics
+ {
+ [JsonProperty(PropertyName = "enable")]
+ public bool? Enable { get; set; }
+
+ [JsonProperty(PropertyName = "utm_source")]
+ public string UtmSource { get; set; }
+
+ [JsonProperty(PropertyName = "utm_medium")]
+ public string UtmMedium { get; set; }
+
+ [JsonProperty(PropertyName = "utm_term")]
+ public string UtmTerm { get; set; }
+
+ [JsonProperty(PropertyName = "utm_content")]
+ public string UtmContent { get; set; }
+
+ [JsonProperty(PropertyName = "utm_campaign")]
+ public string UtmCampaign { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/Mail.cs b/src/SendGrid/Helpers/Mail/Mail.cs
new file mode 100644
index 0000000..2aa1274
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/Mail.cs
@@ -0,0 +1,153 @@
+using Newtonsoft.Json;
+using System.Collections.Generic;
+
+namespace SendGrid.Helpers.Mail
+{
+ /// <summary>
+ /// Class Mail builds an object that sends an email through SendGrid.
+ /// </summary>
+ public class Mail
+ {
+ public Mail()
+ {
+ }
+
+ public Mail(Email from, string subject, Email to, Content content)
+ {
+ this.From = from;
+
+ var personalization = new Personalization();
+ personalization.AddTo(to);
+ this.AddPersonalization(personalization);
+
+ this.Subject = subject;
+ this.AddContent(content);
+ }
+
+ [JsonProperty(PropertyName = "from")]
+ public Email From { get; set; }
+
+ [JsonProperty(PropertyName = "subject")]
+ public string Subject { get; set; }
+
+ [JsonProperty(PropertyName = "personalizations")]
+ public List<Personalization> Personalization { get; set; }
+
+ [JsonProperty(PropertyName = "content")]
+ public List<Content> Contents { get; set; }
+
+ [JsonProperty(PropertyName = "attachments")]
+ public List<Attachment> Attachments { get; set; }
+
+ [JsonProperty(PropertyName = "template_id")]
+ public string TemplateId { get; set; }
+
+ [JsonProperty(PropertyName = "headers")]
+ public Dictionary<string, string> Headers { get; set; }
+
+ [JsonProperty(PropertyName = "sections")]
+ public Dictionary<string, string> Sections { get; set; }
+
+ [JsonProperty(PropertyName = "categories")]
+ public List<string> Categories { get; set; }
+
+ [JsonProperty(PropertyName = "custom_args")]
+ public Dictionary<string, string> CustomArgs { get; set; }
+
+ [JsonProperty(PropertyName = "send_at")]
+ public long? SendAt { get; set; }
+
+ [JsonProperty(PropertyName = "asm")]
+ public ASM Asm { get; set; }
+
+ [JsonProperty(PropertyName = "batch_id")]
+ public string BatchId { get; set; }
+
+ [JsonProperty(PropertyName = "ip_pool_name")]
+ public string SetIpPoolId { get; set; }
+
+ [JsonProperty(PropertyName = "mail_settings")]
+ public MailSettings MailSettings { get; set; }
+
+ [JsonProperty(PropertyName = "tracking_settings")]
+ public TrackingSettings TrackingSettings { get; set; }
+
+ [JsonProperty(PropertyName = "reply_to")]
+ public Email ReplyTo { get; set; }
+
+ public void AddPersonalization(Personalization personalization)
+ {
+ if (Personalization == null)
+ {
+ Personalization = new List<Personalization>();
+ }
+ Personalization.Add(personalization);
+ }
+
+ public void AddContent(Content content)
+ {
+ if (Contents == null)
+ {
+ Contents = new List<Content>();
+ }
+ Contents.Add(content);
+ }
+
+ public void AddAttachment(Attachment attachment)
+ {
+ if (Attachments == null)
+ {
+ Attachments = new List<Attachment>();
+ }
+ Attachments.Add(attachment);
+ }
+
+ public void AddHeader(string key, string value)
+ {
+ if (Headers == null)
+ {
+ Headers = new Dictionary<string, string>();
+ }
+ Headers.Add(key, value);
+ }
+
+ public void AddSection(string key, string value)
+ {
+ if (Sections == null)
+ {
+ Sections = new Dictionary<string, string>();
+ }
+ Sections.Add(key, value);
+ }
+
+ public void AddCategory(string category)
+ {
+ if (Categories == null)
+ {
+ Categories = new List<string>();
+ }
+ Categories.Add(category);
+ }
+
+ public void AddCustomArgs(string key, string value)
+ {
+ if (CustomArgs == null)
+ {
+ CustomArgs = new Dictionary<string, string>();
+ }
+ CustomArgs.Add(key, value);
+ }
+
+ public string Get()
+ {
+ return JsonConvert.SerializeObject(this,
+ Formatting.None,
+ new JsonSerializerSettings
+ {
+ NullValueHandling = NullValueHandling.Ignore,
+ DefaultValueHandling = DefaultValueHandling.Include,
+ StringEscapeHandling = StringEscapeHandling.EscapeHtml
+ });
+ }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/MailSettings.cs b/src/SendGrid/Helpers/Mail/MailSettings.cs
new file mode 100644
index 0000000..1875603
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/MailSettings.cs
@@ -0,0 +1,22 @@
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class MailSettings
+ {
+ [JsonProperty(PropertyName = "bcc")]
+ public BCCSettings BccSettings { get; set; }
+
+ [JsonProperty(PropertyName = "bypass_list_management")]
+ public BypassListManagement BypassListManagement { get; set; }
+
+ [JsonProperty(PropertyName = "footer")]
+ public FooterSettings FooterSettings { get; set; }
+
+ [JsonProperty(PropertyName = "sandbox_mode")]
+ public SandboxMode SandboxMode { get; set; }
+
+ [JsonProperty(PropertyName = "spam_check")]
+ public SpamCheck SpamCheck { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/OpenTracking.cs b/src/SendGrid/Helpers/Mail/OpenTracking.cs
new file mode 100644
index 0000000..b171a0b
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/OpenTracking.cs
@@ -0,0 +1,13 @@
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class OpenTracking
+ {
+ [JsonProperty(PropertyName = "enable")]
+ public bool? Enable { get; set; }
+
+ [JsonProperty(PropertyName = "substitution_tag")]
+ public string SubstitutionTag { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/Personalization.cs b/src/SendGrid/Helpers/Mail/Personalization.cs
new file mode 100644
index 0000000..47d0832
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/Personalization.cs
@@ -0,0 +1,80 @@
+using System.Collections.Generic;
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class Personalization
+ {
+ [JsonProperty(PropertyName = "to")]
+ public List<Email> Tos { get; set; }
+
+ [JsonProperty(PropertyName = "cc")]
+ public List<Email> Ccs { get; set; }
+
+ [JsonProperty(PropertyName = "bcc")]
+ public List<Email> Bccs { get; set; }
+
+ [JsonProperty(PropertyName = "subject")]
+ public string Subject { get; set; }
+
+ [JsonProperty(PropertyName = "headers")]
+ public Dictionary<string, string> Headers { get; set; }
+
+ [JsonProperty(PropertyName = "substitutions")]
+ public Dictionary<string, string> Substitutions { get; set; }
+
+ [JsonProperty(PropertyName = "custom_args")]
+ public Dictionary<string, string> CustomArgs { get; set; }
+
+ [JsonProperty(PropertyName = "send_at")]
+ public long? SendAt { get; set; }
+
+ public void AddTo(Email email)
+ {
+ if (Tos == null)
+ Tos = new List<Email>();
+
+ Tos.Add(email);
+ }
+
+ public void AddCc(Email email)
+ {
+ if (Ccs == null)
+ Ccs = new List<Email>();
+
+ Ccs.Add(email);
+ }
+
+ public void AddBcc(Email email)
+ {
+ if (Bccs == null)
+ Bccs = new List<Email>();
+
+ Bccs.Add(email);
+ }
+
+ public void AddHeader(string key, string value)
+ {
+ if (Headers == null)
+ Headers = new Dictionary<string, string>();
+
+ Headers.Add(key, value);
+ }
+
+ public void AddSubstitution(string key, string value)
+ {
+ if (Substitutions == null)
+ Substitutions = new Dictionary<string, string>();
+
+ Substitutions.Add(key, value);
+ }
+
+ public void AddCustomArgs(string key, string value)
+ {
+ if (CustomArgs == null)
+ CustomArgs = new Dictionary<string, string>();
+
+ CustomArgs.Add(key, value);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/README.md b/src/SendGrid/Helpers/Mail/README.md
new file mode 100644
index 0000000..67c1933
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/README.md
@@ -0,0 +1,12 @@
+**This helper allows you to quickly and easily build a Mail object for sending email through SendGrid.**
+
+# Quick Start
+
+Run the [Example Project](https://github.com/sendgrid/sendgrid-csharp/tree/master/SendGrid/SendGrid/Helpers/Mail) (make sure you have set your Environment variable to include your SENDGRID_API_KEY).
+
+Click on the Example project, then click the `Start` button in the menu.
+
+## Usage
+
+- See the [example](https://github.com/sendgrid/sendgrid-csharp/tree/master/SendGrid/Example/Example.cs) for a complete working example.
+- [Documentation](https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/overview.html) \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/SandboxMode.cs b/src/SendGrid/Helpers/Mail/SandboxMode.cs
new file mode 100644
index 0000000..7dea93e
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/SandboxMode.cs
@@ -0,0 +1,10 @@
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class SandboxMode
+ {
+ [JsonProperty(PropertyName = "enable")]
+ public bool? Enable { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/SpamCheck.cs b/src/SendGrid/Helpers/Mail/SpamCheck.cs
new file mode 100644
index 0000000..8b1abf4
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/SpamCheck.cs
@@ -0,0 +1,16 @@
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class SpamCheck
+ {
+ [JsonProperty(PropertyName = "enable")]
+ public bool? Enable { get; set; }
+
+ [JsonProperty(PropertyName = "threshold")]
+ public int? Threshold { get; set; }
+
+ [JsonProperty(PropertyName = "post_to_url")]
+ public string PostToUrl { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/SubscriptionTracking.cs b/src/SendGrid/Helpers/Mail/SubscriptionTracking.cs
new file mode 100644
index 0000000..ce5704e
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/SubscriptionTracking.cs
@@ -0,0 +1,19 @@
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class SubscriptionTracking
+ {
+ [JsonProperty(PropertyName = "enable")]
+ public bool Enable { get; set; }
+
+ [JsonProperty(PropertyName = "text")]
+ public string Text { get; set; }
+
+ [JsonProperty(PropertyName = "html")]
+ public string Html { get; set; }
+
+ [JsonProperty(PropertyName = "substitution_tag")]
+ public string SubstitutionTag { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Helpers/Mail/TrackingSettings.cs b/src/SendGrid/Helpers/Mail/TrackingSettings.cs
new file mode 100644
index 0000000..73f8056
--- /dev/null
+++ b/src/SendGrid/Helpers/Mail/TrackingSettings.cs
@@ -0,0 +1,19 @@
+using Newtonsoft.Json;
+
+namespace SendGrid.Helpers.Mail
+{
+ public class TrackingSettings
+ {
+ [JsonProperty(PropertyName = "click_tracking")]
+ public ClickTracking ClickTracking { get; set; }
+
+ [JsonProperty(PropertyName = "open_tracking")]
+ public OpenTracking OpenTracking { get; set; }
+
+ [JsonProperty(PropertyName = "subscription_tracking")]
+ public SubscriptionTracking SubscriptionTracking { get; set; }
+
+ [JsonProperty(PropertyName = "ganalytics")]
+ public Ganalytics Ganalytics { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/SendGrid/Properties/AssemblyInfo.cs b/src/SendGrid/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..1b64038
--- /dev/null
+++ b/src/SendGrid/Properties/AssemblyInfo.cs
@@ -0,0 +1,19 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("SendGrid")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("377c20e4-2297-488f-933b-fb635c56d8fc")]
diff --git a/src/SendGrid/SendGrid.xproj b/src/SendGrid/SendGrid.xproj
new file mode 100644
index 0000000..c3a2b06
--- /dev/null
+++ b/src/SendGrid/SendGrid.xproj
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>377c20e4-2297-488f-933b-fb635c56d8fc</ProjectGuid>
+ <RootNamespace>SendGrid</RootNamespace>
+ <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
+ <OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
+ <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <SchemaVersion>2.0</SchemaVersion>
+ </PropertyGroup>
+ <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
+</Project>
diff --git a/src/SendGrid/project.json b/src/SendGrid/project.json
new file mode 100644
index 0000000..3beab98
--- /dev/null
+++ b/src/SendGrid/project.json
@@ -0,0 +1,46 @@
+{
+ "buildOptions": {
+ "emitEntryPoint": false,
+ "keyFile": "../../tools/sendgrid-csharp.snk",
+ "xmlDoc": true,
+ "platform": "anycpu",
+ "compile": {
+ }
+ },
+ "configurations": {
+ "Release": {
+ "buildOptions": {
+ "warningsAsErrors": false
+ }
+ }
+ },
+ "dependencies": {
+ "Microsoft.AspNetCore.Http.Abstractions": "1.1.0"
+ },
+ "frameworks": {
+ "netstandard1.3": {
+ "buildOptions": {
+ "define": [ "NETSTANDARD" ]
+ },
+ "imports": "dnxcore50",
+ "dependencies": {
+ "NETStandard.Library": "1.6.1",
+ "Newtonsoft.Json": "9.0.1",
+ "System.Reflection.TypeExtensions": "4.1.0"
+ }
+ },
+ "net452": {
+ "buildOptions": {
+ "define": [ "NET452" ]
+ },
+ "dependencies": {
+ "Newtonsoft.Json": "9.0.1",
+ "System.Net.Http": "4.0.0"
+ },
+ "frameworkAssemblies": {
+ "System.Runtime.Serialization": "4.0.0"
+ }
+ }
+ },
+ "version": "9.0.0-*"
+}