WebSurfer's Home

トップ > Blog 1   |   Login
Filter by APML

canvas の画像をアップロード (その 2)

by WebSurfer 20. November 2022 11:46

先の記事「canvas の画像をアップロード」の機能を .NET 6.0 の ASP.NET Core MVC アプリに実装しました。以下に備忘録として書いておきます。

canvas の画像をアップロード

基本的には先の記事と同じことを行っており、クライアントの PC にある画像を HTML5 の File API を利用して取得し、それを指定のサイズに縮小して HTML5 の canvas に描画し、canvas に描画された画像をサーバーにアップロードして保存するというものです。

先の記事との違いは、(1) アプリが先の記事では ASP.NET Web Forms であったものがこの記事では ASP.NET Core MVC であること、(2) jQuery は使わないようにしたこと(なので、jQuery ajax に代えて fetch API を使ってます)、(3) アップロードされてきたファイルを受けるのを ASP.NET Core Web API のコントローラーとしたことです。

概略の動きは以下の通りです。詳しくは下のサンプルコードとそれに書いたコメントを参照ください。

  1. クライアントによる画像ファイルの選択は HTML の <input type="file" ... /> を利用する。
  2. <input type="file" ... /> で画像ファイルが選択されたタイミングで、HTML5 File API の FileReader オブジェクトに readAsDataURL メソッド を使って選択された画像ファイルを読み込む。
  3. FileReader の result プロパティ を使って、読み込んだ画像ファイルを Data url 形式("data:image/jpeg;base64, ..." という文字列)で取得し、それを image オブジェクトの src 属性に設定する。
  4. その image オブジェクトを HTML5 の canvas に CanvasRenderingContext2D.drawImage() メソッド を使って描画する。その際、描画する画像の最大サイズの制限を設け(今回のサンプルでは 500 x 500 とした)、それに入る場合はそのまま、入らない場合は幅・高さどちらか大きい方を 500px に縮小し他方をその縮小率と同じに縮小(要するに縦横比を保ったまま 500 x 500 に入るよう縮小)する。
  5. canvas 上の縮小後の画像データを取得して Web サーバーに fetch API を使って送信するメソッドを作る。canvas からの画像データの取得は HTMLCanvasElement.toDataURL() メソッド を用いる。Data url 形式で取得できるので、それを fetch API を用いて JSON 形式で送信する。(BASE64 でエンコードされているので、バイナリ形式よりサイズが約 1.3 倍大きくなってしまうが・・・)
  6. <input type="button" ... /> タイプのボタンを配置し、その onclick 属性に上記のメソッドを設定する。
  7. 非同期でクライアントから送信された BASE64 形式の画像データは、ASP.NET Core Web API のコントローラーで受け、デコードしてバイナリ形式に戻してファイルに保存する。
  8. 先の記事と同様に、画像ファイルのサイズを 500,000 bytes に、ファイルのタイプを image/jpeg に制限する機能も実装した。

上記を実現するための JavaScript のコードを実装した View のサンプルコードは以下の通りです。

@{
    ViewData["Title"] = "Canvas";
}

<h1>Canvas</h1>

<input type="file" id="file1" />
<input id="button1" type="button" value="Upload" style="display:none;" />
<br />
<div id="msg"></div>
<canvas id="mycanvas"></canvas>
<div id="result"></div>

