Asp.NET Core 3.1フレームワークを使用してサーバーにファイルをアップロードするときにプロパティとしてIFormFileを使用するにはどうすればよいですか?

user12310517

ファイルの保存を処理するWebAPIを作成しようとしています。

Asp.Netコア1.0+フレームワークには、ファイルをビューモデルにバインドできるIFormFileインターフェイスが付属しています。ASP.NETコアでのアップロードファイルに関するドキュメントは、次のことを述べて

IFormFileは、アクションメソッドパラメーターまたはバインドされたモデルプロパティとして直接使用できます。

IFormFileアクションメソッドのパラメータとして使用したところ、問題なく動作しました。しかし、私の場合は、カスタム検証ルールを含めることに加えて他の値をバインドしたいので、モデルのプロパティとして使用したいと思います。これが私のビューモデルです。

public class NewFile
{
    [Required]
    [MinFileSize(125), MaxFileSize(5 * 1024 * 1024)]
    [AllowedExtensions(new[] { ".jpg", ".png", ".gif", ".jpeg", ".tiff" })]
    public IFormFile File { get; set; }

    [Required]
    public int? CustomField1 { get; set; }

    [Required]
    public int? CustomField2 { get; set; }

    [Required]
    public int? CustomField3 { get; set; }
}

これは、クライアント要求とファイルを受け入れるサーバーコードの両方のコードです。簡単にするために、両方のメソッドは同じコントローラーに配置されています。しかし実際には、「クライアント」メソッドは、ファイルを送信する別のアプリケーションに配置されます。

[ApiController, Route("api/[controller]")]
public class FilesController : ControllerBase
{
    [HttpGet("client")]
    public async Task<IActionResult> Client()
    {
        using HttpClient client = new HttpClient();

        // we need to send a request with multipart/form-data
        var multiForm = new MultipartFormDataContent
        {
            // add API method parameters
            { new StringContent("CustomField1"), "1" },
            { new StringContent("CustomField2"), "1234" },
            { new StringContent("CustomField3"), "5" },
        };

        // add file and directly upload it
        using FileStream fs = System.IO.File.OpenRead("C:/1.jpg");
        multiForm.Add(new StreamContent(fs), "file", "1.jpg");

        // send request to API
        var responce = await client.PostAsync("https://localhost:123/api/files/store", multiForm);

        return Content("Done");
    }

    [HttpPost("store")]
    public async Task<IActionResult> Store(NewFile model)
    {
        if (ModelState.IsValid)
        {
            try
            {
                var filename = MakeFileName(model, Path.GetFileName(model.File.FileName));

                Directory.CreateDirectory(Path.GetDirectoryName(filename));

                using var stream = new FileStream(filename, FileMode.Create);
                await model.File.CopyToAsync(stream);

                return PhysicalFile(filename, "application/octet-stream");
            }
            catch (Exception e)
            {
                return Problem(e.Message);
            }
        }

        // Are there a better way to display validation errors when using Web API?
        var errors = string.Join("; ", ModelState.Values.SelectMany(v => v.Errors).Select(v => v.ErrorMessage));

        return Problem(errors);
    }
}

リクエストを行うと、次のエラーが発生storeしますが、ブレークポイントを配置したため、リクエストはメソッドに到達しませんが、メソッドには到達しません

StatusCode:415、ReasonPhrase: 'サポートされていないメディアタイプ'、バージョン:1.1、コンテンツ:System.Net.Http.HttpConnectionResponseContent

ファイルをサーバーに正しく送信Fileし、ビューモデルのプロパティにバインドするにはどうすればよいですか?

Nkosi

ApiController 特に明記されていない限り、デフォルトではJSONを想定しています

[FromForm]リクエスト本文のform-dataを使用してモデルをバインドするために使用します。

public async Task<IActionResult> Store([FromForm]NewFile model) {
    //...
}. 

ASP.NETCoreでの参照モデルのバインド

CustomField1、CustomField2、およびCustomField3`は、元の質問にあるように送信されているにもかかわらず、nullです。

クライアントはこれらの他のフィールドを正しく送信していません。コンテンツとフィールド名を切り替えました

var multiForm = new MultipartFormDataContent {
    // add API method parameters
    { new StringContent("1"), "CustomField1" },
    { new StringContent("1234"), "CustomField2" },
    { new StringContent("5"), "CustomField3" },
};

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