LoginSignup
1
1

More than 5 years have passed since last update.

HTTPClient でRuby on railsサーバ宛に画像を含むマルチパートでPOSTする

Last updated at Posted at 2017-05-30

一日中、はまっていた。

画像と幾つかの変数を含む内容をRuby on rails 宛に、C#からHttpClientを使ってPOSTしたのだけど、うまくいかない。
素直にライブラリの使い方どおりやってもうまくいかない。
rails側で、変数名に改行が入る?という謎い事態になった。

回避法

content.Headers.Add("Content-Disposition", $"form-data; name=\"{item.Key}\"");
というように、ここでnameを指定し、MultipartFormDataContentにAddする時、名前をつけない。
根本的な解決法という感じはしないけど。

ソースコード全体

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace Test
{
    public class ImagePostData
    {
        public string id { get; set; }
        public string kind { get; set; }
        public byte[] image { get; set; }

    //本来は変数はたくさんあったので、メタプログラミング用
        IEnumerable<KeyValuePair<string, string>> GetProperties()
        {
            foreach (var item in this.GetType().GetProperties())
            {
                if (item.PropertyType != typeof(byte[]))
                {
                    yield return new KeyValuePair<string, string>(item.Name, item.GetValue(this).ToString());
                }
            }
        }

        public MultipartFormDataContent CreateMultipartFormDataContent()
        {
            var dataContent = new System.Net.Http.MultipartFormDataContent();
            var byteContent = new ByteArrayContent(image);
            //Content-Dispositionの指定と、nameを文字列で渡す。
            byteContent.Headers.Add("Content-Disposition", $"form-data; name=\"image\" ; filename = \"{this.id}_{this.kind}.jpg\"");
            byteContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
            //nameをつけずに渡す。
            dataContent.Add(byteContent);

            foreach (var item in GetProperties())
            {
                var content = new StringContent(item.Value);
                //nameをヘッダーにかく
                content.Headers.Add("Content-Disposition", $"form-data; name=\"{item.Key}\"");
                //nameをつけずに渡す。
                dataContent.Add(content);
            }
            return dataContent;
        }
    }

    [TestClass]
    public class UnitTest2
    {
        string postUrl = "https://****.****.com/****/upload";

        /// <summary>
        /// 使い方
        /// </summary>
        /// <returns></returns>
        [TestMethod]        
        public async Task TestMethod1()
        {
            System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();

            var imageFile = @"0.jpeg";
            var post = new ImagePostData()
            {
                image = System.IO.File.ReadAllBytes(imageFile),             
                id = "1",
                kind = "default",
            };

            var c = post.CreateMultipartFormDataContent();
            var result = await client.PostAsync(postUrl, c);
        }
    }
}

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1