@section Scripts {
    <script type="text/javascript">
    //<![CDATA[
        // 以下の操作を行っている:

        // File API の FileReader を利用して、input type="file" で
        // 選択された画像ファイルを読み込み、その画像の Data url 
        // 形式の文字列を取得。

        // その Data url 形式文字列を image オブジェクトの src 属
        // 性に設定するとロード完了時に image.onload イベントが発
        // 生するので、そのイベントのリスナで image オブジェクトの
        // 画像を指定のサイズ以下に縮小して canvas に描画する。

        // [Upload] ボタンクリックで uploadImage メソッドを起動。
        // そのメソッド内で canvas の画像データを DataURL 形式で取
        // 得して JSON 文字列を組み立て、それを fetch API を使って
        // サーバーに送信する。

        // 上に述べた FileReader と image オブジェクトへの参照。
        // 初期化は下の DOMContentLoaded イベントのリスナで行う
        let fileReader;
        let image;

        // 画像のサイズとタイプの制限。ここではそれぞれ 500000 
        // バイト、image/jpeg に制限している
        const maxFileSize = 500000;
        const allowedContentType = "image/jpeg";
 
        // canvas に描く画像のサイズ制限。ここでは 500 x 500 以下
        // に制限している
        const maxWidth = 500;
        const maxHeight = 500;

        // 上に定義されている input type="file" などのオブジェクト
        // をいちいち getElementById で取得しなくて済むように以下
        // の変数に保持。代入は下の DOMContentLoaded イベントのリ
        // スナで行う
        let inputFile, uploadButton, msgDiv, myCanvas, resultDiv;         

        // DOMContentLoaded イベントのリスナ設定
        window.addEventListener('DOMContentLoaded', () => {
            inputFile = document.getElementById("file1");
            uploadButton = document.getElementById("button1");
            msgDiv = document.getElementById("msg");
            myCanvas = document.getElementById("mycanvas");
            resultDiv = document.getElementById("result");

            // ブラウザの HTML5 File API サポートを確認
            if (window.File && window.FileReader && window.FileList) {

                // fileReader と image オブジェクトの初期化
                fileReader = new FileReader();
                image = new Image();                

                // [Upload] ボタンクリックで uploadImage メソッド
                // を起動できるようリスナとして設定
                uploadButton.addEventListener('click', uploadImage);

                // input type="file" でファイルの選択が完了すると 
                // change イベントが発生するのでそれにリスナをアタ
                // ッチし、以下の処置を行う
                inputFile.addEventListener('change', () => {
                    resultDiv.innerText = "";

                    // 選択されたファイルのタイプ/サイズの検証
                    // ClientValidate ヘルパメソッドは下の定義参照
                    if (ClientValidate(inputFile) == false) {
                        uploadButton.style.display = "none";
                        myCanvas.style.display = "none";
                        return;
                    }

                    // fileReader オブジェクトに input type="file" 
                    // で選択された画像ファイルを読み込む
                    fileReader.readAsDataURL(inputFile.files[0]);
                });

                // 上の readAsDataURL メソッドは非同期で動くので、
                // 読み込み完了の onloadend イベントのリスナで 
                // FileReader から Data url を取得し image オブジ
                // ェクトの src 属性に設定する
                fileReader.onloadend = () => {
                    image.src = fileReader.result; 
                };
                
                // image オブジェクトで画像のロードが完了すると 
                // image.onload イベントが発生するので、そのイベン
                // トのリスナで image オブジェクトが保持する画像を
                // サイズ制限以下に縮小して canvas 描画する。
                // DrawImageOnCanvas メソッドは下の定義参照
                image.onload = DrawImageOnCanvas;
            }
            else {
                inputFile.style.display = "none";
                myCanvas.style.display = "none";
                msgDiv.innerText =
                    "File API がサポートされていません。";
            }
        });

        // 選択されたファイルの検証のためのヘルパ関数
        function ClientValidate(fileUpload) {
            msgDiv.innerText = "";

            if (fileUpload.files[0] == null) {
                msgDiv.innerText = "ファイルが未選択です。";
                return false;
            }

            if (fileUpload.files[0].type != allowedContentType) {
                msgDiv.innerText = "選択されたファイルのタイプが " + 
                    allowedContentType + " ではありません。";
                return false;
            }

            if (fileUpload.files[0].size > maxFileSize) {
                msgDiv.innerText = "ファイルのサイズが " + 
                    maxFileSize + " バイトを超えています。";
                return false;
            }

            return true;
        }

        // 上で定義した image オブジェクトの src 属性に Data url
        // が設定され画像のロードが完了すると発生する onload イ
        // ベントにアタッチするリスナ。これで image 要素の画像を
        // 指定されたサイズ以下に縮小して canvas に描画する
        function DrawImageOnCanvas() {
            // オリジナル画像のサイズ
            const w = image.width;
            const h = image.height;

            let targetW, targetH;
            const context = myCanvas.getContext('2d');

            if (w <= maxWidth && h <= maxHeight) {
                // w, h ともに制限 maxWidth, maxHeight 以内 ⇒
                // そのままのサイズで canvas に描画
                myCanvas.setAttribute('width', w);
                myCanvas.setAttribute('height', h);
                context.drawImage(image, 0, 0);
            }
            else if (w < h) {
                // w, h どちらかが制限オーバーで h の方が大きい ⇒
                // 高さを maxHeight に縮小
                targetH = maxHeight;
                // 幅は高さの縮小比率で縮小
                targetW = Math.floor(w * targetH / h);
                myCanvas.setAttribute('width', targetW);
                myCanvas.setAttribute('height', targetH);
                context.drawImage(image, 0, 0, targetW, targetH);
            }
            else {
                // w, h どちらかが制限オーバーで w の方が大きい ⇒
                // 幅を maxWidth に縮小
                targetW = maxWidth;
                // 高さは幅の縮小比率で縮小
                targetH = Math.floor(h * targetW / w);
                myCanvas.setAttribute('width', targetW);
                myCanvas.setAttribute('height', targetH);
                context.drawImage(image, 0, 0, targetW, targetH);
            }

            uploadButton.style.display = "inline-block";
            myCanvas.style.display = "block";
        }

        // canvas の画像データを DataURL 形式で取得し、JSON 文
        // 字列を組み立てて fetch API で送信。
        async function uploadImage() {
            const context = myCanvas.getContext('2d');
            const dataUrl = context.canvas.toDataURL("image/jpeg");
            const params = {
                method: "POST",
                body: '{"imgBase64":"' + dataUrl + '"}',
                headers: { 'Content-Type': 'application/json' }
            }
            const response = await fetch("/api/Canvas", params);
            if (response.ok) { 
                const message = await response.text();
                resultDiv.innerText = message
            } else {
                resultDiv.innerText = "アップロード失敗";
            }
        }
    //]]>
    </script>
}

