使用Web Api上传图像会导致服务器上的文件无效

时间:2014-04-11 23:34:21

标签: windows-phone-8 asp.net-web-api image-uploading

我无法使用WebApi成功上传完整的图像文件。 当执行控制器的Post方法时,一个文件上传实际上导致两个文件被写入服务器上的磁盘。

但是,这些文件无法作为预期的图像文件打开。 一个文件有0个字节,另一个文件大约有21kb。

我怀疑我的客户端代码导致了这个问题。 那么如何使用WebApi成功上传完整的图像文件?

客户代码:

    internal async Task Upload(Windows.Storage.StorageFile file)
    {
        IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read);
        var reader = new Windows.Storage.Streams.DataReader(fileStream.GetInputStreamAt(0));
        await reader.LoadAsync((uint)fileStream.Size);

        var url = string.Format("{0}{1}", Globals.URL_PREFIX, "api/images");
        byte[] image = new byte[fileStream.Size];

        await UploadImage(image, url);
    }


    public async Task UploadImage(byte[] image, string url)
    {
        var imageContent = new ByteArrayContent(image);
        imageContent.Headers.ContentType = MediaTypeHeaderValue.Parse("image/jpeg");

        var fileName = string.Format("{0}.jpg", Guid.NewGuid().ToString());
        var content = new MultipartFormDataContent();
        content.Add(imageContent, "image", fileName);

        Stream stream = new System.IO.MemoryStream(image);
        content.Add(new StreamContent(stream), "file", fileName);

        var message = new HttpRequestMessage();
        message.Method = HttpMethod.Post;
        message.Content = content;
        message.RequestUri = new Uri(url);

        var client = new HttpClient();

        await client.SendAsync(message).ContinueWith(task =>
        {
            if (task.Result.IsSuccessStatusCode)
            {
                //do something with response
            }
        });
    }

服务器代码:

public async Task<HttpResponseMessage> Post()
{
    var root = HttpContext.Current.Server.MapPath("~/Images/Profiles/");
    var provider = new MultipartFormDataStreamProvider(root);

    try 
    {
        // Read the form data.
        await Request.Content.ReadAsMultipartAsync(provider);
        return Request.CreateResponse(HttpStatusCode.OK);
    } 
    catch (Exception e) 
    {
        return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
    }

    return Request.CreateResponse(HttpStatusCode.OK);
}

2 个答案:

答案 0 :(得分:0)

看看这个样本: https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/FileUploadSample/ReadMe.txt

我认为这个问题是你试图提供两次相同的字节数组。你真的只需要做一次。

using (FileStream fileStream = new FileStream(_filename, FileMode.Open, FileAccess.Read, FileShare.Read, BufferSize, useAsync: true))
{
    // Create a stream content for the file
    StreamContent content = new StreamContent(fileStream, BufferSize);

    // Create Multipart form data content, add our submitter data and our stream content
    MultipartFormDataContent formData = new MultipartFormDataContent();
    formData.Add(new StringContent("Me"), "submitter");
    formData.Add(content, "filename", _filename);

    // Post the MIME multipart form data upload with the file
    Uri address = new Uri(_baseAddress + "api/fileupload");
    HttpResponseMessage response = await client.PostAsync(address, formData);

    FileResult result = await response.Content.ReadAsAsync<FileResult>();
    Console.WriteLine("{0}Result:{0}  Filename:  {1}{0}  Submitter: {2}", Environment.NewLine, result.FileNames.FirstOrDefault(), result.Submitter);
}

答案 1 :(得分:0)

<强>客户端

 public async Task UploadImage(byte[] image, string url)
        {
            Stream stream = new System.IO.MemoryStream(image);
            HttpStreamContent streamContent = new HttpStreamContent(stream.AsInputStream());

            Uri resourceAddress = null;
            Uri.TryCreate(url.Trim(), UriKind.Absolute, out resourceAddress);
            Windows.Web.Http.HttpRequestMessage request = new Windows.Web.Http.HttpRequestMessage(Windows.Web.Http.HttpMethod.Post, resourceAddress);
            request.Content = streamContent;

            var httpClient = new Windows.Web.Http.HttpClient();
            var cts = new CancellationTokenSource();
            Windows.Web.Http.HttpResponseMessage response = await httpClient.SendRequestAsync(request).AsTask(cts.Token);
        }

<强>控制器:

public async Task<HttpResponseMessage> Post()
{
    Stream requestStream = await this.Request.Content.ReadAsStreamAsync();
    byte[] byteArray = null;
    using (MemoryStream ms = new MemoryStream())
    {
        await requestStream.CopyToAsync(ms);
        byteArray = ms.ToArray();
    }
    .
    .
    .
    return Request.CreateResponse(HttpStatusCode.OK);
}