关于WCF的建立与一般服务的写法参照 https://blog.csdn.net/a1002308667/article/details/82928510
在WCF项目中新建上传服务UpImg.svc,添加如下代码:
[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
public string ModifyImg(Stream image)
{
UploadImg ui = new UploadImg();//UploadImg代码在文章的后面
return userid = ui.Upload(image);
}
post服务不要设置BodyStyle,回传的数据以流stream的形式进行接收。另外需要注意编辑webconfig
在该服务的绑定点编辑maxbuferpoolSize等属性,这里关乎上传文件的大小,在配置文件中的体现为:
<binding name="UpImgServiceBinding" maxBufferSize="214748364"
maxReceivedMessageSize="214748364" crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
这里单位为字节数。
前台代码:
<input id="imgput" type="file" accept="image/*" onchange="selectimg(this);" />
<img id='imgtest' src="#" alt="Alternate Text" width="25px" />
function selectimg(file) {
var url = null;
if (window.createobjectURL) {
url = window.createObjectURL(file.files[0]);//预览图片,浏览器支持不同
}
else if (window.URL) {
url = window.URL.createObjectURL(file.files[0]);
} else if (window.webkitURL) {
url = window.webkitURL.createObjectURL(file.files[0]);
}
var pimg = file.files[0];//获取图片文件
if (pimg.size > 1024 * 500) {
alert("文件不能超过500KB");
}
else {
var format = new FormData();//构建表单信息
var userid = "001";
format.append(userid, pimg);
$("#imgtest").attr("src", url);
$.ajax({
url: "http://localhost:20867/UpImg.svc/ModifyImg",
type: "post",
data: format,
processData: false,//这里设置为false,回传流文件
dataType: 'json',
contentType: 'application/x-www-form-urlencoded',
async: false,
success: function (result) {
alert(result.d);
}
});
}
}
回传的流文件是包含数据头和尾的表单信息,wcf似乎没有解析的办法,所以需要自行解析流,回传的数据我们用文本打开:
------WebKitFormBoundarym7KM4bFo7y4fALw7
Content-Disposition: form-data; name="001"; filename="10.png"
Content-Type: image/png
塒NG
IHDR ? 9 訰 IDATx滌?`吁?馱O蔝Z〃 堒封亗2?@D萱=?n?u?q沴╯蝺榧懲EPT读?圣R@乖"蠦KA恃?镧洠I?I?iy>冬m?>?ty觚9>荐? 唲痵v. aI寀 ?? 6? l凨 @?? €?. a#\ 翭? 剭p [r?HLLPJr睷R掜?窒 U昒*PYY
……
------WebKitFormBoundarym7KM4bFo7y4fALw7--
它包含了数据的文件名称,表单的内容name,type等文件头,以及与文件头一致的尾,这样我们就可以将中间的文件提取出来了:
public class UploadImg
{
public string Upload(Stream file)
{
try
{
string userid = "-1";
using (var ms = new MemoryStream())
{
file.CopyTo(ms);
ms.Position = 0;
var encoding = System.Text.Encoding.Default;
var reader = new StreamReader(ms, encoding);
var headerLength = 0L;
//读取第一行
var firstLine = reader.ReadLine();
//计算偏移(回车换行2个字符)
headerLength += encoding.GetBytes(firstLine).LongLength + 2;
//读取第二行
var secondLine = reader.ReadLine();
//计算偏移
headerLength += encoding.GetBytes(secondLine).LongLength + 2;
//解析用户名 投机取巧的办法,name理论上是键值对的值,不过一样可以传值
userid = new System.Text.RegularExpressions.Regex("name=\"(.+)\";").Match(secondLine).Groups[1].Value;
//解析文件名
var fileName = new System.Text.RegularExpressions.Regex("filename=\"(?<fn>.*)\"").Match(secondLine).Groups["fn"].Value;
fileName = System.IO.Path.GetExtension(fileName);
//一直读到空行为止
while (true)
{
var line = reader.ReadLine();
if (line == null)
break;
//若未到头,则计算偏移(字符串长度+回车换行2个字符)
headerLength += encoding.GetBytes(line).LongLength + 2;
if (line == "")
break;
}
//设置偏移,以开始读取文件内容
ms.Position = headerLength;
减去末尾:“\r\n--\r\n”共6字符长度
ms.SetLength(ms.Length - encoding.GetBytes(firstLine).LongLength - 6);
string relfilename = "E:\\_" + userid + "head." + fileName;//服务器地址
using (var fileToupload = new FileStream(relfilename, FileMode.Create))
{
ms.CopyTo(fileToupload);
fileToupload.Close();
fileToupload.Dispose();
}
}
return userid;
}
catch (Exception)
{
return "-1";
}
}
}
至此,上传的文件就写入了服务器