クライアントから JSON 形式で送信されてきた BASE64 形式の画像データは、以下のコードの ASP.NET Core Web API のコントローラーで受け、デコードしてバイナリ形式に戻してファイルに保存しています。

using Microsoft.AspNetCore.Mvc;

namespace MvcCore6App3.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class CanvasController : ControllerBase
    {
        // 物理パスの取得用
        private readonly IWebHostEnvironment _hostingEnvironment;

        public CanvasController(IWebHostEnvironment hostingEnvironment)
        {
            this._hostingEnvironment = hostingEnvironment;
        }

        [HttpPost]        
        public async Task<string> Post([FromBody] JsonData data)
        {
            // 文字列先頭の "data:image/jpeg;base64," を除去。
            string imgBase64 = 
                data.ImgBase64.Replace("data:image/jpeg;base64,", "");

            // BASE64 エンコードされた画像データを元のバイト列に変換
            Byte[] imgByteArray = Convert.FromBase64String(imgBase64);

            // ファイル名を設定
            string filename = 
                $"img{DateTime.Now.ToString("yyyyMMddHHmmss")}.jpg";

            // アプリケーションルートの物理パスを取得
            string contentRootPath = 
                _hostingEnvironment.ContentRootPath;

            string filePath = 
                $"{contentRootPath}\\UploadedFiles\\{filename}";

            // フォルダ UploadedFile に画像ファイルを保存
            await System.IO.File
                 .WriteAllBytesAsync(filePath, imgByteArray);

            return $"ファイル名 {filename} として保存しました。";
        }
    }

    // 先の記事の ASP.NET Web Forms アプリの Web メソッドでは
    // ReceiveImage(string imgBase64) という形で引数の imgBase64
    // に直接  {"imgBase64":"value"} の value を受け取ることがで
    // きたが、Web API ではそのようなことはできず、以下のような
    // クラスを定義して、それで受け取る必要がある
    public class JsonData
    {
        public string ImgBase64 { get; set; } = null!;
    }
}

JavaScript はブラウザ依存なところがありますが、Edge 107.0.1418.52, Chrome 107.0.5304.107, Firefox 107.0, Opera 93.0.4585.11 では期待通り動くことは確認しました。

Tags: , , , , ,

Upload Download

Blazor WASM でファイルアップロード

by WebSurfer 28. October 2022 14:12

Blazor Web Assembly (WASM) アプリで、html の form 要素及び input type="file" 要素と jQuery ajax を使ってファイルをアップロードする方法を書きます。

Blazor WASM でファイルアップロード

(.NET 5.0 以降であれば、InputFile クラスを利用できるそうですので、そちらを使う方がいいかもしれません。詳細は Microsoft のドキュメント「ASP.NET Core Blazor ファイルのアップロード」を見てください)

jQuery / JavaScript を使ってファイルのアップロードはできますので、基本ブラウザである Blazor WASM のクライアント側からでも同様にファイルのアップロードはできます。

