1. 代码

  1. /// <summary>
  2. /// 文件上传下载控制器
  3. /// </summary>
  4. public class FileController : ApiController
  5. {
  6. /// <summary>
  7. /// 上传文件
  8. /// </summary>
  9. /// http://192.168.11.67:8077/file
  10. /// <returns></returns>
  11. [HttpPost]
  12. public Task<IList<UploadFile>> Upload()
  13. {
  14. // 获取请求客户端的IP地址
  15. var ipAddr = GetRemoteClientIPAddress();
  16. try
  17. {
  18. //如果文件路径不存在,创建路径
  19. if (!Directory.Exists(UploadFolder)) Directory.CreateDirectory(UploadFolder);
  20. if (Request.Content.IsMimeMultipartContent())
  21. {
  22. // 读取文件数据
  23. var task = Request.Content.ReadAsMultipartAsync().ContinueWith(t =>
  24. {
  25. // 如果上传过程失败或被取消,则返回错误信息
  26. if (t.IsFaulted || t.IsCanceled)
  27. {
  28. throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.InternalServerError, "上传过程出错或被取消"));
  29. }
  30. try
  31. {
  32. // 读取请求数据
  33. var provider = t.Result;
  34. IList<UploadFile> files = new List<UploadFile>();
  35. // 有可能一次上传多个文件,循环保存文件
  36. foreach (var filecontent in provider.Contents)
  37. {
  38. // 读取文件对应的byte数组
  39. var byteArray = filecontent.ReadAsByteArrayAsync().Result;
  40. // 获取文件信息
  41. var fileinfo = GetFileInfo(filecontent, byteArray.Length);
  42. // 保存文件
  43. if (fileinfo.StatusCode == 1)
  44. {
  45. fileinfo.StatusCode = FileHelper.WriteFile(fileinfo.UploadPath, byteArray, fileinfo.UploadName) ? 1 : 0;
  46. }
  47. // 记录文件信息
  48. files.Add(fileinfo);
  49. if (fileinfo.StatusCode == 1)
  50. {
  51. Trace.WriteLine("客户端【" + ipAddr + "】请求上传文件" + fileinfo.UploadPath + "/" + fileinfo.UploadName + "成功");
  52. WriteLog.WriteLogger.Info("客户端【" + ipAddr + "】请求上传文件" + fileinfo.UploadPath + "/" + fileinfo.UploadName + "成功");
  53. }
  54. else
  55. {
  56. Trace.WriteLine("客户端【" + ipAddr + "】请求上传文件" + fileinfo.UploadPath + "/" + fileinfo.UploadName + "失败");
  57. WriteLog.WriteLogger.Info("客户端【" + ipAddr + "】请求上传文件" + fileinfo.UploadPath + "/" + fileinfo.UploadName + "成功");
  58. }
  59. }
  60. return files;
  61. }
  62. catch (Exception ex)
  63. {
  64. Trace.WriteLine("客户端【" + ipAddr + "】上传文件失败!");
  65. WriteLog.WriteLogger.Error("客户端【" + ipAddr + "】上传文件失败!", ex);
  66. throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.InternalServerError, ex));
  67. }
  68. });
  69. return task;
  70. }
  71. else
  72. {
  73. // 请求格式错误
  74. throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType, "请求内容格式不正确!"));
  75. }
  76. }
  77. catch (Exception ex)
  78. {
  79. Trace.WriteLine("客户端【" + ipAddr + "】上传文件失败!");
  80. WriteLog.WriteLogger.Error("客户端【" + ipAddr + "】上传文件失败!", ex);
  81. // 返回异常到请求端
  82. if (ex is HttpResponseException) throw ex; else throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message));
  83. }
  84. }
  85. /// <summary>
  86. /// 下载文件 注意:加上 attachment 这个header,在浏览器访问 url 链接时会弹出下载框
  87. /// http://192.168.11.67:8077/file?name=filename
  88. /// </summary>
  89. /// <param name="name">文件相对路径</param>
  90. /// <returns></returns>
  91. [HttpGet]
  92. public HttpResponseMessage Download(string name)
  93. {
  94. // 客户端请求IP
  95. var ipAddr = GetRemoteClientIPAddress();
  96. var result = new HttpResponseMessage();
  97. // 读取文件
  98. FileInfo file = new FileInfo(Path.Combine(UploadFolder, name.TrimStart('/', '\\')));
  99. if (file.Exists)
  100. {
  101. var isImg = IsImage(name);
  102. // 如果是图片,返回流,否则弹出下载框下载文件
  103. if (isImg)
  104. {
  105. try
  106. {
  107. // 返回图片流
  108. result.StatusCode = HttpStatusCode.OK;
  109. result.Content = new StreamContent(new MemoryStream(File.ReadAllBytes(file.FullName)));
  110. result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/" + name.Substring(name.LastIndexOf('.') + 1));
  111. Trace.WriteLine("客户端【" + ipAddr + "】请求访问图片【" + name + "】成功");
  112. WriteLog.WriteLogger.Info("客户端【" + ipAddr + "】请求访问图片【" + name + "】成功");
  113. }
  114. catch (Exception ex)
  115. {
  116. result.StatusCode = HttpStatusCode.InternalServerError;
  117. Trace.WriteLine("客户端【" + ipAddr + "】请求访问图片【" + name + "】失败");
  118. WriteLog.WriteLogger.Error("客户端【" + ipAddr + "】请求访问图片【" + name + "】失败!", ex);
  119. }
  120. }
  121. else
  122. {
  123. try
  124. {
  125. // 返回文件流
  126. FileStream fs = new FileStream(file.FullName, FileMode.Open);
  127. result = new HttpResponseMessage(HttpStatusCode.OK);
  128. result.Content = new StreamContent(fs);
  129. result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
  130. // 加上attachment,浏览器会自动弹出下载框
  131. result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
  132. result.Content.Headers.ContentDisposition.FileName = file.Name;
  133. //fs.Close();
  134. Trace.WriteLine("客户端【" + ipAddr + "】请求下载文件【" + name + "】成功");
  135. WriteLog.WriteLogger.Info("客户端【" + ipAddr + "】请求下载文件【" + name + "】成功");
  136. }
  137. catch (Exception ex)
  138. {
  139. result = new HttpResponseMessage(HttpStatusCode.InternalServerError);
  140. Trace.WriteLine("客户端【" + ipAddr + "】请求下载文件【" + name + "】失败");
  141. WriteLog.WriteLogger.Error("客户端【" + ipAddr + "】请求下载文件【" + name + "】失败!", ex);
  142. }
  143. }
  144. }
  145. else
  146. {
  147. result.StatusCode = HttpStatusCode.NotFound;
  148. result.Content = new StringContent("找不到文件:" + name);
  149. Trace.WriteLine("服务器上查找不到名为【" + name + "】的文件");
  150. WriteLog.WriteLogger.Info("服务器上查找不到名为【" + name + "】的文件");
  151. }
  152. return result;
  153. }
  154. /// <summary>
  155. /// 上传存储文件夹
  156. /// </summary>
  157. private string UploadFolder = System.Configuration.ConfigurationManager.AppSettings.Get("FileSaveFolder");
  158. /// <summary>
  159. /// 图片后缀
  160. /// </summary>
  161. private string[] PicSuffixArray = { "png", "jpg", "jpeg" };
  162. /// <summary>
  163. /// 返回文件上传时的文件信息
  164. /// </summary>
  165. /// <param name="content">请求标头</param>
  166. /// <param name="sizelength">文件字节流长度</param>
  167. /// <returns></returns>
  168. [NonAction()]
  169. public UploadFile GetFileInfo(HttpContent content, int sizelength)
  170. {
  171. try
  172. {
  173. // 文件保存路径(源路径+前缀路径)
  174. string savepath = UploadFolder;
  175. string filenamestar = "";
  176. if (!string.IsNullOrEmpty(content.Headers.ContentDisposition.FileNameStar))
  177. {
  178. filenamestar = content.Headers.ContentDisposition.FileNameStar.TrimStart('/', '\\').Trim(Path.GetInvalidPathChars());
  179. savepath = Path.Combine(savepath, filenamestar);
  180. }
  181. // 文件名
  182. string filename;
  183. if (!string.IsNullOrEmpty(content.Headers.ContentDisposition.FileName))
  184. {
  185. filename = content.Headers.ContentDisposition.FileName.TrimStart('/', '\\').Trim(Path.GetInvalidFileNameChars());
  186. }
  187. else
  188. {
  189. filename = Guid.NewGuid().ToString();
  190. }
  191. while (File.Exists(Path.Combine(savepath, filename)))
  192. {
  193. // 文件名重复在后面增加日期
  194. filename = filename.Insert(filename.LastIndexOf('.'), "_" + DateTime.Now.ToString("yyyyMMdd"));
  195. }
  196. // 计算文件大小
  197. var size = string.Empty;
  198. if (sizelength > 1024 * 1024)
  199. {
  200. size = (sizelength * 100 / 1024 / 1024 / 100.00).ToString() + "MB";
  201. }
  202. else
  203. {
  204. if (sizelength > 1024)
  205. {
  206. size = (sizelength * 100 / 1024 / 100.00).ToString() + "KB";
  207. }
  208. else
  209. {
  210. size = sizelength.ToString() + "B";
  211. }
  212. }
  213. return new UploadFile(savepath, filename, string.Format("?name={0}", Path.Combine(filenamestar, filename)), size);
  214. }
  215. catch (Exception ex)
  216. {
  217. WriteLog.WriteLogger.Error("上传文件时获取文件信息失败!", ex);
  218. return new UploadFile("", "", "上传失败", "", 1);
  219. }
  220. }
  221. /// <summary>
  222. /// 判断是否为图片
  223. /// </summary>
  224. /// <param name="fileName"></param>
  225. /// <returns></returns>
  226. [NonAction()]
  227. private bool IsImage(string fileName)
  228. {
  229. bool result = false;
  230. try
  231. {
  232. fileName = fileName.ToLower();
  233. var suffix = fileName.Substring(fileName.LastIndexOf(".") + 1);
  234. if (PicSuffixArray.Where(x => x == suffix.ToLower()).Count() > 0)
  235. {
  236. result = true;
  237. }
  238. }
  239. catch (Exception ex)
  240. {
  241. WriteLog.WriteLogger.Error("判断文件" + fileName + "是否图片", ex);
  242. }
  243. return result;
  244. }
  245. /// <summary>
  246. /// 获取请求客户的 ip 地址
  247. /// </summary>
  248. /// <returns></returns>
  249. [NonAction()]
  250. private string GetRemoteClientIPAddress()
  251. {
  252. var result = string.Empty;
  253. try
  254. {
  255. if (Request.Properties.ContainsKey("MS_OwinContext"))
  256. result = ((OwinContext)Request.Properties["MS_OwinContext"]).Request.RemoteIpAddress;
  257. }
  258. catch(Exception ex)
  259. {
  260. WriteLog.WriteLogger.Error("获取请求客户的 ip 地址出错!", ex);
  261. }
  262. return result;
  263. }
  264. }
  265. /// <summary>
  266. /// 上传文件信息
  267. /// </summary>
  268. public class UploadFile
  269. {
  270. /// <summary>
  271. ///
  272. /// </summary>
  273. /// <param name="name">上传时的文件原名</param>
  274. /// <param name="paramurl">上传后访问路径</param>
  275. /// <param name="size">文件大小</param>
  276. /// <param name="namestar">存储的文件路径</param>
  277. public UploadFile(string path, string name, string paramurl, string size, int statuscode = 1)
  278. {
  279. UploadPath = path;
  280. UploadName = name;
  281. ParamUrl = paramurl;
  282. Size = size;
  283. StatusCode = statuscode;
  284. }
  285. /// <summary>
  286. /// 上传文件结果,1是成功
  287. /// </summary>
  288. public int StatusCode { get; set; }
  289. /// <summary>
  290. /// 上传时的文件前缀路径
  291. /// </summary>
  292. public string UploadPath { get; set; }
  293. /// <summary>
  294. /// 上传时的文件名
  295. /// </summary>
  296. public string UploadName { get; set; }
  297. /// <summary>
  298. /// 文件访问的路径参数
  299. /// </summary>
  300. public string ParamUrl { get; set; }
  301. /// <summary>
  302. /// 文件大小
  303. /// </summary>
  304. public string Size { get; set; }
  305. }

