Swagger
1.上傳檔案
2.寄信加附檔
enctype這個屬性管理的是表單的MIME編碼
①application/x-www-form-urlencoded (默認值):
在AJAX里不寫有可能會報錯,
但是在HTML的form表單里是可以不寫 enctype="application/x-www-form-urlencoded"的,
因為默認HTML表單就是這種傳輸編碼類型。
②multipart/form-data:
是用來指定傳輸數據的特殊類型的,
主要就是我們上傳的非文本的內容,
比如圖片或者mp3等等。
③text/plain:
是純文本傳輸的意思,在發送郵件時要設置這種編碼類型,否則會出現接收時編碼混亂的問題,
網路上經常拿text/plain和 text/html做比較,
前者用來傳輸純文本文件,
後者則是傳遞html代碼的編碼類型,
在發送文件時才用得上。
原文網址:https://read01.com/oLgjLj.html
ASP.NET WebAPI
在Swagger中若需上傳檔案則須將所有body中的參數類型改為formData
在ASP.NET WebAPI中的Swagger ParameterType更改為formdata須自己加入其屬性(因為沒有[FromForm]此屬性)
第一步:增添其屬性
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class SwaggerParameterAttribute : Attribute
{
}
第二步:增加Filter
/// <summary>
/// Class SwaggerParameterOperationFilter.
/// </summary>
/// <seealso cref="Swashbuckle.Swagger.IOperationFilter" />
public class SwaggerParameterOperationFilter : Swashbuckle.Swagger.IOperationFilter
{
/// <summary>
/// Applies the specified operation.
/// </summary>
/// <param name="operation">The operation.</param>
/// <param name="schemaRegistry">The schema registry.</param>
/// <param name="apiDescription">The API description.</param>
public void Apply(Swashbuckle.Swagger.Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
//確認是否有加入此Attribute 如果有的話就做
var requestAttributes = apiDescription.GetControllerAndActionAttributes<SwaggerParameterAttribute>();
if (requestAttributes.Any())
{
operation.parameters = operation.parameters ?? new List<Parameter>();
//取得Action的參數
var getActionParameters = apiDescription.ActionDescriptor.GetParameters();
foreach (var item in getActionParameters)
{
//如果底層型別為Object
if (item.ParameterType.BaseType.Name == typeof(object).Name)
{
//檢查是否有此Object 有才做 , 如果是string 在CheckObjectName這邊正常會判定為False , string底層型別為Object,item.ParameterType.Name = String
var checkObjectName = schemaRegistry.Definitions.ContainsKey(item.ParameterType.Name);
if (checkObjectName)
{
//取得Object裡面的屬性
var data = schemaRegistry.Definitions[item.ParameterType.Name];
foreach (var item2 in data.properties)
{
//加進Swagger裡面
operation.parameters.Add(new Parameter
{
name = item2.Key,
description = item2.Value.description,
@in = "formData",
required = false,
type = item2.Value.type,
@enum = item2.Value.@enum
});
}
//移除Swagger內容
schemaRegistry.Definitions.Remove(item.ParameterType.Name);
operation.parameters.Remove(operation.parameters.FirstOrDefault(x => x.@in == "body"));
var parameterList = new List<Parameter>(operation.parameters.ToList());
foreach (var parameter in operation.parameters.Where(x => x.@in == "query"))
{
parameterList.Remove(parameter);
}
operation.parameters = parameterList;
}
}
}
}
}
}
第三步:在Controller的Method中加入其屬性[SwaggerParameter]
[HttpPost]
[SwaggerParameter]
[Route("uploadFilesAndSendEmail")]
public async Task<IHttpActionResult> UploadFileAndSendEmail([FromUri]ModelClass model)
{
var subject = HttpContext.Current.Request.Form["subject"];
//若為htmlcode則需Encode
var content = HttpUtility.HtmlEncode(HttpContext.Current.Request.Form["Content"]);
var guid = Guid.NewGuid();
model.ID = guid;
model.Subject = subject;
model.Content = content;
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
string root = System.Web.HttpContext.Current.Server.MapPath("~/App_Data/uploads");
model.Root = root;
// 若資料夾不存在,則創建該資料夾
if (!Directory.Exists(root))
{
// 創建資料夾
Directory.CreateDirectory(root);
}
var i = 1;
var fileNames = new List<string>();
// 驗證檔案大小及副檔名
try
{
var multipartMemoryStreamProvider = await Request.Content.ReadAsMultipartAsync();
foreach (var httpcontent in multipartMemoryStreamProvider.Contents)
{
using (httpcontent)
{
if (httpcontent.Headers.ContentDisposition.FileName != null)
{
var fileName = httpcontent.Headers.ContentDisposition.FileName.Replace("\"", string.Empty);
List<string> validExtensions = new List<string> { ".jpg", ".jpeg", ".png" };
using (var stream = await httpcontent.ReadAsStreamAsync())
{
//驗證附檔名
var extension = Path.GetExtension(fileName.Replace("\"", string.Empty));
if (!validExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase))
{
if (fileNames.Count() > 0)
{
foreach (var file in fileNames)
{
File.Delete(Path.Combine(root, file));
}
}
stream.Dispose();
throw new CustomException(StatusType.FileTypeIsNotSupported);
}
else if (stream.Length > 2097152)// 2MB = 2*1024*1024
{
if (fileNames.Count() > 0)
{
foreach (var file in fileNames)
{
File.Delete(Path.Combine(root, file));
}
}
stream.Dispose();
throw new CustomException(StatusType.UploadFileLengthOver);
}
// 將檔案名稱抓取出來
if (fileName.StartsWith("\"") && fileName.EndsWith("\""))
{
fileName = fileName.Trim('"');
}
if (fileName.Contains(@"/") || fileName.Contains(@"\"))
{
fileName = Path.GetFileName(fileName);
}
var renameFile = $"{guid}_{i}{extension}";
fileNames.Add(renameFile);
// 上傳檔案至Server
using (var fileStream = new FileStream(Path.Combine(root, renameFile), FileMode.Create))
{
await stream.CopyToAsync(fileStream);
}
i++;
}
}
}
}
model.Attachments = fileNames;
model.Attachment = string.Join(",", fileNames);
//寄信
var result = this._customerService.SendMail("zh-cn", model);
return this.Ok(result);
}
catch (CustomException e)
{
throw new CustomException(e.StatusType);
}
catch (Exception e)
{
throw new Exception(e.Message);
}
}
SendMail
public bool SendMail(string langID, ReuquestCustomServiceModel model)
{
var result = default(bool);
var subject = $"{model.Subject}";
content += HttpUtility.HtmlDecode(model.Content);
//// 寄信
var mailMessage = new MailMessage();
//// 信件主旨
mailMessage.Subject = subject;
//// 信件內容
mailMessage.Body = HttpUtility.HtmlDecode(content);
//// 信件內容 是否採用Html格式
mailMessage.IsBodyHtml = true;
//// 信件標題編碼
mailMessage.SubjectEncoding = System.Text.Encoding.UTF8;
//// 寄件人
mailMessage.From = new MailAddress(member.Email);
//// 收件人
var serviceMail = new List<string>(){"收件人Email"};
var mailTos = serviceEmail.Value.Split(';');
foreach (var mailTo in mailTos)
{
mailMessage.To.Add(mailTo);
}
//加入附檔
if (model.Attachments.Count() > 0)
{
foreach (string fileName in model.Attachments)
{
Attachment attfile = new Attachment($"{model.Root}\\{fileName}");
mailMessage.Attachments.Add(attfile);
}
}
//寄送mail
this._smtpHelper.SendMail(mailMessage);
//釋放每個附件,才不會Lock住
if (mailMessage.Attachments != null && mailMessage.Attachments.Count > 0)
{
for (int i = 0; i < mailMessage.Attachments.Count; i++)
{
mailMessage.Attachments[i].Dispose();
}
}
return true;
}