その jQuery / JavaScript のコードを Blazor WASM のクライアント側に組み込んで呼び出すことで、Blazor WASM アプリとしてファイルのアップロード機能を持たせることが可能です。(以下に概略を書きますが、詳細は Microsoft のドキュメント「ASP.NET Core Blazor で .NET メソッドから JavaScript 関数を呼び出す」を見てください)

なお、input type="submit" ボタンを form 要素内に配置して、それをクリックするというのは NG です。ファイルはアップロードされますが、返ってきた応答でブラウザの画面が書き換えられてしまうので。

jQuery ajax を使ってのファイルのアップロード機能をどのように実装するかの具体例を以下に書いておきます。

ベースとする Blazro WASM ソリューションは、Visual Studio 2022 のテンプレートを使って、フレームワーク .NET 6.0 で、[ASP.NET Core でホストされた(h)]にチェックを入れて作成したものを使います。ソリューション内に Client, Server, Shared という 3 つのプロジェクトができるはずです。

(1) ファイルアップロード用の Razor ページ

Client プロジェクトの Pages フォルダに以下の Razor ページを追加します。

@page "/fileupload"
@inject IJSRuntime JSRuntime;

<h3>File Upload bys jQuery Ajax</h3>

<form id="form1" method="post" enctype="multipart/form-data">
    <input type="file" name="postedfile" />
</form>

<button type="button" class="btn btn-primary" @onclick="UploadFile">
    アップロード
</button>

<div id="result"></div>

@code {
    private async Task UploadFile()
    {
        await JSRuntime.InvokeVoidAsync("uploadFile");
    }
}

Shared フォルダの NavMenu.razor に上の fileupload ページへのリンクを追加し、メニューからリンクをクリックしてアクセスできるようにします。

(2) ファイルアップロード用の js ファイル

ファイルをアップロードする jQuery / JavaScript コードのコードを含んだ js ファイルを作成します。コードは以下の通りです。js ファイルの名前は任意ですがここでは exampleJsInterop.js としておきます。

window.uploadFile = () => {
    // FormData オブジェクトの利用
    var fd = new FormData(document.getElementById("form1"));

    $.ajax({
        url: '/Upload',
        method: 'post',
        data: fd,
        processData: false, // jQuery にデータを処理させない
        contentType: false  // contentType を設定させない
    }).done(function (response) {
        $("#result").empty;
        $("#result").text(response);
    }).fail(function (jqXHR, textStatus, errorThrown) {
        $("#result").empty;
        $("#result").text('textStatus: ' + textStatus +
            ', errorThrown: ' + errorThrown);
    });
}

(3) js ファイルの配置

上の exampleJsInterop.js と jQuery.js を、Client プロジェクトの wwwroot フォルダ下に js フォルダを作って、その中に配置します。

js ファイルの配置

(4) index.html に script タグを追加

Client プロジェクトの wwwroot フォルダ下の index.html に、exampleJsInterop.js と jQuery.js がダウンロードされるよう、script タグを追加します。

Index.html に script タグを追加

(5) Server プロジェクトに Controller 追加

Server プロジェクトの Controllers フォルダにアップロードされたファイルを受け取って必要な処置をする Controller を追加します。

具体例は以下のコードを見てください。Web API の Controller としています。名前をステップ (2) の jQuery / JavaScript のコードにある url: '/Upload' と合わせる必要があることに注意してください。

using Microsoft.AspNetCore.Mvc;

namespace BlazorWasmCoreHosted.Server.Controllers
{
    [Route("[controller]")]
    [ApiController]
    public class UploadController : ControllerBase
    {
        // .NET 6.0 で作ったプロジェクトは「Null 許容」オプションが「有効化」に
        // 設定してあるので、引数も NULL 許容にしておかないと、クライアントでファ
        // イルを選択しないで送信した場合、HTTP 400 Bad Request エラーになって
        //  "The postedFile field is required."というエラーメッセージが返ってくる
        [HttpPost]
        public string Post([FromForm] IFormFile? postedFile)
        {
            string result = "";
            if (postedFile != null && postedFile.Length > 0)
            {
                // アップロードされたファイル名を取得
                string filename = System.IO.Path.GetFileName(postedFile.FileName);

                // アップロードされたファイルを処理(省略)

                result = $"{filename} ({postedFile.ContentType}) - " +
                    $"{postedFile.Length} bytes アップロード完了";
            }
            else
            {
                result = "ファイルアップロードに失敗しました";
            }

            return result;
        }
    }
}