2. Http 系列

2.1 发起请求

使用 HttpWebRequest 发起 Http 请求:https://www.cnblogs.com/MichaelLoveSna/p/14501036.html

使用 WebClient 发起 Http 请求 :https://www.cnblogs.com/MichaelLoveSna/p/14501582.html

使用 HttpClient 发起 Http 请求:https://www.cnblogs.com/MichaelLoveSna/p/14501592.html

使用 HttpClient 发起上传文件、下载文件请求:https://www.cnblogs.com/MichaelLoveSna/p/14501603.html

2.2 接受请求

使用 HttpListener 接受 Http 请求:https://www.cnblogs.com/MichaelLoveSna/p/14501628.html

使用 WepApp 接受 Http 请求:https://www.cnblogs.com/MichaelLoveSna/p/14501612.html

使用 WepApp 处理文件上传、下载请求:https://www.cnblogs.com/MichaelLoveSna/p/14501616.html

C# 应用 - 使用 WepApp 处理文件上传、下载请求的更多相关文章

  1. Struts的文件上传下载

    Struts的文件上传下载 1.文件上传 Struts2的文件上传也是使用fileUpload的组件,这个组默认是集合在框架里面的.且是使用拦截器:<interceptor name=" ...

  2. Android okHttp网络请求之文件上传下载

    前言: 前面介绍了基于okHttp的get.post基本使用(http://www.cnblogs.com/whoislcj/p/5526431.html),今天来实现一下基于okHttp的文件上传. ...

  3. Selenium2学习-039-WebUI自动化实战实例-文件上传下载

    通常在 WebUI 自动化测试过程中必然会涉及到文件上传的自动化测试需求,而开发在进行相应的技术实现是不同的,粗略可划分为两类:input标签类(类型为file)和非input标签类(例如:div.a ...

  4. 艺萌文件上传下载及自动更新系统(基于networkComms开源TCP通信框架)

    1.艺萌文件上传下载及自动更新系统,基于Winform技术,采用CS架构,开发工具为vs2010,.net2.0版本(可以很容易升级为3.5和4.0版本)开发语言c#. 本系统主要帮助客户学习基于TC ...

  5. 艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输)(一)

    艺萌TCP文件上传下载及自动更新系统介绍(TCP文件传输) 该系统基于开源的networkComms通讯框架,此通讯框架以前是收费的,目前已经免费并开元,作者是英国的,开发时间5年多,框架很稳定. 项 ...

  6. ssh框架文件上传下载

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. SpringMVC——返回JSON数据&&文件上传下载

    --------------------------------------------返回JSON数据------------------------------------------------ ...

  8. 【FTP】FTP文件上传下载-支持断点续传

    Jar包:apache的commons-net包: 支持断点续传 支持进度监控(有时出不来,搞不清原因) 相关知识点 编码格式: UTF-8等; 文件类型: 包括[BINARY_FILE_TYPE(常 ...

  9. NetworkComms 文件上传下载和客户端自动升级(非开源)

    演示程序下载地址:http://pan.baidu.com/s/1geVfmcr 淘宝地址:https://shop183793329.taobao.com 联系QQ号:3201175853 许可:购 ...

随机推荐

  1. 大数据开发-从cogroup的实现来看join是宽依赖还是窄依赖

    前面一篇文章提到大数据开发-Spark Join原理详解,本文从源码角度来看cogroup 的join实现 1.分析下面的代码 import org.apache.spark.rdd.RDD impo ...

  2. PAT L2-004. 这是二叉搜索树吗?【前序遍历转化为后序遍历】

    一棵二叉搜索树可被递归地定义为具有下列性质的二叉树:对于任一结点, 其左子树中所有结点的键值小于该结点的键值: 其右子树中所有结点的键值大于等于该结点的键值: 其左右子树都是二叉搜索树. 所谓二叉搜索 ...

  3. codeforces 875B

    B. Sorting the Coins time limit per test 1 second memory limit per test 512 megabytes input standard ...

  4. 基金术语 All In One

    基金术语 All In One GP.LP.PE.VC.FOF LP 有限合伙人(Limited Partner, LP):我们可以简单的理解为出资人. 很多时候,一个项目需要投资上千万乃至数个亿的资 ...

  5. 加密算法大全图解 :密码体系,对称加密算法,非对称加密算法,消息摘要, Base64,数字签名,RSA,DES,MD5,AES,SHA,ElGamal,

    1. 加密算法大全: ***************************************************************************************** ...

  6. CSS ::marker All In One

    CSS ::marker All In One CSS pseudo element / CSS 伪元素 /* user agent stylesheet */ ::marker { unicode- ...

  7. Alexa website ranking

    Alexa website ranking The top 500 sites on the web https://www.alexa.com/topsites https://www.alexa. ...

  8. js to svg flowchart

    js to svg flowchart flowchart https://flowchart.js.org/ https://github.com/adrai/flowchart.js https: ...

  9. Flutter: 判断是Android还是Ios

    /// 在ui中使用下面的这个判断 Theme.of(context).platform == TargetPlatform.android /// 而不是 import 'dart:io' Plat ...

  10. TypeScript——02——TS基本数据类型介绍和使用

    一,TS的数据类型 ES6的数据类型: 6种基本数据类型 Boolean Number String Symbol undefined null 3种引用类型 Array Function Objec ...