HttpContext.Current.Request.Files WCF 中始终为 Null [使用原始元数据保存图像]
HttpContext.Current.Request.Files Always Null in WCF [save image with original metadata]
我正在尝试使用 WCF 使用 表单数据 上传 图片 。我正在编写下面的代码以在 WCF 代码中获取图像,但它总是向我发送 null 值,但我能够 接收图像 字节流。我的主要 objective 是使用原始图像元数据保存图像。
HttpPostedFile file = HttpContext.Current.Request.Files["media1"];
为了完成这个功能,我已经添加了:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
在Web.Config:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
注意:我想用元数据保存图像。
您不应使用 HttpContext
来获取 WCF 中的文件。您可以简单地创建一个以流作为输入的服务。这里有一个简单的例子:Uploading an image using WCF RESTFul service full working example
更新:
尝试字节数组而不是流并像这样包装 class:
public class Input
{
[DataMember]
public string fileName { get; set; }
[DataMember]
public DateTime createdDate{ get; set; }
[DataMember]
public DateTime modifiedDate{ get; set; }
[DataMember]
public byte[] fileContents { get; set; }
.
.
}
然后只需将文件写入磁盘或您想要的任何地方,如下所示:
public string Upload(Input input)
{
File.WriteAllBytes(input.fileName, input.fileContents);
return "OK";
}
最后,在给定 link
的帮助下,我的问题得到了解决
我在我的实现中写了下面的代码,我刚从codeplex下载了MultipartParser.cs class,而且我在这里粘贴完整class 因为 Codeplex 会在一段时间后关闭。
public string Upload(Stream data)
{
MultipartParser parser = new MultipartParser(data);
if (parser.Success)
{
// Save the file
string filename = parser.Filename;
string contentType = parser.ContentType;
byte[] filecontent = parser.FileContents;
File.WriteAllBytes(@"C:\test1.jpg", filecontent);
}
return "OK";
}
MultipartParser.cs Class:
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
/// <summary>
/// MultipartParser http://multipartparser.codeplex.com
/// Reads a multipart form data stream and returns the filename, content type and contents as a stream.
/// 2009 Anthony Super http://antscode.blogspot.com
/// </summary>
namespace WcfService1
{
public class MultipartParser
{
public MultipartParser(Stream stream)
{
this.Parse(stream, Encoding.UTF8);
}
public MultipartParser(Stream stream, Encoding encoding)
{
this.Parse(stream, encoding);
}
public static async Task ParseFiles(Stream data, string contentType, Action<string, Stream> fileProcessor)
{
var streamContent = new StreamContent(data);
streamContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
var provider = await streamContent.ReadAsMultipartAsync();
foreach (var httpContent in provider.Contents)
{
var fileName = httpContent.Headers.ContentDisposition.FileName;
if (string.IsNullOrWhiteSpace(fileName))
{
continue;
}
using (Stream fileContents = await httpContent.ReadAsStreamAsync())
{
fileProcessor(fileName, fileContents);
}
}
}
private void Parse(Stream stream, Encoding encoding)
{
this.Success = false;
// Read the stream into a byte array
byte[] data = ToByteArray(stream);
// 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 int IndexOf(byte[] searchWithin, byte[] serachFor, int startIndex)
{
int index = 0;
int startPos = Array.IndexOf(searchWithin, serachFor[0], startIndex);
if (startPos != -1)
{
while ((startPos + index) < searchWithin.Length)
{
if (searchWithin[startPos + index] == serachFor[index])
{
index++;
if (index == serachFor.Length)
{
return startPos;
}
}
else
{
startPos = Array.IndexOf<byte>(searchWithin, serachFor[0], startPos + index);
if (startPos == -1)
{
return -1;
}
index = 0;
}
}
}
return -1;
}
private byte[] ToByteArray(Stream stream)
{
byte[] buffer = new byte[32768];
using (MemoryStream ms = new MemoryStream())
{
while (true)
{
int read = stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
return ms.ToArray();
ms.Write(buffer, 0, read);
}
}
}
public bool Success
{
get;
private set;
}
public string ContentType
{
get;
private set;
}
public string Filename
{
get;
private set;
}
public byte[] FileContents
{
get;
private set;
}
}
}
我正在尝试使用 WCF 使用 表单数据 上传 图片 。我正在编写下面的代码以在 WCF 代码中获取图像,但它总是向我发送 null 值,但我能够 接收图像 字节流。我的主要 objective 是使用原始图像元数据保存图像。
HttpPostedFile file = HttpContext.Current.Request.Files["media1"];
为了完成这个功能,我已经添加了:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
在Web.Config:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
注意:我想用元数据保存图像。
您不应使用 HttpContext
来获取 WCF 中的文件。您可以简单地创建一个以流作为输入的服务。这里有一个简单的例子:Uploading an image using WCF RESTFul service full working example
更新:
尝试字节数组而不是流并像这样包装 class:
public class Input
{
[DataMember]
public string fileName { get; set; }
[DataMember]
public DateTime createdDate{ get; set; }
[DataMember]
public DateTime modifiedDate{ get; set; }
[DataMember]
public byte[] fileContents { get; set; }
.
.
}
然后只需将文件写入磁盘或您想要的任何地方,如下所示:
public string Upload(Input input)
{
File.WriteAllBytes(input.fileName, input.fileContents);
return "OK";
}
最后,在给定 link
的帮助下,我的问题得到了解决我在我的实现中写了下面的代码,我刚从codeplex下载了MultipartParser.cs class,而且我在这里粘贴完整class 因为 Codeplex 会在一段时间后关闭。
public string Upload(Stream data)
{
MultipartParser parser = new MultipartParser(data);
if (parser.Success)
{
// Save the file
string filename = parser.Filename;
string contentType = parser.ContentType;
byte[] filecontent = parser.FileContents;
File.WriteAllBytes(@"C:\test1.jpg", filecontent);
}
return "OK";
}
MultipartParser.cs Class:
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
/// <summary>
/// MultipartParser http://multipartparser.codeplex.com
/// Reads a multipart form data stream and returns the filename, content type and contents as a stream.
/// 2009 Anthony Super http://antscode.blogspot.com
/// </summary>
namespace WcfService1
{
public class MultipartParser
{
public MultipartParser(Stream stream)
{
this.Parse(stream, Encoding.UTF8);
}
public MultipartParser(Stream stream, Encoding encoding)
{
this.Parse(stream, encoding);
}
public static async Task ParseFiles(Stream data, string contentType, Action<string, Stream> fileProcessor)
{
var streamContent = new StreamContent(data);
streamContent.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType);
var provider = await streamContent.ReadAsMultipartAsync();
foreach (var httpContent in provider.Contents)
{
var fileName = httpContent.Headers.ContentDisposition.FileName;
if (string.IsNullOrWhiteSpace(fileName))
{
continue;
}
using (Stream fileContents = await httpContent.ReadAsStreamAsync())
{
fileProcessor(fileName, fileContents);
}
}
}
private void Parse(Stream stream, Encoding encoding)
{
this.Success = false;
// Read the stream into a byte array
byte[] data = ToByteArray(stream);
// 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 int IndexOf(byte[] searchWithin, byte[] serachFor, int startIndex)
{
int index = 0;
int startPos = Array.IndexOf(searchWithin, serachFor[0], startIndex);
if (startPos != -1)
{
while ((startPos + index) < searchWithin.Length)
{
if (searchWithin[startPos + index] == serachFor[index])
{
index++;
if (index == serachFor.Length)
{
return startPos;
}
}
else
{
startPos = Array.IndexOf<byte>(searchWithin, serachFor[0], startPos + index);
if (startPos == -1)
{
return -1;
}
index = 0;
}
}
}
return -1;
}
private byte[] ToByteArray(Stream stream)
{
byte[] buffer = new byte[32768];
using (MemoryStream ms = new MemoryStream())
{
while (true)
{
int read = stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
return ms.ToArray();
ms.Write(buffer, 0, read);
}
}
}
public bool Success
{
get;
private set;
}
public string ContentType
{
get;
private set;
}
public string Filename
{
get;
private set;
}
public byte[] FileContents
{
get;
private set;
}
}
}