アプリを実行してファイルアップロードに成功するとこの記事の一番上にある画像のようになります。

Tags: , , ,

Upload Download

ファイルアップロード時の検証 (CORE)

by WebSurfer 26. January 2021 22:32

ASP.NET Core. 3.1 MVC アプリでファイルをアップロードする際に、カスタム検証属性を利用してファイルのサイズとタイプをクライアント側とサーバー側の両方で検証し、検証結果 NG の場合はエラーメッセージを表示する方法について書きます。

ファイルアップロード時の検証

基本的には先の記事「ASP.NET Core MVC 検証属性の自作」の応用です。先の記事ではパラメータが 1 つだけでしたが、この記事ではファイルのサイズとタイプという 2 つを検証するところが大きな違いです。

クライアント側での検証は、Web Forms アプリの記事「FileUpload と CustomValidator」と同様に、ブラウザの HTML5 File API を利用して JavaScript でファイルのサイズとタイプ情報を取得し、外部から入力されるパラメータ値と比較して検証します。

そのパラメータ値はカスタム検証属性(下のコード例では FileValidationAttribute)をモデルのプロパティに設定する際に引数(下のコード例では 50000 と "image/jpeg")として渡すようにしています。

サーバー側では引数に渡されたパラメータ値(ファイルサイズ / タイプ)を容易に取得でき、検証属性クラスの IsValid メソッドに引数として渡される IFromFile オブジェクトから取得できるファイルサイズとタイプを比較して検証できます。問題はクライアント側での検証用 JavaScript / jQuery にそのパラメータ値をどのように渡すかです。

パラメータが 1 つだけなら先の記事「ASP.NET Core MVC 検証属性の自作」で書いた View の中のスクリプトのように addSingleVal メソッドを利用できます。しかし、2 つあると addSingleVal メソッドでは何ともならず、add メソッドを利用せざるを得ないようです。

add メソッドの使い方は、先の記事を書くときに調べた Unobtrusive Client Validation in ASP.NET MVC 3 という記事に記述がありましたが、具体的にどういうコードを書けばいいのかが分かりません。

やむを得ず検証用の控えめな JavaScript のソースコード jquery.validate.unobtrusive.js を調べると、addBool, addSingleVal, addMinMax メソッドは add メソッドをラップしたものだということが分かりました。その中の addMinMax メソッドが min, max というパラメータを 2 つ渡していますので、それを見よう見まねで書いてみたのが下の View の中のコードです。

Edge, Chrome のデバッガでスクリプトをステップ実行するなどして調べましたが一応は期待通り動いていることを確認しました。具体的にどのような仕組みで動いているかまでは分かっていませんが。(汗)

いかにサンプルコードをアップしておきます。上の画像を表示したものです。要点はコメントに書いたつもりですのでそれを見てください。(手抜きでスミマセン)

Model とカスタム検証属性

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using System.Globalization;
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace MvcCoreApp.Models
{
    // Model
    public class FileUpload
    {
        [Required(ErrorMessage = "{0} is required.")]
        public string Name { get; set; }

        [Display(Name = "Upload file")]
        [Required(ErrorMessage = "{0} is required.")]
        [FileValidation(50000, "image/jpeg")]
        public IFormFile PostedFile { get; set; }
    }

    // カスタム検証属性
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class FileValidationAttribute : ValidationAttribute, 
                                           IClientModelValidator
    {
        private readonly long size;
        private readonly string type;

        public FileValidationAttribute(long size, string type)
        {
            this.size = size;
            this.type = type;
            this.ErrorMessage = "{0} must be less than {1} byte, {2}";
        }

        public override string FormatErrorMessage(string displayName)
        {
            return String.Format(CultureInfo.CurrentCulture, 
                                 ErrorMessageString, displayName, 
                                 this.size, this.type);
        }

        public override bool IsValid(object value)
        {
            var postedFile = value as IFormFile;

            if (postedFile == null || postedFile.Length == 0)
            {
                return false;
            }

            if (postedFile.Length <= this.size && 
                postedFile.ContentType == this.type)
            {
                return true;
            }

            return false;
        }
        // IClientModelValidator が実装するメソッド。検証対象の input
        // 要素に控えめな JavaScript (jquery.validate.unobtrusive.js)
        // による検証のための属性と値を追加
        public void AddValidation(ClientModelValidationContext context)
        {
            MergeAttribute(context.Attributes, "data-val", "true");
            var errorMessage = FormatErrorMessage(
                context.ModelMetadata.GetDisplayName());
            MergeAttribute(context.Attributes, 
                "data-val-filevalidation", errorMessage);
            MergeAttribute(context.Attributes, 
                "data-val-filevalidation-size", this.size.ToString());
            MergeAttribute(context.Attributes, 
                "data-val-filevalidation-type", this.type);
        }

        // 上の AddValidation メソッドで使うヘルパーメソッド
        private bool MergeAttribute(IDictionary<string, string> attributes, 
                                    string key, string value)
        {
            if (attributes.ContainsKey(key))
            {
                return false;
            }
            attributes.Add(key, value);
            return true;
        }
    }
}

