在网络编程过程中需要向服务器上传文件。

Multipart/form-data是上传文件的一种方式。

        /// <summary>
/// 上传工程文件
/// </summary>
/// <returns></returns>
public async Task<HttpResponseMessage> UploadProjectFile()
{
ProjectFile postData = new ProjectFile();
IEnumerable<string> stringValues;
//获取请求头文件相关参数
Request.Headers.TryGetValues("token", out stringValues);
postData.token = stringValues.FirstOrDefault(); Request.Headers.TryGetValues("uid", out stringValues);
postData.uid = int.Parse(stringValues.FirstOrDefault()); Request.Headers.TryGetValues("project_id", out stringValues);
postData.project_id = int.Parse(stringValues.FirstOrDefault()); Request.Headers.TryGetValues("md5", out stringValues);
postData.md5 = stringValues.FirstOrDefault(); Request.Headers.TryGetValues("file_name", out stringValues);
postData.file_name = stringValues.FirstOrDefault();
//验证Token
var result = CheckToken(postData.token);
if (!result)
{
return CreateResponseError(, "请求拒绝");
}
//获取文件名,这里的文件名必须带扩展名
string fileName = postData.file_name; int projectId = postData.project_id;
//获取应用程序的当前工作目录
string rootPath = HostingEnvironment.MapPath("~/");
//通过Path类的Combine方法可以合并路径。获取当前工程文件夹地址
string directoryPath = Path.Combine(rootPath, "BgerProject", projectId.ToString());
//创建目录时如果目录已存在,则不会重新创建目录,且不会报错。创建目录时会自动创建路径中各级不存在的目录。
Directory.CreateDirectory(directoryPath);
//获取当前工程文件地址
string filePath = Path.Combine(directoryPath, fileName);
if (Request.Content.IsMimeMultipartContent())
{
Dictionary<string, string> dic = new Dictionary<string, string>();
var provider = new MultipartFormDataMemoryStreamProvider(); await Request.Content.ReadAsMultipartAsync(provider);
foreach (var item in provider.FileContents)
{
//Trace.WriteLine(item.Headers.ContentDisposition.FileName);//获取上传文件实际的文件名
//Trace.WriteLine("Server file path: " + item.LocalFileName);//获取上传文件在服务上默认的文件名
var stream = await item.ReadAsStreamAsync();
if (Path.GetExtension(item.Headers.ContentDisposition.FileName.Replace("\"", "")) == ".mp4")
{
//通过正则表达式判断是视频还是音频
Regex regex = new Regex("voice", RegexOptions.Compiled);
Match m = regex.Match(item.Headers.ContentDisposition.Name.ToLower());
if (m.Success)
{
//音频直接保存处理 //判断是否已存在该音频
if (!File.Exists(filePath))
{
using (StreamWriter sw = new StreamWriter(filePath))
{
stream.CopyTo(sw.BaseStream);
sw.Flush();
}
}
}
else
{
//视频进行压缩处理
//保存原片(如果路径不存在,创建路径) using (StreamWriter sw = new StreamWriter(filePath))
{
stream.CopyTo(sw.BaseStream);
sw.Flush();
}
//压缩并保存上传的视频
//压缩后的存放路径(如果路径不存在,创建路径)
////判断是否已存在该视频
//if (!File.Exists(filePath))
//{
// //压缩保存视频
// if (!FFMPEGHelper.CreateNewVideo(originalFilePath, filePath))
// {
// continue;
// };
//}
}
}
else
{
//保存原片(如果路径不存在,创建路径) using (StreamWriter sw = new StreamWriter(filePath))
{
stream.CopyTo(sw.BaseStream);
sw.Flush();
}
//压缩并保存上传的图片
//压缩后的存放路径(如果路径不存在,创建路径) ////判断是否已存在该图片
//if (!File.Exists(filePath))
//{
// var pxLimit = 481;
// //判断是否需要压缩
// System.Drawing.Image iSource = System.Drawing.Image.FromFile(originalFilePath);
// if (iSource.Width <= pxLimit || iSource.Height <= pxLimit)
// {
// //无需压缩
// System.IO.File.Copy(originalFilePath, filePath);
// }
// else
// {
// var min = Math.Min((int)iSource.Width, (int)iSource.Height);
// if (min > pxLimit)
// {
// //缩放倍率
// var rate = (double)pxLimit / min;
// var width = (int)Math.Ceiling(rate * (double)iSource.Width);
// var height = (int)Math.Ceiling(rate * (double)iSource.Height); // //压缩保存图片
// if (!ImageHelper.GetPicThumbnail(originalFilePath, filePath, height, width, 100))
// {
// continue;
// };
// }
// }
//}
}
}
return CreateResponse("请求成功"); }
return CreateResponseError(,"缺少MIME内容"); }
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks; namespace BgerServer.Models
{
/// <summary>
/// 与MultipartFormDataStreamProvider对应,但不将文件直接存入指定位置,而是需要自己指定数据流如何保存
/// </summary>
public class MultipartFormDataMemoryStreamProvider : MultipartStreamProvider
{
private NameValueCollection _formData = new NameValueCollection();
private Collection<bool> _isFormData = new Collection<bool>();
/// <summary>
/// 获取文件对应的HttpContent集合,文件如何读取由实际使用方确定,可以ReadAsByteArrayAsync,也可以ReadAsStreamAsync
/// </summary>
public Collection<HttpContent> FileContents
{
get
{
if (this._isFormData.Count != this.Contents.Count)//两者总数不一致,认为未执行过必须的Request.Content.ReadAsMultipartAsync(provider)方法
{
throw new InvalidOperationException("System.Net.Http.HttpContentMultipartExtensions.ReadAsMultipartAsync must be called first!");
}
return new Collection<HttpContent>(this.Contents.Where((ct, idx) => !this._isFormData[idx]).ToList());
}
}
/// <summary>Gets a <see cref="T:System.Collections.Specialized.NameValueCollection" /> of form data passed as part of the multipart form data.</summary>
/// <returns>The <see cref="T:System.Collections.Specialized.NameValueCollection" /> of form data.</returns>
public NameValueCollection FormData
{
get
{
return this._formData;
}
}
public override async Task ExecutePostProcessingAsync()
{
for (var i = ; i < this.Contents.Count; i++)
{
if (!this._isFormData[i])//非文件
{
continue;
}
var formContent = this.Contents[i];
ContentDispositionHeaderValue contentDisposition = formContent.Headers.ContentDisposition;
string formFieldName = UnquoteToken(contentDisposition.Name) ?? string.Empty;
string formFieldValue = await formContent.ReadAsStringAsync();
this.FormData.Add(formFieldName, formFieldValue);
}
}
public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
{
if (parent == null)
{
throw new ArgumentNullException("parent");
}
if (headers == null)
{
throw new ArgumentNullException("headers");
}
ContentDispositionHeaderValue contentDisposition = headers.ContentDisposition;
if (contentDisposition == null)
{
throw new InvalidOperationException("Content-Disposition is null");
}
this._isFormData.Add(string.IsNullOrEmpty(contentDisposition.FileName));
return new MemoryStream();
}
/// <summary>
/// 复制自 System.Net.Http.FormattingUtilities 下同名方法,因为该类为internal,不能在其它命名空间下被调用
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
private static string UnquoteToken(string token)
{
if (string.IsNullOrWhiteSpace(token))
{
return token;
}
if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > )
{
return token.Substring(, token.Length - );
}
return token;
}
}
}

