2
<script type="text/javascript">
    $.validator.addMethod('accept', function () { return true; });
</script>
@using (Html.BeginForm("Create","My controller",FormMethod.Post,new {enctype = "multipart/form-data"})) {
    @Html.ValidationSummary(true)
    <fieldset>
        <div class="editor-field">
            <input type="file" id="File" name="File" accept="image/*" />
        </div>

JSがオンになっているファイルをアップロードできません([送信]をクリックすると、ファイル入力の周囲に黄色のフレームが表示され、それ以上何も起こりません)。

JSをオフにすると、フォームが送信されます。

上に3行あるので、ファイルアップロードフォームはJSで魔法のように機能します。これらは私のプロジェクトの1つで見つかりましたが、何をしているのか、なぜ必要なのか思い出せません。

これを説明してもらえますか?

編集

ビューのコード全体。

@using EDoctor.Properties
@using EDoctor.Resources
@model EDoctor.Models.DoctorProfileViewModel

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script type="text/javascript">
    $.validator.addMethod('accept', function () { return true; });
</script>
@using (Html.BeginForm("Create","DoctorProfiles",FormMethod.Post,new {enctype = "multipart/form-data"})) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>DoctorProfiles</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Model.PhotoFileUrl)
        </div>
        <div class="editor-field">
            <input type="file" id="File" name="File" accept="image/*" />
            @Html.ValidationMessage("UploadFile")
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.Model.LicenseNumber)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Model.LicenseNumber)
            @Html.ValidationMessageFor(model => model.Model.LicenseNumber)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Model.FirstName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Model.FirstName)
            @Html.ValidationMessageFor(model => model.Model.FirstName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Model.LastName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Model.LastName)
            @Html.ValidationMessageFor(model => model.Model.LastName)
        </div>

        @Html.HiddenFor(model => model.Model.UserId)

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>
4

3 に答える 3

3

ファイルの種類の検証をオフにしました。デフォルトでは、html ファイル タイプには、特定のタイプのファイルを受け入れる属性があります。このAcceptフィールドは、許可されるファイルの種類を管理します。

$.validator.addMethod('accept', function () { return true; });

常に true を返す検証メソッドを追加する ( success)。その結果、任意のファイル タイプ

于 2013-03-19T02:42:08.047 に答える
2

必須としてマークされているモデル プロパティがあると思いますが、フォームのどこにもありません。私はこれを見る:

@Html.LabelFor(model => model.Model.PhotoFileUrl)

この

@Html.ValidationMessage("UploadFile")

ただし、これはファイル要素に使用するマークアップです。

<input type="file" id="File" name="File" accept="image/*" />

したがって、モデルがフィールドに[Required]属性を持っている可能性がありますUploadFile。バリデーターは検証するフィールドを見つけることができないため、これは目立たない検証をトリガーする可能性があります。

于 2013-03-19T17:39:36.587 に答える
1

DaveとTiesonの助けを借りて、私はついにそれを解決し、素晴らしいクライアント側の検証を得ました。誰かがクライアント側のファイル検証も実行する必要がある場合は、ここに詳細な説明を投稿します。

一般的なアイデア

  • MVC / jQueryは、 accept = "image/*"を期待どおりに理解しません。*.pngを受け入れません。例:
  • @ Html.ValidationMessage( "file_input")を追加しない限り、エラーメッセージを表示する場所はありません。結果として、フォームを送信しようとすると、フィールドの周りに黄色のフレーム(クロム)または何も表示されず、顔に大きなWTFが表示されるだけです。
  • @ Html.ValidationMessageは、次のhtmlを生成します。

    <span class="field-validation-valid" data-valmsg-for="file_input" data-valmsg-replace="true"></span>
    
  • jQueryバリデーターは、上記の行がhtmlで見つかった場合、独自の検証メッセージを配置するように要求します。

クライアント側で画像の形式とサイズを検証し、カスタム/ローカライズされた検証メッセージを取得したい場合はどうなりますか?おそらく何らかのプラグインを使用できますが、次のようにすることもできます。

<div class="editor-field">
    <input type="file" id="file_input" name="file_input" onchange='validate_image_upload(this)' accept="image/*" class="fileToUpload" data-error-msg-max-size="@string.Format(ErrorMessages.FileSizeExceedsMaxSize,Settings.Default.OfficialMaxFileUploadSizeMBs)" data-error-msg-file-format="@string.Format(ErrorMessages.IncorrectImageFile, Settings.Default.AcceptableImageFormats)" data-max-size="1500000" data-acceptable-formats="@Settings.Default.AcceptableImageFormats"/>
    @Html.ValidationMessage("file_input[custom]")
