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;
		}
	}
}

  

 

posted @ 2015-11-10 11:42  胡一飘  阅读(1010)  评论(0编辑  收藏  举报