web-dev-qa-db-ja.com

ASP.NET MVCで検証に失敗した後、入力タイプ=ファイルフィールド値を保持するにはどうすればよいですか?

作成したMVCアプリにシンプルなフォームがあります。ユーザーが画像をアップロードできるように、ファイルフィールドが含まれています。すべてうまくいきます。

問題は、フォームの送信が検証に失敗した場合、ファイルフィールドのコンテンツが失われることです(他のフィールドは、HtmlHelpersに入力されたままです!)。 検証に失敗した後、ファイルフィールドにデータを入力したままにするにはどうすればよいですか?

TIA!

61
Chaddeus

ブラウザは、セキュリティリスクのためにこのように設計されています。 HTMLソースまたはJavascriptでファイル入力ボックスの値を設定することはできません。そうしないと、悪意のあるスクリプトがユーザーの注意なしにプライベートファイルを盗む可能性があります。

主題について 興味深い情報 があります。

57

私の知る限り、HTMLファイル入力ボックスの値を設定することはできません。ファイル入力ボックスをラベルまたはテキストボックスに結合することをお勧めします。

その後、後で再送信するために、ファイル入力ボックスからの値をitに入力できます。

2
Michael

事前にajaxで検証を行い、ページの部分的な更新を行うことをお勧めします。この場合、ファイルは失われません。

1

ファイルが大きすぎない場合は、base64で隠しフィールドの値として使用できます。

1

Flashベースのファイルアップローダーがあります。それらのいずれかを試してください。フラッシュやJavaスクリプトがサポートされていない場合、jQueryプラグインを探すことをお勧めします。

1
gokkor

「不可能」が正解としてマークされることに同意しません。誰かがまだ可能性を探している場合、ここで私のために働いた回避策があります。 MVC5を使用しています。アイデアは、セッション変数を使用することです。 ASP.Net Form からアイデアを得ました。

私のモデル/ ViewModel(関連するプロパティのみ):

public partial class emp_leaves
    {
        public string fileNameOrig { get; set; }
        public byte[] fileContent { get; set; }

        public HttpPostedFileBase uploadFile { get; set; }
    }

私のコントローラー(HttpPost)で://チェック

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(emp_leaves emp_leaves)
{
    if (emp_leaves.uploadFile != null && emp_leaves.uploadFile.ContentLength>0 && !string.IsNullOrEmpty(emp_leaves.uploadFile.FileName))
    {
        emp_leaves.fileNameOrig = Path.GetFileName(emp_leaves.uploadFile.FileName);
        emp_leaves.fileContent = new byte[emp_leaves.uploadFile.ContentLength];
        emp_leaves.uploadFile.InputStream.Read(emp_leaves.fileContent, 0, emp_leaves.uploadFile.ContentLength);
        Session["emp_leaves.uploadFile"] = emp_leaves.uploadFile; //saving the file in session variable here
    }
    else if (Session["emp_leaves.uploadFile"] != null)
    {//if re-submitting after a failed validation you will reach here.
        emp_leaves.uploadFile = (HttpPostedFileBase)Session["emp_leaves.uploadFile"];
        if (emp_leaves.uploadFile != null && emp_leaves.uploadFile.ContentLength>0 && !string.IsNullOrEmpty(emp_leaves.uploadFile.FileName))
        {
            emp_leaves.fileNameOrig = Path.GetFileName(emp_leaves.uploadFile.FileName);
            emp_leaves.uploadFile.InputStream.Position = 0;
            emp_leaves.fileContent = new byte[emp_leaves.uploadFile.ContentLength];
            emp_leaves.uploadFile.InputStream.Read(emp_leaves.fileContent, 0, emp_leaves.uploadFile.ContentLength);    
        }
    }
//code to save follows here...
}

最後に、編集ビュー内で、ここで、ファイルアップロードコントロールを条件付きで表示しています。

< script type = "text/javascript" >
  $("#removefile").on("click", function(e) {
    if (!confirm('Delete File?')) {
      e.preventDefault();
      return false;
    }
    $('#fileNameOrig').val('');
    //toggle visibility for concerned div
    $('#downloadlrfdiv').hide();
    $('#uploadlrfdiv').show();
    return false;
  }); <
/script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
@model PPMSWEB.Models.emp_leaves @{ HttpPostedFileBase uploadFileSession = Session["emp_leaves.uploadFile"] == null ? null : (HttpPostedFileBase)Session["emp_leaves.uploadFile"]; } @using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data"
})) { @Html.AntiForgeryToken()
<div class="row">
  @*irrelevant content removed*@
  <div id="downloadlrfdiv" @((!String.IsNullOrEmpty(Model.fileNameOrig) && (Model.uploadFile==n ull || uploadFileSession !=null)) ? "" : "style=display:none;")>
    <label>Attachment</label>
    <span>
            <strong>
                <a id="downloadlrf" href="@(uploadFileSession != null? "" : Url.Action("DownloadLRF", "emp_leaves", new { empLeaveId = Model.ID }))" class="text-primary ui-button-text-icon-primary" title="Download attached file">
                    @Model.fileNameOrig
                </a>
            </strong>
            @if (isEditable && !Model.readonlyMode)
            {
                @Html.Raw("&nbsp");
                <a id="removefile" class="btn text-danger lead">
                    <strong title="Delete File" class="glyphicon glyphicon-minus-sign">  </strong>
                </a>
            }
            </span>
  </div>
  <div id="uploadlrfdiv" @(!(!String.IsNullOrEmpty(Model.fileNameOrig) && Model.uploadFile==n ull) && !Model.readonlyMode ? "" : "style=display:none;")>
    <label>Upload File</label> @Html.TextBoxFor(model => model.uploadFile, new { @type = "file", @class = "btn btn-default", @title = "Upload file (max 300 KB)" }) @Html.ValidationMessageFor(x => x.uploadFile)
  </div>
</div>
}
0
Arfath

HTMLファイル入力ボックスの値を設定することはできません。回避策として、検証後にフォームを出力するときに、ファイルアップロードボックスを非表示の入力フィールドに置き換えます。

送信時に、非表示フィールドにファイル入力ボックスの値を入力します(後で再送信するため)。ファイルをアップロードするか、非表示フィールド名を一度に(両方ではなく)表示することを忘れないでください。

注:以下のコードは、イラスト/説明のみを目的としています。使用する言語に適したコードに置き換えてください。

<?php /* You may need to sanitize the value of $_POST['file_upload']; 
* this is just a start */
if(isset($_POST['file_upload']) && !empty($_POST['file_upload'])){ ?>
<input type="hidden" name="file_upload" value="<?php print($_POST['file_upload']); ?>" />
<?php } else { ?>
<input type="file" name="file_upload" />
<?php } ?>
0
Agi Hammerthief