项目环境:
1、前端使用Layui控件进行图片上传,发送的请求为POST,Context-Type为”multipart/form-data; boundary=—-WebKitFormBoundaryA6CXcNQSGgWydFKy”
2、后端采用WCF服务,寄宿于Winform程序(怎么寄宿的不解释)
3、接口方法
[OperationContract]
[WebInvoke(UriTemplate = "WebUploadPhoto", Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
string WebUploadPhoto(Stream pStream);
问题现象:
1、由于Context-Type为”multipart/form-data; boundary=—-WebKitFormBoundaryA6CXcNQSGgWydFKy”,而且是Layui控件固定的格式的(我没找到修改的方法),导致服务器端接收的stream中包含有
—-WebKitFormBoundaryA6CXcNQSGgWydFKy的字样,真正的文件内容在其内,所以必须解析stream;
2、由于是WCF,导致HttpContext.Currect可能为空,所以无法使用MultipartFormDataStreamProvider来解析;
解决方法:
1、有幸找到国外大神的解析代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
namespace SampleService
{
public class MultipartParser
{
private byte[] requestData;
public MultipartParser(Stream stream)
{
this.Parse(stream, Encoding.UTF8);
ParseParameter(stream, Encoding.UTF8);
}
public MultipartParser(Stream stream, Encoding encoding)
{
this.Parse(stream, encoding);
}
private void Parse(Stream stream, Encoding encoding)
{
this.Success = false;
// Read the stream into a byte array
byte[] data = ToByteArray(stream);
requestData = data;
// Copy to a string for header parsing
string content = encoding.GetString(data);
// The first line should contain the delimiter
int delimiterEndIndex = content.IndexOf("\r\n");
if (delimiterEndIndex > -1)
{
string delimiter = content.Substring(0, content.IndexOf("\r\n"));
// Look for Content-Type
Regex re = new Regex(@"(?<=Content\-Type:)(.*?)(?=\r\n\r\n)");
Match contentTypeMatch = re.Match(content);
// Look for filename
re = new Regex(@"(?<=filename\=\"")(.*?)(?=\"")");
Match filenameMatch = re.Match(content);
// Did we find the required values?
if (contentTypeMatch.Success && filenameMatch.Success)
{
// Set properties
this.ContentType = contentTypeMatch.Value.Trim();
this.Filename = filenameMatch.Value.Trim();
// Get the start & end indexes of the file contents
int startIndex = contentTypeMatch.Index + contentTypeMatch.Length + "\r\n\r\n".Length;
byte[] delimiterBytes = encoding.GetBytes("\r\n" + delimiter);
int endIndex = IndexOf(data, delimiterBytes, startIndex);
int contentLength = endIndex - startIndex;
// Extract the file contents from the byte array
byte[] fileData = new byte[contentLength];
Buffer.BlockCopy(data, startIndex, fileData, 0, contentLength);
this.FileContents = fileData;
this.Success = true;
}
}
}
private void ParseParameter(Stream stream, Encoding encoding)
{
this.Success = false;
// Read the stream into a byte array
byte[] data;
if (requestData.Length == 0)
{
data = ToByteArray(stream);
}
else { data = requestData; }
// Copy to a string for header parsing
string content = encoding.GetString(data);
// The first line should contain the delimiter
int delimiterEndIndex = content.IndexOf("\r\n");
if (delimiterEndIndex > -1)
{