web-dev-qa-db-ja.com

ASP.NET Core Web API(境界ベースのリクエスト解析)でファイルと他のフォームデータを一緒に受信します

リクエストから1つのfileと1つのtext値を受け取ることになっているアクションメソッドのパラメーターをどのように形成しますか?

私はこれを試しました

public string Post([FromBody]string name, [FromBody]IFormFile imageFile)

そして、Postmanからそれを打ってみましたが、それは私に500 Internal Server Errorを与えます。また、ブレークポイントを配置したアクションメソッド内の最初のステートメントにヒットしないため、デバッグすることもできません。

どのようにして境界ベースのリクエストを解析し、ファイルと他のテキストフィールドを抽出できますか? ASP.NET Coreは初めてです。

13
shashwat

同様の問題があり、次のように関数で[FromForm]属性とFileUploadModelViewを使用して問題を解決しました。

[HttpPost]
        [Route("upload")]
        public async Task<IActionResult> Upload([FromForm] FileUploadViewModel model, [FromForm] string member_code)
        {
            var file = model.File;

            ...
        }
18
Ye Yint

Mailgunからの応答 (ファイルとテキスト値の両方を含む)を解析するために、次のコードを使用してこれを達成しています。

「ダッシュ」は、「MessageHeaders」などのプロパティ名が「message-headers」に変換されることに注意してください。明らかに、ユースケースに合ったロジックを使用する必要があります。

コントローラ:

using System;
using Microsoft.AspNetCore.Mvc;
using NuGet.Protocol.Core.v3;

namespace Potato
{
    [Route("api/[controller]")]
    public class MailgunController : Controller
    {
        [HttpPost]
        public IActionResult Post()
        {
            MailgunEmail email = new MailgunEmail(Request);

            return Ok(email.ToJson());
        }
    }
}

モデル:

using System;
using System.Reflection;
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;

namespace Potato
{
    public class MailgunEmail
    {
        public IEnumerable<IFormFile> Attachments { get; set; }

        public string Recipient { get; set; }
        public string Sender { get; set; }
        public string From { get; set; }
        public string Subject { get; set; }
        public string BodyPlain { get; set; }
        public string StrippedText { get; set; }
        public string StrippedSignature { get; set; }
        public string BodyHtml { get; set; }
        public string StrippedHtml { get; set; }
        public int? AttachmentCount { get; set; }
        public int Timestamp { get; set; }
        public string Token { get; set; }
        public string Signature { get; set; }
        public string MessageHeaders { get; set; }
        public string ContentIdMap { get; set; }

        public MailgunEmail(HttpRequest request)
        {
            var form = request.Form;

            Attachments = new List<IFormFile>(form.Files);

            foreach (var prop in typeof(MailgunEmail).GetProperties()) {
                string propName = Dashify(prop.Name);
                var curVal = form[propName];
                if (curVal.Count > 0) {
                    prop.SetValue(this, To(curVal[0], prop.PropertyType), null);
                }
            }
        }

        private object To(IConvertible obj, Type t)
        {
            Type u = Nullable.GetUnderlyingType(t);

            if (u != null) {
                return (obj == null) ? GetDefaultValue(t) : Convert.ChangeType(obj, u);
            } else {
                return Convert.ChangeType(obj, t);
            }
        }

        private object GetDefaultValue(Type t)
        {
            if (t.GetTypeInfo().IsValueType) {
                return Activator.CreateInstance(t);
            }
            return null;
        }

        private string Dashify(string source)
        {
            string result = "";
            var chars = source.ToCharArray();
            for (int i = 0; i < chars.Length; ++i) {
                var c = chars[i];
                if (i > 0 && char.IsUpper(c)) {
                    result += '-';
                }
                result += char.ToLower(c);
            }
            return result;
        }
    }
}
5
Daniel Centore

HomeController.csで

using Microsoft.AspNetCore.Hosting;
.......
private IHostingEnvironment _environment;

public HomeController(IHostingEnvironment environment)
{
    _environment = environment;
}

[HttpPost]
[ValidateAntiForgeryToken]        
public IActionResult Index(IFormCollection formdata)
{
 var files = HttpContext.Request.Form.Files;
 foreach (var file in files)
 {
     var uploads = Path.Combine(_environment.WebRootPath, "Images");
     if (file.Length > 0)
     {
        string FileName = Guid.NewGuid(); // Give file name
        using (var fileStream = new FileStream(Path.Combine(uploads, FileName), FileMode.Create))
        {
            file.CopyToAsync(fileStream);
        }       
     }
  }
}

表示中-Index.cshtml

<form method="post" enctype="multipart/form-data" >
 .....
</form>

このコードを試すことができます。

ありがとう!!

3
Nitika Chopra

このページは私を大いに助けました https://docs.Microsoft.com/en-us/aspnet/core/mvc/models/file-uploads

だから今私のコードで私はコントローラメソッドを持っています:

 public async Task<IActionResult> UploadFiles(UploadedFile ups)

モデルのクラスとして

public class UploadedFile
    {
        public string UploadName { get; set; }
        public List<IFormFile> Files { get; set; }
    }

のような形

<form method="post" enctype="multipart/form-data" asp-controller="Files" asp-action="UploadFiles">
2
mslliviu

適切なJSON形式でファイルとテキストを送信していると思います。

文字列型のプロパティとしてファイルとテキストを含む新しいクラスを作成する必要があります。 attribute [FromBody]を使用してメソッドの引数に新しいクラスを追加すると、必要に応じて画像文字列を解析できます。

別の方法は、リクエストコンテンツ全体にアクセスすることです

await Request.Content.ReadAsStringAsync();

ただし、コンテンツ全体を解析する必要があります。

0
FelschR