</div>

ValidationMessageの「file_input」に「[custom]」を追加することに注意してください

これは、jQueryをだまし、jQueryが独自の検証メッセージを送信しないようにするために行います。(変更しない場合、jQueryは容赦なく自分のメッセージを殺します)。それでも、元のMVCスタイルのエラーメッセージが表示され、Razorを使用して生成できます。なんとかして内容を設定するだけです。これは、ビューファイルの上に(他のスクリプトタグの下に)次のコードを追加することで実行できます。

<script type="text/javascript">
    $.validator.addMethod('accept', IsFileValid);
</script>

今、何が起きた?

  • 独自のメソッド(IsFileValid)を挿入することにより、画像ファイルを受け入れるというjQueryの奇妙なアイデアを無視します。
  • IsFileValidがfalseを返した場合でも、jQueryは独自の検証メッセージを表示したいと考えています。しかし、それを置く場所がなく(ValidationMessageに「[custom]」を追加しました)、次のhtmlが生成されます。

    <span class="field-validation-valid" data-valmsg-for="file_input[custom]" data-valmsg-replace="true"></span>
    

そしてjQueryは探しています

<span class="field-validation-valid" data-valmsg-for="file_input" data-valmsg-replace="true"></span>
  • 何も見つからないため、入力フィールドを強調表示し、送信ボタンをブロックします。(いいですね、作業の半分は私たちのために行われています)

  • これまでに行う必要があるのは、このスクリプトで実行できる独自の検証メッセージを配置することだけです。(IsFileValidはすべてを処理するため、上記以外のことを行う必要はありません)。

    function IsFileValid(value, field) {
        return validate_image_upload(field);
    }
    
    String.prototype.format = function () {
        var s = arguments[0];
        for (var i = 0; i < arguments.length - 1; i++) {
            var reg = new RegExp("\\{" + i + "\\}", "gm");
            s = s.replace(reg, arguments[i + 1]);
        }
    
        return s;
    };
    
    function validate_image_upload(field) {
        var isValid = validate_image_size(field) &&
            validate_image_format(field);
    
        if (isValid)
            remove_error_message(field);
        else
            append_error_message(field);
    
        return isValid;
    }
    
    function validate_image_format(field) {
        var ext = $(field).val().split('.').pop().toLowerCase();
        var acceptabelExtensions = $(field).data("acceptableFormats").toLowerCase().split(',');
        if ($.inArray(ext, acceptabelExtensions) == -1) {
            var msg = String.prototype.format($(field).data("errorMsgFileFormat"), acceptabelExtensions.join(', '));
            append_error_message(field, msg);
            return false;
        } else {
            return true;
        }
    }
    
    function validate_image_size(field) {
        if (field.files[0].size > $(field).data("maxSize")) {
            append_error_message(field, $(field).data("errorMsgMaxSize"));
            return false;
        } else {
            return true;
        }
    }
    
    function append_error_message(field, msg) {
        var f = $(field);
        var sib = f.siblings();
        $.each(sib, function (i, v) {
            var name1 = $(v).data("valmsgFor");
            var name2 = f.attr("name") + "[custom]";
            if (name1 == name2) {
                $(v).attr("class", "field-validation-error");
                $(v).text(msg);
                return;
            }
        });
    }
    
    function remove_error_message(field) {
        var f = $(field);
        var sib = f.siblings();
        $.each(sib, function (i, v) {
            var name1 = $(v).data("valmsgFor");
            var name2 = f.attr("name") + "[custom]";
            if (name1 == name2) {
                $(v).attr("class", "field-validation-valid");
                return;
            }
        });
    }
    

備考

  • スクリプトはファイル拡張子とファイルサイズを検証します
  • 検証メッセージを表示/非表示にします(このfile_input [custom]を検索し、 file_inputにマップします)
  • IsFileValidメソッドは、ファイル入力の変更時にもフックされます(したがって、不正な画像を選択すると、すぐにエラーが表示されます)
  • 最大ファイルサイズと受け入れられるファイル拡張子は、設定からのビューを介して渡されます。(入力タグを参照してください)。
  • 検証メッセージはビューフォームリソースを介して渡されるため、簡単にローカライズできます(入力タグを参照)
  • もちろん、それは安全ではありません。それはただユーザーフレンドリーです。サーバー側の検証も忘れずに実行してください。

私が誰かを数時間救ったことを願っています。:)

于 2013-03-20T00:04:39.290 に答える