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;
}
}
}
Web Api 上传图片,解决上传图片无格式的更多相关文章
- 解决.NET Web API生成的Help无Controller说明&服务端接收不到请求
今天在用.NET Web API写一个接口的时候遇到一个问题.在Controller中新加了一个方法,客户端就不能请求接口了,当时建WEB API项目是用的VS默认设置,在服务端打断点一直没有进去,而 ...
- 让ASP.NET Web API支持POST纯文本格式(text/plain)的数据
今天在web api中遇到了这样一个问题,虽然api的参数类型是string,但只能接收post body中json格式的string,不能接收原始string. web api是这样定义的: pub ...
- 用Ajax调用web api,解决URL太长的问题;
本来是用的WCF,但是服务需要多种方式调用(后台+前端Ajax),最终局面就是我在WCF每个服务中都判断一下↓ #region 解决接收不到Ajax中传来的参数... if (jsonParames ...
- ASP.NET Web API 2.0 统一响应格式
传统实现 在搭建 Web API 服务的时候,针对客户端请求,我们一般都会自定义响应的 JSON 格式,比如: { "Data" : { "Id" : 100, ...
- [Web API] 如何让 Web API 统一回传格式以及例外处理[转]
[Web API] 如何让 Web API 统一回传格式以及例外处理 前言 当我们在开发 Web API 时,一般的情况下每个 API 回传的数据型态或格式都不尽相同,如果你的项目从头到尾都是由你一个 ...
- [Web API] 如何让 Web API 统一回传格式以及例外处理
[Web API] 如何让 Web API 统一回传格式以及例外处理 前言 当我们在开发 Web API 时,一般的情况下每个 API 回传的数据型态或格式都不尽相同,如果你的项目从头到尾都是由你一个 ...
- "Asp.Net Web Api MediaTypeFormatter Error for x-www-formurlencoded data" 解决方法
遇到标题中所说的问题原因是使用 jQuery AJAX 以 POST 方式调用 Asp.Net Web API .解决办法请看以下代码中有注释的部分. public static class WebA ...
- Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群
Redis总结(五)缓存雪崩和缓存穿透等问题 前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...
- Web API系列(二)接口安全和参数校验
以前简单介绍过web api 的设计,但是还是有很多朋友问我,如何合理的设计和实现web api.比如,接口安全,异常处理,统一数据返回等问题.所以有必要系统的总结总结 web api 的设计和实现. ...
- 集成架构:对比 Web API 与面向服务的架构和企业应用程序集成(转)
http://kb.cnblogs.com/page/521644/ 摘要:总体上讲,SOA 和 Web API 似乎解决的是同一个问题:以实时的.可重用的方式公开业务功能.本教程将分析这些举措有何不 ...
随机推荐
- pc, 手机全屏
全屏 1 div{ position:absolute/relative/fixed; top:0; bottom:0; left:0; right:0;} 2 <!doctype html& ...
- [转载]MySQL将DateTime时间类型格式化
DATE_FORMAT(date,format) 根据format字符串安排date值的格式. select from_unixtime(time,'%Y-%m-%d %H:%i:%s'); ...
- MySQL删除表数据
原文请点这里 在MySQL中有两种方法可以删除数据,一种是DELETE语句,另一种是TRUNCATE TABLE语句.DELETE语句可以通过WHERE对要删除的记录进行选择.而使用TRUNCATE ...
- Java中final的作用
Java中Final可以被用于变量,方法,类.具体来说: 1, Final 变量 修饰主类型时,制定变量为常数,不希望被改变 修饰类类型时,表示变量的句柄不变,不能被指定指向新的变量 修饰参数时,参数 ...
- 集合ArrayList
/*集合ArrayList * 例如: * 1.创建:ArrayList<Egg> myList = new ArrayList<Egg>(); * Egg类型的集合 ...
- iOS ShareSDK 使用
流量精灵软件中,也在大部分地方使用到了shareSDK 这个三方开源库.具体的有两种需求 a.弹出所有分享模块 b.只弹出指定的平台:如微信朋友圈和QQ . 配置方法,三方库中也很详细,这里我只有写出 ...
- BZOJ 2763 分层图最短路
突然发现我不会分层图最短路,写一发. 就是同层中用双向边相连,用单向边连下一层 #include <cstdio> #include <algorithm> #include ...
- Spring MVC的常用注解
一.@Controller @Controller 负责注册一个bean 到spring 上下文中,bean 的ID 默认为类名称开头字母小写,你也可以自己指定. 二.@RequestMapping ...
- c语言求平面上2个坐标点的直线距离、求俩坐标直线距离作为半径的圆的面积、递归、菲波那次数列、explode
#include <stdio.h> #include <math.h> #include <string.h> char explode( char * str ...
- oop、configparser、xml模块
本节大纲:一:在python中,有两种编程思想.1:函数式编程.2:oop.无论是函数式编程还是oop都是相辅相成.并不是说oop比函数式编程就好.各有各的优缺点.在其他语言中java等只能以面向对象 ...