View

@model MvcCoreApp.Models.FileUpload

@{
    ViewData["Title"] = "Upload";
}

<h1>Upload</h1>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="Upload" enctype="multipart/form-data">
            <div asp-validation-summary="ModelOnly" class="text-danger">
            </div>
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>

            <div class="form-group">
                <label asp-for="PostedFile" class="control-label"></label>
                <input type="file" asp-for="PostedFile" />
                <br />
                <span asp-validation-for="PostedFile" class="text-danger">
                </span>
            </div>

            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}


<script type="text/javascript">
    //<![CDATA[
    $.validator.addMethod("filevalidation",
        function (value, element, parameters){
            // HTML5 File API の File, FileList がサポートされている
            // 場合のみ検証する。サポートされてないとスクリプトエラ
            // ーになるので下の if 文は必要
            if (window.File && window.FileList) {

                // ファイルが選択されてないと fileUpload.files[0] は
                // undefined になる。element.files[0] == null は念のため
                if (element.files[0] == undefined ||
                    element.files[0] == null) {
                    // ファイル未選択は RequiredAttribute で検証する
                    // こととし、ここでは true を返すことにした(検証
                    // とエラーメッセージがダブらないように)
                    return true;
                }

                if (element.files[0].type != parameters.type) {                    
                    return false;
                }

                if (element.files[0].size > Number(parameters.size)) {
                    return false;
                }

                return ture;
            } else {
                // HTML5 File API の File, FileList がサポートされて
                // いない場合はクライアント側では検証しない
                return ture;
            }
        });

    // パラメータを 2 つ渡す方法が問題。add メソッドを使わざるを得ない
    $.validator.unobtrusive.adapters.
        add("filevalidation", ["type", "size"], function (options) {

            // 上の検証スクリプトで parameters.type, parameters.size と
            // という形でパラメータを取得するには以下のように JavaScript
            // オブジェクトとして setValidationValues の第 3 引数に渡す。
            // 配列 [options.params.size,options.params.type] としても渡
            // せるが、取得するとき parameters[0] のようにする必要がある
            var value = {
                size: options.params.size,
                type: options.params.type
            };

            setValidationValues(options, "filevalidation", value);
        });

    // jquery.validate.unobtrusive.js からコピーしたヘルパーメソッド
    function setValidationValues(options, ruleName, value) {
        options.rules[ruleName] = value;
        if (options.message) {
            options.messages[ruleName] = options.message;
        }
    }
    //]]>
</script>
}

Comtroller / Action Method

using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using MvcCoreApp.Models;
using Microsoft.AspNetCore.Http;
using System.IO;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace MvcCoreApp.Controllers
{
    public class ValidationController : Controller
    {
        public IActionResult Upload()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult Upload(FileUpload model)
        {
            string result = "";
            IFormFile postedFile = model.PostedFile;

            if (ModelState.IsValid)            
            {
                string filename = Path.GetFileName(postedFile.FileName);
                
                result = filename + " (" + postedFile.ContentType + ") - " +
                        postedFile.Length + " bytes アップロード完了";
            }
            else
            {
                result = "ファイルアップロードに失敗しました";
            }

            ViewBag.Result = result;
            return View();
        }
    }
}

Tags: , , , ,

Upload Download

About this blog

2010年5月にこのブログを立ち上げました。その後ブログ2を追加し、ここはプログラミング関係、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  November 2022  >>
MoTuWeThFrSaSu
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar