1. 代码

/// <summary>
/// 文件上传下载控制器
/// </summary>
public class FileController : ApiController
{
/// <summary>
/// 上传文件
/// </summary>
/// http://192.168.11.67:8077/file
/// <returns></returns>
[HttpPost]
public Task<IList<UploadFile>> Upload()
{
// 获取请求客户端的IP地址
var ipAddr = GetRemoteClientIPAddress(); try
{
//如果文件路径不存在,创建路径
if (!Directory.Exists(UploadFolder)) Directory.CreateDirectory(UploadFolder); if (Request.Content.IsMimeMultipartContent())
{
// 读取文件数据
var task = Request.Content.ReadAsMultipartAsync().ContinueWith(t =>
{
// 如果上传过程失败或被取消,则返回错误信息
if (t.IsFaulted || t.IsCanceled)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.InternalServerError, "上传过程出错或被取消"));
} try
{
// 读取请求数据
var provider = t.Result; IList<UploadFile> files = new List<UploadFile>();
// 有可能一次上传多个文件,循环保存文件
foreach (var filecontent in provider.Contents)
{
// 读取文件对应的byte数组
var byteArray = filecontent.ReadAsByteArrayAsync().Result;
// 获取文件信息
var fileinfo = GetFileInfo(filecontent, byteArray.Length);
// 保存文件
if (fileinfo.StatusCode == 1)
{
fileinfo.StatusCode = FileHelper.WriteFile(fileinfo.UploadPath, byteArray, fileinfo.UploadName) ? 1 : 0;
}
// 记录文件信息
files.Add(fileinfo); if (fileinfo.StatusCode == 1)
{
Trace.WriteLine("客户端【" + ipAddr + "】请求上传文件" + fileinfo.UploadPath + "/" + fileinfo.UploadName + "成功");
WriteLog.WriteLogger.Info("客户端【" + ipAddr + "】请求上传文件" + fileinfo.UploadPath + "/" + fileinfo.UploadName + "成功");
}
else
{
Trace.WriteLine("客户端【" + ipAddr + "】请求上传文件" + fileinfo.UploadPath + "/" + fileinfo.UploadName + "失败");
WriteLog.WriteLogger.Info("客户端【" + ipAddr + "】请求上传文件" + fileinfo.UploadPath + "/" + fileinfo.UploadName + "成功");
}
}
return files;
}
catch (Exception ex)
{
Trace.WriteLine("客户端【" + ipAddr + "】上传文件失败!");
WriteLog.WriteLogger.Error("客户端【" + ipAddr + "】上传文件失败!", ex);
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.InternalServerError, ex));
}
});
return task;
}
else
{
// 请求格式错误
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.UnsupportedMediaType, "请求内容格式不正确!"));
}
}
catch (Exception ex)
{
Trace.WriteLine("客户端【" + ipAddr + "】上传文件失败!");
WriteLog.WriteLogger.Error("客户端【" + ipAddr + "】上传文件失败!", ex);
// 返回异常到请求端
if (ex is HttpResponseException) throw ex; else throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message));
}
} /// <summary>
/// 下载文件 注意:加上 attachment 这个header,在浏览器访问 url 链接时会弹出下载框
/// http://192.168.11.67:8077/file?name=filename
/// </summary>
/// <param name="name">文件相对路径</param>
/// <returns></returns>
[HttpGet]
public HttpResponseMessage Download(string name)
{
// 客户端请求IP
var ipAddr = GetRemoteClientIPAddress(); var result = new HttpResponseMessage();
// 读取文件
FileInfo file = new FileInfo(Path.Combine(UploadFolder, name.TrimStart('/', '\\')));
if (file.Exists)
{
var isImg = IsImage(name);
// 如果是图片,返回流,否则弹出下载框下载文件
if (isImg)
{
try
{
// 返回图片流
result.StatusCode = HttpStatusCode.OK;
result.Content = new StreamContent(new MemoryStream(File.ReadAllBytes(file.FullName)));
result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/" + name.Substring(name.LastIndexOf('.') + 1));
Trace.WriteLine("客户端【" + ipAddr + "】请求访问图片【" + name + "】成功");
WriteLog.WriteLogger.Info("客户端【" + ipAddr + "】请求访问图片【" + name + "】成功");
}
catch (Exception ex)
{
result.StatusCode = HttpStatusCode.InternalServerError;
Trace.WriteLine("客户端【" + ipAddr + "】请求访问图片【" + name + "】失败");
WriteLog.WriteLogger.Error("客户端【" + ipAddr + "】请求访问图片【" + name + "】失败!", ex);
}
}
else
{
try
{
// 返回文件流
FileStream fs = new FileStream(file.FullName, FileMode.Open);
result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(fs);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
// 加上attachment,浏览器会自动弹出下载框
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = file.Name;
//fs.Close();
Trace.WriteLine("客户端【" + ipAddr + "】请求下载文件【" + name + "】成功");
WriteLog.WriteLogger.Info("客户端【" + ipAddr + "】请求下载文件【" + name + "】成功");
}
catch (Exception ex)
{
result = new HttpResponseMessage(HttpStatusCode.InternalServerError);
Trace.WriteLine("客户端【" + ipAddr + "】请求下载文件【" + name + "】失败");
WriteLog.WriteLogger.Error("客户端【" + ipAddr + "】请求下载文件【" + name + "】失败!", ex);
}
}
}
else
{
result.StatusCode = HttpStatusCode.NotFound;
result.Content = new StringContent("找不到文件:" + name);
Trace.WriteLine("服务器上查找不到名为【" + name + "】的文件");
WriteLog.WriteLogger.Info("服务器上查找不到名为【" + name + "】的文件");
}
return result;
} /// <summary>
/// 上传存储文件夹
/// </summary>
private string UploadFolder = System.Configuration.ConfigurationManager.AppSettings.Get("FileSaveFolder"); /// <summary>
/// 图片后缀
/// </summary>
private string[] PicSuffixArray = { "png", "jpg", "jpeg" }; /// <summary>
/// 返回文件上传时的文件信息
/// </summary>
/// <param name="content">请求标头</param>
/// <param name="sizelength">文件字节流长度</param>
/// <returns></returns>
[NonAction()]
public UploadFile GetFileInfo(HttpContent content, int sizelength)
{
try
{
// 文件保存路径(源路径+前缀路径)
string savepath = UploadFolder;
string filenamestar = "";
if (!string.IsNullOrEmpty(content.Headers.ContentDisposition.FileNameStar))
{
filenamestar = content.Headers.ContentDisposition.FileNameStar.TrimStart('/', '\\').Trim(Path.GetInvalidPathChars());
savepath = Path.Combine(savepath, filenamestar);
}
// 文件名
string filename;
if (!string.IsNullOrEmpty(content.Headers.ContentDisposition.FileName))
{
filename = content.Headers.ContentDisposition.FileName.TrimStart('/', '\\').Trim(Path.GetInvalidFileNameChars());
}
else
{
filename = Guid.NewGuid().ToString();
}
while (File.Exists(Path.Combine(savepath, filename)))
{
// 文件名重复在后面增加日期
filename = filename.Insert(filename.LastIndexOf('.'), "_" + DateTime.Now.ToString("yyyyMMdd"));
}
// 计算文件大小
var size = string.Empty;
if (sizelength > 1024 * 1024)
{
size = (sizelength * 100 / 1024 / 1024 / 100.00).ToString() + "MB";
}
else
{
if (sizelength > 1024)
{
size = (sizelength * 100 / 1024 / 100.00).ToString() + "KB";
}
else
{
size = sizelength.ToString() + "B";
}
}
return new UploadFile(savepath, filename, string.Format("?name={0}", Path.Combine(filenamestar, filename)), size);
}
catch (Exception ex)
{
WriteLog.WriteLogger.Error("上传文件时获取文件信息失败!", ex);
return new UploadFile("", "", "上传失败", "", 1);
}
} /// <summary>
/// 判断是否为图片
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
[NonAction()]
private bool IsImage(string fileName)
{
bool result = false;
try
{
fileName = fileName.ToLower();
var suffix = fileName.Substring(fileName.LastIndexOf(".") + 1);
if (PicSuffixArray.Where(x => x == suffix.ToLower()).Count() > 0)
{
result = true;
}
}
catch (Exception ex)
{
WriteLog.WriteLogger.Error("判断文件" + fileName + "是否图片", ex);
}
return result;
} /// <summary>
/// 获取请求客户的 ip 地址
/// </summary>
/// <returns></returns>
[NonAction()]
private string GetRemoteClientIPAddress()
{
var result = string.Empty; try
{
if (Request.Properties.ContainsKey("MS_OwinContext"))
result = ((OwinContext)Request.Properties["MS_OwinContext"]).Request.RemoteIpAddress;
}
catch(Exception ex)
{
WriteLog.WriteLogger.Error("获取请求客户的 ip 地址出错!", ex);
} return result;
}
} /// <summary>
/// 上传文件信息
/// </summary>
public class UploadFile
{
/// <summary>
///
/// </summary>
/// <param name="name">上传时的文件原名</param>
/// <param name="paramurl">上传后访问路径</param>
/// <param name="size">文件大小</param>
/// <param name="namestar">存储的文件路径</param>
public UploadFile(string path, string name, string paramurl, string size, int statuscode = 1)
{
UploadPath = path;
UploadName = name;
ParamUrl = paramurl;
Size = size;
StatusCode = statuscode;
} /// <summary>
/// 上传文件结果,1是成功
/// </summary>
public int StatusCode { get; set; } /// <summary>
/// 上传时的文件前缀路径
/// </summary>
public string UploadPath { get; set; } /// <summary>
/// 上传时的文件名
/// </summary>
public string UploadName { get; set; } /// <summary>
/// 文件访问的路径参数
/// </summary>
public string ParamUrl { get; set; } /// <summary>
/// 文件大小
/// </summary>
public string Size { get; set; }
}

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. 详解Go语言I/O多路复用netpoller模型

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 本文使用的go的源码15.7 可以从 Go 源码目录结构和对应代码文件了解 Go 在不同 ...

  2. 洛谷P1119-灾后重建-floyd算法

    洛谷P1119-灾后重建 题目描述 给出\(B\)地区的村庄数NN,村庄编号从\(0\)到\(N-1\),和所有\(M\)条公路的长度,公路是双向的. 给出第\(i\)个村庄重建完成的时间\(t_i\ ...

  3. Operating System:管程相关概念

    管程 (Moniters,也称为监视器)一.管程的概念是一种程序结构,结构内的多个子程序(对象或模块)形成的多个工作线程互斥访问共享资源.这些共享资源一般是硬件设备或一群变量.管程实现了在一个时间点, ...

  4. Chapter Zero 0.1.4 计算机上常用的计算单位

    0.1 计算机硬件 计算机上常用的计算单位 容量单位: 计算机对于数据的判断依据有没有通电来记录信息,对于每个记录而言, 他只认识0或1,而0/1这个二进制单位我们成为bit. 因为bit太小,所以存 ...

  5. Leetcode(3)-无重复字符的最长子串

    给定一个字符串,找出不含有重复字符的最长子串的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. 给定 &q ...

  6. 多线程(四) AQS底层原理分析

    J.U.C 简介 Java.util.concurrent 是在并发编程中比较常用的工具类,里面包含很多用来在并发 场景中使用的组件.比如线程池.阻塞队列.计时器.同步器.并发集合等等.并 发包的作者 ...

  7. DC1(msf drupal7+suid-find提权)

    这边我们靶机是仅主机模式,IP是192.168.56.101,,直接上msf拿到shell,  不过payload要改一下 改成php/meterperter/bind_tcp 拿到shell了 ,采 ...

  8. sql 手注 语法

    mysql中的information_schema 结构用来存储数据库系统信息 information_schema 结构中这几个表存储的信息,在注射中可以用到的几个表.  | SCHEMATA ―― ...

  9. 属于我的md5sum程序

    目录 前言 介绍 使用说明 总结 前言 之所以想做这个软件是因为一直在使用的http://keir.net/hash.html软件有很多功能不能满足. 经过自学C#,研究多线程,异步更新UI,等等知识 ...

  10. 通过改写 原始对象的paint 方法,来设置对象的border颜色

    解决方案: //通过改写 原始对象的paint 方法,来设置对象的border颜色 1. package test1;import java.awt.Color;import java.awt.Gra ...