从HttpClient的提交文件和JSON数据的WebAPI [英] Submitting File and Json data to webapi from HttpClient

查看:1991
本文介绍了从HttpClient的提交文件和JSON数据的WebAPI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从HttpClient的文件发送和JSON数据的Web API服务器。结果
我似乎无法通过有效载荷来访问服务器上的JSON,只是作为一个JSON变种。

I want to send file and json data from HttpClient to web api server.
I cant seem to access the json in the server via the payload, only as a json var.

 public class RegulationFilesController : BaseApiController
    {
        public void PostFile(RegulationFileDto dto)
        {
            //the dto is null here
        }
    }

下面是客户端:

   using (var client = new HttpClient())
                {
                    using (var content = new MultipartFormDataContent())
                    {
                        client.BaseAddress = new Uri(ConfigurationManager.AppSettings["ApiHost"]);
                        content.Add(new StreamContent(File.OpenRead(@"C:\\Chair.png")), "Chair", "Chair.png");
                        var parameters = new RegulationFileDto
                        {
                            ExternalAccountId = "1234",
                        };
                        JavaScriptSerializer serializer = new JavaScriptSerializer();
                        content.Add(new StringContent(serializer.Serialize(parameters), Encoding.UTF8, "application/json"));

                            var resTask = client.PostAsync("api/RegulationFiles", content); //?ApiKey=24Option_key
                            resTask.Wait();
                            resTask.ContinueWith(async responseTask =>
                            {
                                var res = await responseTask.Result.Content.ReadAsStringAsync();


                            }
                                );

                    }
                }

这个例子将工作:<一href=\"http://stackoverflow.com/questions/18059588/httpclient-multipart-form-post-in-c-sharp\">HttpClient多重表单张贴在C#
但是只能通过表单数据,而不是有效载荷。

this example will work:HttpClient Multipart Form Post in C# but only via the form-data and not payload.

能否请你建议如何同时访问请求的文件,并提交JSON和文件?

Can you please suggest how to access the file and the submitted json And the file at the same request?

感谢

推荐答案

我已经尝试了许多不同的方式同时提交的文件数据和元数据,这是我发现最好的方法:

I have tried many different ways to submit both file data and metadata and this is the best approach I have found:

不要使用MultipartFormDataContent,只能使用StreamContent的文件数据。这样,您就可以流文件上传,这样你就不会占用服务器上太多RAM。 MultipartFormDataContent需要你整个请求将文件加载到内存,然后保存到本地存储的地方。通过流,你也有复制流分成其他位置的好处,如Azure存储容器。

Don't use MultipartFormDataContent, use only StreamContent for the file data. This way you can stream the file upload so you don't take up too much RAM on the server. MultipartFormDataContent requires you to load the entire request into memory and then save the files to a local storage somewhere. By streaming, you also have the benefit of copying the stream into other locations such as an Azure storage container.

这解决了二进制数据的问题,现在为元数据。为此,使用自定义页眉和序列化JSON成说。您的控制器可以读取自定义页眉和反序列化的元数据DTO。有大小限制头,看到这里 href=\"http://stackoverflow.com/questions/686217/maximum-on-http-header-values​​\">(8-16KB),这是大量的数据。如果你需要更多的空间,你可以做两个独立的请求,一个POST的最低需求,然后补丁更新所需的任何属性超过一个头可以适合。

This solves the issue of the binary data, and now for the metadata. For this, use a custom header and serialize your JSON into that. Your controller can read the custom header and deserialize it as your metadata dto. There is a size limit to headers, see here (8-16KB), which is a large amount of data. If you need more space, you could do two separate requests, one to POST the minimum need, and then a PATCH to update any properties that needed more than a header could fit.

样code:

public class RegulationFilesController : BaseApiController
{
    public async Task<IHttpActionResult> Post()
    {
        var isMultipart = this.Request.Content.IsMimeMultipartContent();

        if (isMultipart)
        {
            return this.BadRequest("Only binary uploads are accepted.");
        }

        var headerDto = this.GetJsonDataHeader<RegulationFileDto>();
        if(headerDto == null)
        {
            return this.BadRequest("Missing X-JsonData header.");
        }

        using (var stream = await this.Request.Content.ReadAsStreamAsync())
        {
            if (stream == null || stream.Length == 0)
            {
                return this.BadRequest("Invalid binary data.");
            }

            //save stream to disk or copy to another stream

            var model = new RegulationFile(headerDto);

            //save your model to the database

            var dto = new RegulationFileDto(model);

            var uri = new Uri("NEW URI HERE");

            return this.Created(uri, dto);
        }
    }

    private T GetJsonDataHeader<T>()
    {
        IEnumerable<string> headerCollection;

        if (!this.Request.Headers.TryGetValues("X-JsonData", out headerCollection))
        {
            return default(T);
        }

        var headerItems = headerCollection.ToList();

        if (headerItems.Count() != 1)
        {
            return default(T);
        }

        var meta = headerItems.FirstOrDefault();

        return !string.IsNullOrWhiteSpace(meta) ? JsonConvert.DeserializeObject<T>(meta) : default(T);
    }
}

这篇关于从HttpClient的提交文件和JSON数据的WebAPI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