簡體   English   中英

IFormFile 始終為空(帶有 MVC/Razor 的 ASP.NET Core)

[英]IFormFile always null (ASP.NET Core with MVC/Razor)

我有一個嘗試上傳 IFormFile 的 ASP.NET Core MVC 應用程序。 但是,IFormFile 始終為空。 我發現的其他解決方案都沒有解決這個問題。 我究竟做錯了什么?

模型

public class EmailForm
{
    [Display(Name = "Add a picture")]
    [DataType(DataType.Upload)]
    [FileExtensions(Extensions = "jpg,png,gif,jpeg,bmp,svg")]
    public IFormFile SubmitterPicture { get; set; }
}

控制器

public async Task<ActionResult> Contribute([Bind("SubmitterPicture")] EmailForm model)
{
    if (ModelState.IsValid)
    {
        //Do some stuff
    }
}

看法

        <form method="post" asp-action="Contribute" asp-antiforgery="true" enctype="multipart/form-data" >
            <div class="form-group" >
                <div class="col-md-2">@Html.LabelFor(m => m.SubmitterPicture)</div>
                <div class="col-md-4">
                    <input type="file" name="SubmitterPicture" id="SubmitterPicture" />
    </div>
            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" class="btn btn-default" value="Contribute" />
                </div>
            </div>
<form method="post" enctype="multipart/form-data">
</form>

enctype="多部分/表單數據"

多部分表單數據是關鍵。

您也可以從HttpContext.Request.Form.Files獲取文件並擺脫模型中的IFormFile接口。 我推薦這種方法,因為我認為文件與數據模型無關。

這個例子是:

public IActionResult Index()
{
    //Please note that if no form data is posted
    // HttpContext.Request.Form will throw an exception
    if (HttpContext.Request.Form.Files[0] != null) {
        var file = HttpContext.Request.Form.Files[0];
        using (FileStream fs = new FileStream("Your Path", FileMode.CreateNew, FileAccess.Write, FileShare.Write)) {
            file.CopyTo(fs);
        }
    }
    return View();
}

如果此方法也失敗,則意味着multipart請求有問題。

在同一個問題坐了幾個小時后,我找到了解決方案。

問題:

在表單中提交單個輸入。

結論:

基本上,在您的 html 表單中,如果除了提交按鈕之外只有一個輸入,這將不起作用。 當我在 viewModel 上添加另一個屬性並在表單中添加另一個輸入時,我的屬性不再為空。

我希望這對其他人有幫助。

剃刀頁面 HTML:

@page
@model SomeModel

<form method="post" enctype="multipart/form-data">
    <div class="form-group">
        <div class="col-md-10">
            <p>Upload one or more files using this form:</p>
            <input asp-for="Input.SingleInput" type="file" class="form-control" />
            <input asp-for="Input.AnotherInput" class="form-control" />
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-10">
            <input type="submit" value="Upload" />
        </div>
    </div>
</form>

Razor 頁面代碼背后:

public class SomeModel: PageModel
    {
        [BindProperty]
        public SomeViewModel Input { get; set; }

        public async Task OnGetAsync()
        {

        }

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            // This won't be null.
            var showMeSomething = Input.SingleInput;

            return RedirectToPage();
        }
    }

一些視圖模型:

public class SomeViewModel
    {
        public IFormFile SingleInput{ get; set; }
        public string AnotherInput{ get; set; }
    }

我發現通過在我的 html 表單上提供名稱,我能夠映射到參數(ASP.NET Core 2.1):

客戶端:

<form method="post" enctype="multipart/form-data" action="...">
    <input type="file" name="myFile" required />
    <input type="password" name="myPass" required />
    <input type="submit" value="post" />
</form>

服務器端:

[HttpPost()]
public async Task<IActionResult> Post(IFormFile myFile, [FromForm]string myPass)
{
    //...
}

您的代碼看起來非常好,只要您使用您在問題上發布的相同版本的代碼,它就應該可以工作。 我有一種非常強烈的感覺,即您對ModelState.IsValid表達式變得false ,因此看到了某種意外行為。

FileExtensions數據注釋應該與String類型屬性一起使用,而不是與IFormFile類型屬性一起使用。 由於這個原因, IsValid返回 false。

所以從你的視圖模型中刪除它。

public class EmailForm
{
    [Display(Name = "Add a picture")]
    [DataType(DataType.Upload)]
    public IFormFile SubmitterPicture { get; set; }
}

這是來自團隊成員之一的相關 GH 問題和解釋,供您參考。

FileExtensions Data annotation 無效 ModelState #5117

同樣,如果有人在 .Net Core 2.1 中工作並使用asp-for為您的輸入元素綁定模型,則不要為該<input>元素提供 name 和 id 屬性。 理想情況下,在瀏覽器上呈現時的InputTagHelper會生成name and id屬性及其值。 如果您為 name 和 id wrt 模型類提供相同的值,那么一切正常。 否則,系統不知道它應該綁定到哪個模型屬性。 更好的方法是不在<input>上提供 id 和 name 下面是示例代碼。

<form id="uploadForm" enctype="multipart/form-data" name="uploadForm" asp-action="UploadExcel" method="post">

                <div class="form-group form-group-lg form-group-sm row ">
                    <div class="col-sm-12 col-md-10 col-lg-10 uploadDiv" style="display: flex !important">
                        <label asp-for="FileName" class="col-sm-12 col-md-10 col-lg-10" style="font-size: 15px; max-width: fit-content ">File Name :</label>
                        <input asp-for="FileName" class="form form-control fileName"
                               type="text"
                               placeholder="Enter your file name" />
<!--File upload control-->
                        <label asp-for="FileName" class="col-sm-12 col-md-10 col-lg-10" style="font-size: 15px; max-width: fit-content ">Attachment :</label>
                        <input asp-for="File" required class="form-control" type="file" placeholder="File Name" />
                    </div>
                </div>
                <div class=" form-group form-group-lg form-group-sm row">
                    <span asp-validation-for="FileName" class="text-danger"></span>
                </div>
                <div class=" form-group form-group-lg form-group-sm row">
                    <small>Please upload .xls or .xlxs or json or xml formatted files only</small>
                </div>
                <div class="form-group form-group-lg form-group-sm row">
                    <div class="col-sm-12 col-md-10 col-lg-10">
                        <input type="submit" class="btn btn-primary" name="submit" id="fileUploadButton" value="Upload" />
                        <input type="reset" class="btn btn-Gray" name="result" id="resetButton" value="Reset" />
                    </div>
                </div>
                <a asp-action="DownloadTemplate" asp-controller="Download" title="Click to download template">Import Batch Transactions Template</a>
            </form>

模型.cs

public class ExcelUploadViewModel
    {

        /// <summary>
        /// Gets or Sets the FileName
        /// </summary>
        [Required(ErrorMessage = "FileName is required")]
        public string FileName { get; set; }

        [Required(ErrorMessage = "File is required")]
        [DataType(DataType.Upload)]
        [FromForm(Name = "File")]
        public IFormFile File { get; set; }
}

提交后在此處輸入圖像描述

謝謝你。

我遇到了這個問題,解決方法是確保“input type="file"”的元素設置了 id 和 name。 然后,在控制器中,將 IFormFile 參數名稱設置為完全相同,大小寫也是如此。 G-幸運

將以下內容添加到我的控制器為我解決了這個問題。 這是因為我的文件很大。 根據需要調整限制。

 [RequestFormLimits(ValueLengthLimit = int.MaxValue, MultipartBodyLengthLimit = int.MaxValue)]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM