模拟提交带附件的表单
最近在做XXXX公司邮件对接的时候需要用到文件写入、读取并模拟提交表单相关技术来批量发送邮件,固对这些技术进行了总结。
1.初始化数据—写入文件txt
1 /// <summary> 2 /// 初始化数据 3 /// </summary> 4 /// <returns></returns> 5 public ActionResult Index() 6 { 7 //写入文件txt 8 StringBuilder emailList = new StringBuilder(); 9 emailList.Append("EmailAddress,Name,Seat,Number,PDFUserPassword" + "\n"); 10 emailList.Append("394401333@qq.com,Jerry,A1,144121,PWD111" + "\n"); 11 emailList.Append("394401333@qq.com,杨武,A2,144122,PWD222" + "\n"); 12 emailList.Append("394401333@qq.com,YW,B1,144321,PWD333"); 13 outputToFile(emailList.ToString(), Server.MapPath("~/Files/List.txt")); 14 15 StringBuilder htmlEmailContent = new StringBuilder(); 16 htmlEmailContent.Append(" 亲爱的%Name%,您好:" + "\n"); 17 htmlEmailContent.Append(" XXXXXXX座位请见附档(密码为您的省份证密码)"); 18 outputToFile(htmlEmailContent.ToString(), Server.MapPath("~/Files/Content.txt")); 19 20 StringBuilder mergePDFAttachment = new StringBuilder(); 21 mergePDFAttachment.Append(" 亲爱的%Name%,您好:" + "\n"); 22 mergePDFAttachment.Append(" 感谢您参与“XXXXXXXXX”的抽奖活动" + "\n"); 23 mergePDFAttachment.Append(" 您的座位为%Seat%(票卷编号:%Number%)"); 24 outputToFile(mergePDFAttachment.ToString(), Server.MapPath("~/Files/Attachment.txt")); 25 return View(); 26 } 27 28 /// <summary> 29 /// 写入文字到文件txt 30 /// </summary> 31 /// <param name="outStr"></param> 32 private void outputToFile(string str, string filePath) 33 { 34 //输出到文件 35 //string filePath = Server.MapPath("~/Files/List.txt"); 36 System.IO.FileStream fs = new System.IO.FileStream(filePath, System.IO.FileMode.OpenOrCreate); 37 fs.SetLength(0);//清空txt文件 38 byte[] headByts = Encoding.Default.GetBytes(str); 39 fs.Seek(0, System.IO.SeekOrigin.End); 40 fs.Write(headByts, 0, headByts.Length); 41 fs.Close(); 42 fs.Dispose(); 43 }
2.模拟提交带附件(input type=file)的表单
1 /// <summary> 2 /// 模拟提交带附件(input type=file)的表单 3 /// </summary> 4 /// <returns></returns> 5 [HttpPost] 6 public ActionResult SendEmail() 7 { 8 string html=""; 9 string responseText = string.Empty; 10 try 11 { 12 #region 调用发送电子邮件接口 13 14 //构造文件 15 FormUpload.FileParameter emailListFile = new FormUpload.FileParameter(System.IO.File.ReadAllBytes(Server.MapPath("~/Files/List.txt")), "List.txt"); 16 FormUpload.FileParameter htmlEmailContentFile = new FormUpload.FileParameter(System.IO.File.ReadAllBytes(Server.MapPath("~/Files/Content.txt")), "Content.txt"); 17 FormUpload.FileParameter mergePDFAttachment = new FormUpload.FileParameter(System.IO.File.ReadAllBytes(Server.MapPath("~/Files/Attachment.txt")), "Attachment.txt"); 18 19 //构造参数 20 Dictionary<string, object> postParams = new Dictionary<string, object>(); 21 postParams.Add("ManagerLoginName", "XXXXXXX");//API帳號 22 postParams.Add("ManagerPassword", "XXXXXXX");//API密碼 23 24 postParams.Add("From", "张三");//寄件者名稱 25 postParams.Add("EmailFromAddress", "zhangsan@163.com");//寄件者信箱 26 postParams.Add("Subject", "郵件主旨");//郵件主旨 27 28 //文件作为参数加入,如果有多个文件,可以参照加入多个 29 postParams.Add("EmailListFile", emailListFile);//收件者信箱 30 postParams.Add("HtmlEmailContentFile", htmlEmailContentFile);//郵件內容 31 postParams.Add("MergePDFAttachment", mergePDFAttachment);//附件檔 32 33 //提交请求,获得返回结果 34 var httpWebResp = FormUpload.MultipartFormDataPost("http://localhost:58629/Demo/ReceiveEmail", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.3 Safari/535.19", postParams); 35 36 Stream instream = httpWebResp.GetResponseStream(); 37 StreamReader sr = new StreamReader(instream, Encoding.UTF8); 38 //返回结果网页(html)代码 39 string response = sr.ReadToEnd(); 40 sr.Close(); 41 42 #endregion 43 } 44 catch (Exception ex) 45 { 46 throw ex; 47 //Log.Error(this.GetType().ToString(), "Exception: " + ex.Message); 48 } 49 return RedirectToAction("Index", "Demo"); 50 }
提交表单工具类
1 /// <summary> 2 /// 提交表单工具类 3 /// </summary> 4 public class FormUpload 5 { 6 private static readonly Encoding encoding = Encoding.UTF8; 7 8 /// <summary> 9 /// 提交表单——设置contentType 10 /// </summary> 11 /// <param name="postUrl"></param> 12 /// <param name="userAgent"></param> 13 /// <param name="postParameters"></param> 14 /// <returns></returns> 15 public static HttpWebResponse MultipartFormDataPost(string postUrl, string userAgent, Dictionary<string, object> postParameters) 16 { 17 string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid()); 18 string contentType = "multipart/form-data; boundary=" + formDataBoundary; 19 20 byte[] formData = GetMultipartFormData(postParameters, formDataBoundary); 21 return PostForm(postUrl, userAgent, contentType, formData); 22 } 23 24 /// <summary> 25 /// 提交表单 26 /// </summary> 27 /// <param name="postUrl"></param> 28 /// <param name="userAgent"></param> 29 /// <param name="contentType"></param> 30 /// <param name="formData"></param> 31 /// <returns></returns> 32 private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData) 33 { 34 HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest; 35 36 if (request == null) 37 { 38 throw new NullReferenceException("request is not a http request"); 39 } 40 41 // Set up the request properties. 42 request.Method = "POST"; 43 request.ContentType = contentType; 44 request.UserAgent = userAgent; 45 request.CookieContainer = new CookieContainer(); 46 request.ContentLength = formData.Length; 47 48 // You could add authentication here as well if needed: 49 // request.PreAuthenticate = true; 50 // request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested; 51 // request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.Encoding.Default.GetBytes("username" + ":" + "password"))); 52 53 // Send the form data to the request. 54 using (Stream requestStream = request.GetRequestStream()) 55 { 56 requestStream.Write(formData, 0, formData.Length); 57 requestStream.Close(); 58 } 59 60 return request.GetResponse() as HttpWebResponse; 61 } 62 63 private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary) 64 { 65 Stream formDataStream = new System.IO.MemoryStream(); 66 bool needsCLRF = false; 67 68 foreach (var param in postParameters) 69 { 70 // Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added. 71 // Skip it on the first parameter, add it to subsequent parameters. 72 if (needsCLRF) 73 formDataStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n")); 74 75 needsCLRF = true; 76 77 if (param.Value is FileParameter) 78 { 79 FileParameter fileToUpload = (FileParameter)param.Value; 80 81 // Add just the first part of this param, since we will write the file data directly to the Stream 82 string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\";\r\nContent-Type: {3}\r\n\r\n", 83 boundary, 84 param.Key, 85 fileToUpload.FileName ?? param.Key, 86 fileToUpload.ContentType ?? "application/octet-stream"); 87 88 formDataStream.Write(encoding.GetBytes(header), 0, encoding.GetByteCount(header)); 89 90 // Write the file data directly to the Stream, rather than serializing it to a string. 91 formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length); 92 } 93 else 94 { 95 string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}", 96 boundary, 97 param.Key, 98 param.Value); 99 formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData)); 100 } 101 } 102 103 // Add the end of the request. Start with a newline 104 string footer = "\r\n--" + boundary + "--\r\n"; 105 formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer)); 106 107 // Dump the Stream into a byte[] 108 formDataStream.Position = 0; 109 byte[] formData = new byte[formDataStream.Length]; 110 formDataStream.Read(formData, 0, formData.Length); 111 formDataStream.Close(); 112 113 return formData; 114 } 115 116 public class FileParameter 117 { 118 public byte[] File { get; set; } 119 public string FileName { get; set; } 120 public string ContentType { get; set; } 121 public FileParameter(byte[] file) : this(file, null) { } 122 public FileParameter(byte[] file, string filename) : this(file, filename, null) { } 123 public FileParameter(byte[] file, string filename, string contenttype) 124 { 125 File = file; 126 FileName = filename; 127 ContentType = contenttype; 128 } 129 } 130 }
3.接收请求数据
1 /// <summary> 2 /// 获取post请求数据 3 /// </summary> 4 /// <returns></returns> 5 [HttpPost] 6 public ActionResult ReceiveEmail() 7 { 8 string emailListFile = getPostData(Request.Files["EmailListFile"].InputStream); 9 string htmlEmailContentFile = getPostData(Request.Files["HtmlEmailContentFile"].InputStream); 10 string mergePDFAttachment = getPostData(Request.Files["MergePDFAttachment"].InputStream); 11 return RedirectToAction("Index","Demo"); 12 } 13 14 /// <summary> 15 /// 获取post上来的数据 16 /// </summary> 17 /// <returns></returns> 18 private string getPostData(Stream sm) 19 { 20 int len = (int)sm.Length; 21 byte[] inputByts = new byte[len]; 22 sm.Read(inputByts, 0, len); 23 sm.Close(); 24 25 return Encoding.Default.GetString(inputByts); 26 }