- 一般的上传文件的方法:
<form method="post"action="http://w.sohu.com/t2/upload.do" enctype=”multipart/form-data”>
<inputtype="text" name="desc">
<inputtype="file" name="pic">
</form>
表单中enctype="multipart/form-data"的意思,是设置表单的MIME编码。默认情况,是application/x-www-form-urlencoded,也就是name=value&name2=value2这种上传方式,但不能用于文件上传;只有使用了multipart/form-data,才能完整的传递文件数据
2.那什么是Multipart/form-data:
最早的HTTP POST是不支持文件上传的,给编程开发带来很多问题。但是在1995年,ietf出台了rfc1867,也就是《RFC 1867 -Form-based File Upload in HTML》,用以支持文件上传。所以Content-Type的类型扩充了multipart/form-data用以支持向服务器发送二进制数据。
3.所以web层上传到webapi也需要使用multipart/form-data的方式请求,这里通过httpclient请求api,在httpclient中以multipart/form-data方式上传的参数是MultipartFormDataContent。代码如下
public async Task<ActionResult> UploadPro_WkDoc(HttpPostedFileBase uploadWorkHourFile) { using(HttpClient hc = new HttpClient())
{ //以multipart/form-data方式传递 MultipartFormDataContent form = new MultipartFormDataContent(); //获取流内容,如果提交多个文件则new多个就好了 var fileContent1 = new StreamContent(uploadWorkHourFile.InputStream); //这个在请求头添加附加的信息(这里添加了实际要保存的文件名) fileContent1.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = uploadWorkHourFile.FileName }; form.Add(fileContent1); HttpResponseMessage msg = await hc.PostAsync("api地址", form);
} }
api端代码
//判断上传的数据是否是MimeType类型,是否是用于上传文件的类型(上传二进制数据),Multipart类型 if (!Request.Content.IsMimeMultipartContent()) { Throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } string path = @"\11.11.111.144" + "\SlhFile\";//文件服务器地址” //初始化MultipartFormDataStreamProvider实例,用来接收上传的文件。相当于文件接收器 MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(path); // 读取文件上传并且会自动保存,保存的文件名是file.LocalFileName,没有后缀。所以要指定文件名和后缀通过File.move解决 await Request.Content.ReadAsMultipartAsync(provider); //更换文件名,通过file.move foreach (MultipartFileData file in provider.FileData) { var filename = file.Headers.ContentDisposition.FileName.Replace(""", ""); string newFileName = Guid.NewGuid().ToString("N") + Path.GetExtension(filename); File.Move(file.LocalFileName, Path.Combine(path, newFileName)); } }
4. 保存到文件服务器的时候可能会报错。对*****路径无法访问
在webconfig中<system.web>下加 <identity impersonate="true" userName="用户名 " password="密码" />
还有一种简单的方法就是,web层直接将文件的byte[]数组传到api层,api层直接接受byte[]数组然后保存到文件服务器(和保存到本地一样的写法)