ASP.NET 服务端接收Multipart/form-data文件的更多相关文章

  1. Asp.Net_ 服务端向客户端写JavaScript脚本

    在Asp.net 服务端处理脚本,一般都用 ClientScriptManager ,即web窗体服务端的this.ClientScript.该对象比较常用的方法: 1.RegisterArrayDe ...

  2. C# TCP socket发送大数据包时,接收端和发送端数据不一致 服务端接收Receive不完全

    简单的c# TCP通讯(TcpListener) C# 的TCP Socket (同步方式) C# 的TCP Socket (异步方式) C# 的tcp Socket设置自定义超时时间 C# TCP ...

  3. 自己实现FormsAuthentication.SetAuthCookie方法,怎样在ASP.NET服务端代码中删除客户端Cookie

    如何手动设置AuthCookie ASP.NET中实现可以自己实现FormsAuthentication.SetAuthCookie方法,控制更为灵活 /// <summary> /// ...

  4. android如何与asp.net服务端共享session

    近期需要实现一个功能,就是需要通过发送短信进行注册,现在想把短信验证码放到服务器的session值中,当客户端收到短信并提交短信码时由asp.net服务端进行判断,那么如何共享这个session那么需 ...

  5. MVC文件上传04-使用客户端jQuery-File-Upload插件和服务端Backload组件实现多文件异步上传

    本篇使用客户端jQuery-File-Upload插件和服务端Badkload组件实现多文件异步上传.MVC文件上传相关兄弟篇: MVC文件上传01-使用jquery异步上传并客户端验证类型和大小  ...

  6. 微信小程序开发之多图片上传+服务端接收

    前言: 业务需求,这次需要做一个小程序同时选中三张图片一起上传到服务端,后端使用的.NET WEBAPI接收数据保存. 使用技术: 在这章中将会使用到微信小程序wx.uploadFile(Object ...

  7. java httpclient发送json 请求 ,go服务端接收

    /***java客户端发送http请求*/package com.xx.httptest; /** * Created by yq on 16/6/27. */ import java.io.IOEx ...

  8. [转]微信小程序开发(二)图片上传+服务端接收

    本文转自:http://blog.csdn.net/sk719887916/article/details/54312573 文/YXJ 地址:http://blog.csdn.net/sk71988 ...

  9. tcp syn-synack-ack 服务端接收ack

    TCP 服务端 接收到ack tcp_v4_rcv() -> tcp_v4_do_rcv() -> tcp_v4_hnd_req() + tcp_child_process()tcp_v4 ...

随机推荐

  1. windows下 ionic 打包app --以安卓版本为例

    环境安装 1.nodejs 安装版本5.7,尽量不要安装太新的版本,因为可能会出现兼容性问题,一开始本人安装的是6.+的版本,后来出现问题的,马上换回5.7的,问题就不会出现了. 安装教程网上教程很多 ...

  2. xgboost与gdbt的不同和优化

    XGBoost是GBDT算法的一种变种,是一种常用的有监督集成学习算法:是一种 伸缩性强.便捷的可并行构建模型的Gradient Boosting算法 Xgboost和GBDT不同之处 xgboost ...

  3. MySQL数据库之表的增删改查

    目录 MySQL数据库之表的增删改查 1 引言 2 创建表 3 删除表 4 修改表 5 查看表 6 复制表 MySQL数据库之表的增删改查 1 引言 1.MySQL数据库中,数据库database就是 ...

  4. MSIL实用指南-方法的调用

    方法调用指令主要有Call和Callvirt. 调用static或sealed修饰的方法,用Call指令. 调用virtual或abstract修饰的方法,用Callvirt指令. 代码实例: ilG ...

  5. 使用fine-uploader上传文件

    步骤1:下载fine-uploader 步骤2:加入引用 <link href="/fine-uploader/fine-uploader-gallery.min.css" ...

  6. 一 安装docker(详解)

    一.安装docker 1 Docker 要求 CentOS 系统的内核版本高于 3.10 执行命令:uname -r 2 添加yum源: yum-config-manager --add-repo h ...

  7. dotnet core各rpc组件的性能测试

    一般rpc通讯组件都具有高性特性,因为大部分rpc都是基于二进制和连接复用的特点,相对于HTTP(2.0以下的版本)来说有着很大的性能优势,非常适合服务间通讯交互.本文针对了dotnet core平台 ...

  8. 推荐一个比 ls 命令速度快 100 倍的文件目录浏览神器

    本文首发于:微信公众号「运维之美」,公众号 ID:Hi-Linux. 「运维之美」是一个有情怀.有态度,专注于 Linux 运维相关技术文章分享的公众号.公众号致力于为广大运维工作者分享各类技术文章和 ...

  9. Git学习笔记-相关命令记录

    内容来自:https://www.liaoxuefeng.com/wiki/896043488029600/896067074338496 1.Linux安装Git 首先,你可以试着输入git,看看系 ...

  10. HDU-2018多校7th-1011-Swordsman 附杜教fread代码

    HDU-6396 题意: 背景是打怪升级的故事,有k个不同属性的初始的能力值,每只怪物也有相同个数的能力值,你只能放倒k个能力值都比怪物大的,每放倒一个怪物,都可以得到相应的k个能力值. 思路: 根据 ...