using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Xml; using System.Xml.Serialization; namespace ConsoleApp2 { internal class Program { private static readonly string API_URL = "https://service6.rspread.net/"; private static readonly string LOGIN_EMAIL = "test@reasonables.com"; private static readonly string LOGIN_PWD = "AAAABBBB-CCCC-DDDD-EEEE-FFFFGGGGHHHH"; static void Main(string[] args) { string result = SendWithAttachment(); Console.WriteLine(result); Console.ReadKey(); } static string SendWithAttachment() { string apiUrl = API_URL; string soapAction = "http://service.reasonablespread.com/SendWithAttachment"; byte[] file1 = File.ReadAllBytes(@"C:\Users\test\file1.txt"); byte[] file2 = File.ReadAllBytes(@"C:\Users\test\file2.png"); var campaignAttachment1 = new CampaignAttachment() { displayName = "txtFile.txt", file = file1, fileType = ".txt" }; var campaignAttachment2 = new CampaignAttachment() { displayName = "pngFile.png", file = file2, fileType = ".png" }; var files = new List() { campaignAttachment1, campaignAttachment2 }; var soapClient = new SoapClient(apiUrl, soapAction); soapClient.Arguments.Add(new SoapParameter("LoginEmail", LOGIN_EMAIL)); soapClient.Arguments.Add(new SoapParameter("Password", LOGIN_PWD)); soapClient.Arguments.Add(new SoapParameter("CampaignName", "test-api-SendWithAttachment")); soapClient.Arguments.Add(new SoapParameter("From", "test1@xxx.com")); soapClient.Arguments.Add(new SoapParameter("FromName", "test2@xxx.com")); soapClient.Arguments.Add(new SoapParameter("To", "test3@xxx.com")); soapClient.Arguments.Add(new SoapParameter("replyTo", "test3@xxx.com")); soapClient.Arguments.Add(new SoapParameter("Subject", "test-api-SendWithAttachment")); soapClient.Arguments.Add(new SoapParameter("Body", "This is a test email of API SendWithAttachment.")); soapClient.Arguments.Add(new SoapParameter("files", files)); return soapClient.GetResult(); } } public class CampaignAttachment { public string displayName { get; set; } public byte[] file { get; set; } public string fileType { get; set; } } public static class SoapHelper { private const string FORMAT_ENVELOPE = @" <{0} xmlns='{1}'>{2} "; private const string FORMAT_PARAMTER = "<{0}>{1}"; public static string MakeEnvelope(string soapAction, params SoapParameter[] soapParamters) { string nameSpace, methodName; GetNameSpaceAndMethodName(soapAction, out nameSpace, out methodName); string parameters = BuildSoapParameters(soapParamters); return string.Format(FORMAT_ENVELOPE, methodName, nameSpace, parameters); } private static void GetNameSpaceAndMethodName(string soapAction, out string nameSpace, out string methodName) { var index = soapAction.LastIndexOf(Path.AltDirectorySeparatorChar); nameSpace = soapAction.Substring(0, index + 1); methodName = soapAction.Substring(index + 1, soapAction.Length - index - 1); } private static string BuildSoapParameters(IEnumerable parameters) { var sb = new StringBuilder(); foreach (var param in parameters) { string content = GetObjectContent(param.Value); sb.AppendFormat(FORMAT_PARAMTER, param.Name, content); } return sb.ToString(); } private static String GetObjectContent(Object graph) { using (var memoryStream = new MemoryStream()) { var graphType = graph.GetType(); var xmlSerializer = new XmlSerializer(graphType); xmlSerializer.Serialize(memoryStream, graph); var strContent = Encoding.UTF8.GetString(memoryStream.ToArray()); var xmlDocument = new XmlDocument(); xmlDocument.LoadXml(strContent); if (graphType.IsGenericType && graphType.GetGenericTypeDefinition() == typeof(List<>)) { Type itemType = graphType.GetGenericArguments()[0]; // use this... string graphName = "ArrayOf" + itemType.Name; XmlNode contentNode = xmlDocument.SelectSingleNode(graphName); if (contentNode != null) return contentNode.InnerXml; } if (graphType.Name == "String[]") { String[] contents = (String[])graph; string content = ""; foreach (var c in contents) { content = content + "" + c + ""; } if (content != "") return content; } else { XmlNode contentNode; if (graphType.Name == "Byte[]") contentNode = xmlDocument.SelectSingleNode("base64Binary"); else contentNode = xmlDocument.SelectSingleNode(graphType.Name); if (contentNode != null) return contentNode.InnerXml; } return graph.ToString(); } } } public sealed class SoapParameter { public string Name { get; set; } public object Value { get; set; } public SoapParameter(string name, object value) { this.Name = name; this.Value = value; } } public sealed class SoapClient { public Uri Uri { get; set; } public string SoapAction { get; set; } public IList Arguments { get; private set; } public ICredentials Credentials { get; set; } public SoapClient(string uriString, string soapAction) { this.Uri = new Uri(uriString); this.SoapAction = soapAction; this.Arguments = new List(); this.Credentials = CredentialCache.DefaultNetworkCredentials; } private WebResponse GetResponse() { var webRequest = (HttpWebRequest)WebRequest.Create(this.Uri); webRequest.Headers.Add("SOAPAction", string.Format("\"{0}\"", this.SoapAction)); webRequest.ContentType = "text/xml;charset=utf-8"; webRequest.Accept = "text/xml"; webRequest.Method = "POST"; webRequest.Credentials = this.Credentials; string envelope = SoapHelper.MakeEnvelope(this.SoapAction, this.Arguments.ToArray()) .Replace("\r", "").Replace("\n", "").Trim(); byte[] bytes = Encoding.UTF8.GetBytes(envelope); Stream requestStream = webRequest.GetRequestStream(); requestStream.Write(bytes, 0, bytes.Length); requestStream.Close(); WebResponse webResponse = null; try { webResponse = webRequest.GetResponse(); } catch (WebException ex) { Console.WriteLine("Exception: " + new StreamReader(ex.Response.GetResponseStream()).ReadToEnd()); } return webResponse; } public string GetResult() { var webResponse = this.GetResponse(); if (webResponse == null) return "null"; Stream responseStream = webResponse.GetResponseStream(); StreamReader reader = new StreamReader(responseStream); return reader.ReadToEnd(); } } }