在方法POST

时间:2019-02-21 07:25:44

标签: asp.net-web-api

我有一个WebService,它正在使用POST方法工作并接收文件,但是在其中我还需要同时接收数据。

ASP.NET WebApi代码:

public Task<HttpResponseMessage> Post()
    {
        HttpRequestMessage request = this.Request;
        if (!request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }

        string root = System.Web.HttpContext.Current.Server.MapPath("~/App_Data/uploads");
        var provider = new MultipartFormDataStreamProvider(root);

        var task = request.Content.ReadAsMultipartAsync(provider).
            ContinueWith<HttpResponseMessage>(o =>
            {
                string file1 = provider.FileData.First().LocalFileName;

                return new HttpResponseMessage()
                {
                    Content = new StringContent("File uploaded.")
                };
            }
        );
        return task;
    }

为Android开发的客户端正在发送文件和数据,如下所示(文件的发送已经过测试并且可以正常工作,数据的发送仍然没有经过测试,因为我需要它能够在服务器端):

OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new MultipartBuilder()
        .type(MultipartBuilder.FORM)
        .addPart(
                Headers.of("Content-Disposition", "form-data; name=\"title\""),
                RequestBody.create(null, "Sample Text Content"))
        .addPart(
                Headers.of("Content-Disposition", "form-data; name=\"file\"; filename=\"" + fileName + ".png\""),
                RequestBody.create(MEDIA_TYPE_PNG, bitmapdata))
        .addFormDataPart("fullpath", "test")
        .build();
final com.squareup.okhttp.Request request = new com.squareup.okhttp.Request.Builder()
        .url(url)
        .post(requestBody)
        .build();

如何更改服务器以读取文件和数据?

有人可以帮忙吗? 预先感谢。

1 个答案:

答案 0 :(得分:1)

在这种情况下,客户端android在体内发送了其他值,例如media_type_png。我必须做类似的事情,但是客户端是有角度的,而不是移动应用程序,经过一番搜索之后,我从下面的stackoverflow中找到了代码。产生了下面的代码。

首先接收传入的消息,并检查您是否可以处理它,即[IsMimeMultipartContent][1]()

[HttpPost] 
public async Task<HttpResponseMessage> Upload()
{
    // Here we just check if we can support this
    if (!Request.Content.IsMimeMultipartContent())
    {
        this.Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
    }

    // This is where we unpack the values
    var provider = new MultipartFormDataMemoryStreamProvider();
    var result = await Request.Content.ReadAsMultipartAsync(provider);

    // From the form data we can extract any additional information Here the DTO is any object you want to define
    AttachmentInformationDto attachmentInformation = (AttachmentInformationDto)GetFormData(result);
    // For each file uploaded
    foreach (KeyValuePair<string, Stream> file in provider.FileStreams)
    {
        string fileName = file.Key;
        // Read the data from the file
        byte[] data = ReadFully(file.Value);
        // Save the file or do something with it
    }
}

我用它来解压缩数据:

 // Extracts Request FormatData as a strongly typed model
private object GetFormData(MultipartFormDataMemoryStreamProvider result)
{
    if (result.FormData.HasKeys())
    {
        // Here you can read the keys sent in ie
        result.FormData["your key"]
        AttachmentInformationDto data = AttachmentInformationDto();
        data.ContentType = Uri.UnescapeDataString(result.FormData["ContentType"]); // Additional Keys
        data.Description = Uri.UnescapeDataString(result.FormData["Description"]); // Another example
        data.Name = Uri.UnescapeDataString(result.FormData["Name"]); // Another example
        if (result.FormData["attType"] != null)
        {
            data.AttachmentType = Uri.UnescapeDataString(result.FormData["attType"]);
        }
        return data;
    }

    return null;
}

MultipartFormDataMemoryStreamProvider的定义如下:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;

namespace YOURNAMESPACE
{
    public class MultipartFormDataMemoryStreamProvider : MultipartMemoryStreamProvider
    {
        private readonly Collection<bool> _isFormData = new Collection<bool>();
        private readonly NameValueCollection _formData = new NameValueCollection(StringComparer.OrdinalIgnoreCase);
        private readonly Dictionary<string, Stream> _fileStreams = new Dictionary<string, Stream>();

        public NameValueCollection FormData
        {
            get { return _formData; }
        }

        public Dictionary<string, Stream> FileStreams
        {
            get { return _fileStreams; }
        }

        public override Stream GetStream(HttpContent parent, HttpContentHeaders headers)
        {
            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }

            if (headers == null)
            {
                throw new ArgumentNullException("headers");
            }

            var contentDisposition = headers.ContentDisposition;
            if (contentDisposition == null)
            {
                throw new InvalidOperationException("Did not find required 'Content-Disposition' header field in MIME multipart body part.");
            }

            _isFormData.Add(String.IsNullOrEmpty(contentDisposition.FileName));
            return base.GetStream(parent, headers);
        }

        public override async Task ExecutePostProcessingAsync()
        {
            for (var index = 0; index < Contents.Count; index++)
            {
                HttpContent formContent = Contents[index];
                if (_isFormData[index])
                {
                    // Field
                    string formFieldName = UnquoteToken(formContent.Headers.ContentDisposition.Name) ?? string.Empty;
                    string formFieldValue = await formContent.ReadAsStringAsync();
                    FormData.Add(formFieldName, formFieldValue);
                }
                else
                {
                    // File
                    string fileName = UnquoteToken(formContent.Headers.ContentDisposition.FileName);
                    Stream stream = await formContent.ReadAsStreamAsync();
                    FileStreams.Add(fileName, stream);
                }
            }
        }

        private static string UnquoteToken(string token)
        {
            if (string.IsNullOrWhiteSpace(token))
            {
                return token;
            }

            if (token.StartsWith("\"", StringComparison.Ordinal) && token.EndsWith("\"", StringComparison.Ordinal) && token.Length > 1)
            {
                return token.Substring(1, token.Length - 2);
            }

            return token;
        }
    }
}