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;
        }
    }
}