Web Api 上传图片,解决上传图片无格式
制作这个功能时,找了很多资料,不过忘记了地址,所以就不一一放连接了,
直接上代码吧!
1. 首先新建一个上传的控制器
/// <summary>
/// 上传
/// </summary>
[RoutePrefix("api/Upload")]
public class UploadController : ApiController
2. 有控制器了,肯定要有一个接受的地方
/// <summary>
/// 上传图片
/// </summary>
/// <returns></returns>
/// <exception cref="System.Web.Http.HttpResponseException"></exception>
[HttpPost, Route("Image")]
public async Task<HttpResponseMessage> Post()
3. 重要代码,自己扩展(重写) MultipartFormDataStreamProvider 类
// We implement MultipartFormDataStreamProvider to override the filename of File which
// will be stored on server, or else the default name will be of the format like Body-
// Part_{GUID}. In the following implementation we simply get the FileName from
// ContentDisposition Header of the Request Body.
public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
{
/// <summary>
/// 用户编号由于生产用户图片的前缀
/// <para>如用户为 01,01-12345467878</para>
/// </summary>
public string UserId { get; set; }
/// <summary>
/// 图片名称
/// </summary>
public string ImageName { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="CustomMultipartFormDataStreamProvider"/> class.
/// </summary>
/// <param name="userId">The user identifier.</param>
/// <param name="imageName"></param>
/// <param name="path">The path.</param>
public CustomMultipartFormDataStreamProvider(string userId, string imageName, string path)
: base(path)
{
this.UserId = userId;
this.ImageName = imageName;
}
/// <summary>
/// 获取本地文件名,该文件名将与用于创建存储当前 MIME 正文部分内容的绝对文件名的根路径组合在一起。
/// </summary>
/// <param name="headers">当前 MIME 正文部分的标头。</param>
/// <returns>
/// 不包含路径部分的相对文件名。
/// </returns>
public override string GetLocalFileName(HttpContentHeaders headers)
{
// 保存的图片名称
var serverImageName = "";
if (!string.IsNullOrEmpty(serverImageName))
{
serverImageName = this.ImageName;
}
else
{
// 新增时获取文件名
serverImageName = headers.ContentDisposition.FileName.Replace("\"", string.Empty);
// 用 . 拆分
// 取最后的图片类型
var splitArr = serverImageName.Split('.');
var nowTime = DateTime.Now.ToString("yyyyMMdd");
serverImageName = this.UserId + "-" + nowTime + "." + splitArr.LastOrDefault();
}
return serverImageName;
}
}
4. 类中所有的源代码都在下面:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; using System.Web; using System.Web.Http; namespace Payu_File.Controllers { /// <summary> /// 上传 /// </summary> [RoutePrefix("api/Upload")] public class UploadController : ApiController { /// <summary> /// 上传图片 /// </summary> /// <returns></returns> /// <exception cref="System.Web.Http.HttpResponseException"></exception> [HttpPost, Route("Image")] public async Task<HttpResponseMessage> Post() { // Check whether the POST operation is MultiPart? // 检查该请求是否含有multipart/form-data if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } // 检测文件大小 var request = HttpContext.Current.Request; // 图片文件 var imageFile = request.Files.Get(0); // 图片文件名称 var imageFileName = imageFile.FileName; // 图片文件内容类型 var imageFileType = imageFile.ContentType.ToLower(); var imageTypeList = new List<string>() { "gif", "jpg", "jpeg", "png", "bmp" }; // 检测类型 if (!imageFileType.Contains("image/") || !imageTypeList.Contains(imageFileName.Split('.').LastOrDefault())) { return Request.CreateResponse(HttpStatusCode.OK, new { Success = false, Message = "请上传图片格式的文件,如:gif,jpg,jpeg,png,bmp 结尾的文件" }); } // 检测文件大小 // 最大为 10M if (imageFile.ContentLength >= 10485760) { return Request.CreateResponse(HttpStatusCode.OK, new { Success = false, Message = "图片大小不能超过 10M" }); } // 检测是否有用户编号 if (!request.Form.AllKeys.Contains("UserId")) { return Request.CreateResponse(HttpStatusCode.OK, new { Success = false, Message = "用户还未登录" }); } // 图片名称 // 用于替换同名的文件 var imageName = ""; // 检测是否有 if (request.Form.AllKeys.Contains("ImageName")) { imageName = request.Form.Get("ImageName"); } // 用户编号 // 用户生成用户图片的前缀 var userId = request.Form.Get("UserId"); if (string.IsNullOrEmpty(userId)) { return Request.CreateResponse(HttpStatusCode.OK, new { Success = false, Message = "用户还未登录" }); } // 文件路径 // 默认为 Imager/Portrait var filePath = "Images/Portrait"; // 如果指定图片路径,那么将以指定的路径存储 if (request.Form.AllKeys.Contains("ImageFilePath")) { var tempPath = request.Form.Get("ImageFilePath"); if (!String.IsNullOrEmpty(tempPath)) { filePath = tempPath; } } // Prepare CustomMultipartFormDataStreamProvider in which our multipart form // data will be loaded. var fileSaveLocation = HttpContext.Current.Server.MapPath("~/" + filePath); var provider = new CustomMultipartFormDataStreamProvider(userId, imageName, fileSaveLocation); var files = new List<string>(); try { // Read all contents of multipart message into CustomMultipartFormDataStreamProvider. await Request.Content.ReadAsMultipartAsync(provider); files.AddRange(provider.FileData.Select(file => Path.GetFileName(file.LocalFileName))); // Send OK Response along with saved file names to the client. return Request.CreateResponse(HttpStatusCode.OK, new { Success = true, Message = "上传成功!", ImageName = files.FirstOrDefault() }); } catch (Exception e) { return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e); } } } // We implement MultipartFormDataStreamProvider to override the filename of File which // will be stored on server, or else the default name will be of the format like Body- // Part_{GUID}. In the following implementation we simply get the FileName from // ContentDisposition Header of the Request Body. public class CustomMultipartFormDataStreamProvider : MultipartFormDataStreamProvider { /// <summary> /// 用户编号由于生产用户图片的前缀 /// <para>如用户为 01,01-12345467878</para> /// </summary> public string UserId { get; set; } /// <summary> /// 图片名称 /// </summary> public string ImageName { get; set; } /// <summary> /// Initializes a new instance of the <see cref="CustomMultipartFormDataStreamProvider"/> class. /// </summary> /// <param name="userId">The user identifier.</param> /// <param name="imageName"></param> /// <param name="path">The path.</param> public CustomMultipartFormDataStreamProvider(string userId, string imageName, string path) : base(path) { this.UserId = userId; this.ImageName = imageName; } /// <summary> /// 获取本地文件名,该文件名将与用于创建存储当前 MIME 正文部分内容的绝对文件名的根路径组合在一起。 /// </summary> /// <param name="headers">当前 MIME 正文部分的标头。</param> /// <returns> /// 不包含路径部分的相对文件名。 /// </returns> public override string GetLocalFileName(HttpContentHeaders headers) { // 保存的图片名称 var serverImageName = ""; if (!string.IsNullOrEmpty(serverImageName)) { serverImageName = this.ImageName; } else { // 新增时获取文件名 serverImageName = headers.ContentDisposition.FileName.Replace("\"", string.Empty); // 用 . 拆分 // 取最后的图片类型 var splitArr = serverImageName.Split('.'); var nowTime = DateTime.Now.ToString("yyyyMMdd"); serverImageName = this.UserId + "-" + nowTime + "." + splitArr.LastOrDefault(); } return serverImageName; } } }