メール送信を行なう、WebAPIを作成しようとして、以下のようなインターフェイスを考えた。
[HttpPost]
public async Task<SendMailStatus> PostAsync(
[FromForm]string? FromAddress, // 送信者アドレス
[FromForm]string? Password, // (暗号化された)パスワード
[FromForm]string[]? ToAddresses, // 送信先(複数指定可)
[FromForm]string[]? CcAddresses, // Cc(複数指定可)
[FromForm]string[]? BccAddresses, // Bcc(複数指定可)
[FromForm]string? Subject, // 件名
[FromForm]string? Message, // 本文
[FromForm]IFormFile[]? Attachments // 添付ファイル(複数指定可)
) {
・・・
添付ファイルがあるので、当然、multipart/form-dataとして、クライアントからデータをPOSTしなければならないのだが、この作成方法に引っかかってしまったのであった。
MultipartFormDataContent構造体を使用するのは分かっており、これにファイルを追加するにはBinaryContent構造体を使用すれば良いことも分かっていたのだが、それ以外のFormデータを「Formデータだから、FormUrlEncodedContent構造体を作って、それを追加すればいいんじゃ無いか?」と勝手に思い込んで、色々試したが、ファイル(コード上はAttachments)は取れるのだが、他の引数はうまくデータがとれず、「何じゃこれは?」となった・・・
色々調べて、結局FormUrlEncodedContentでまとめて入れるのでは無く、以下のように個々のパラメータ(key=値)をStringContentとして別々に追加しなければいけないことが分かった。
// マルチパートMime
MultipartFormDataContent MimeData = new MultipartFormDataContent();
// 送信元
StringContent ctx = new(FromAddress);
MimeData.Add(ctx,"FromAddress");
// パスワード
string encPwd = EncryptPassword(Password));
ctx = new(encPwd);
MimeData.Add(ctx,"Password");
// 宛先
foreach(string s in ToAddresses) {
if (s != null) {
ctx = new(s);
MimeData.Add(ctx,"ToAddresses");
}
}
・・・
// 添付ファイル
foreach(var a in Attachments) {
MemoryStream stm = new MemoryStream();
await a.CopyToAsync(stm);
await stm.FlushAsync();
byte[] buf = stm.ToArray();
ByteArrayContent c = new ByteArrayContent(buf);
MimeData.Add(c,"Attachments",a.FileName);
}
await cli.PostAsync("・・・",MimeData);
まったく、基礎がなっておりませぬな・・・
無駄な時間を使ってしまった・・・