IFormFile始终为null(ASP.NET Core with MVC / Razor)

时间:2017-09-26 23:02:23

标签: c# asp.net-mvc asp.net-core-mvc

我有一个ASP.NET Core MVC应用程序试图上传IFormFile。但是,IFormFile始终为null。我发现的其他解决方案都没有解决这个问题。我做错了什么?

模型

Line

控制器

Line

查看

StackPanel

7 个答案:

答案 0 :(得分:12)

<form method="post" enctype="multipart/form-data">
</form>
  

enctype =“ multipart / form-data”

多部分表单数据是关键。

答案 1 :(得分:3)

您也可以从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请求存在问题。

答案 2 :(得分:3)

在遇到相同问题几个小时后,我找到了解决方案。

问题:

在表单中提交单个输入。

结论:

基本上在你的html表单中,如果除了提交按钮之外只有一个输入,这将无法工作。我在viewModel上添加了另一个属性,并在表单中添加了另一个输入,我的属性不再为null。

我希望这有助于其他人。

Razor Page 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>

剃刀页码背后:

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();
        }
    }

<强> SomeViewModel:

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

答案 3 :(得分:0)

您的代码看起来非常好,只要您使用的是您在问题上发布的相同版本的代码,它就应该可以正常工作。我非常强烈地感觉到less表达式false,因此会看到某种意外行为。

ModelState.IsValid数据注释应该与FileExtensions类型属性一起使用,而不是与String类型属性一起使用。由于这个原因,IFormFile返回false。

请从您的视图模型中删除它。

IsValid

以下是团队成员之一的相关GH问题和解释,供您参考。

FileExtensions Data annotation invalid ModelState #5117

答案 4 :(得分:0)

我发现通过在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)
{
    //...
}

答案 5 :(得分:0)

类似地,如果在.Net Core 2.1中工作并且正在使用asp-for来为您的输入元素绑定模型,则不要为该<input>元素提供名称和id属性。理想情况下,浏览器上呈现的InputTagHelper会生成name and id属性及其值。如果为w.r.t Model类的name和id赋予相同的值,则一切正常。否则,系统不知道应绑定到哪个模型属性。 更好的方法是不要在<input>上提供ID和名称 下面是示例代码。

<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>

Model.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; }
}

提交后enter image description here

谢谢。

答案 6 :(得分:0)

我遇到了这个问题,解决方法是确保“input type="file"” 元素设置了 ID 和名称。然后,在控制器中,将 IFormFile 参数名称设置为完全相同,大小写相同。 G-运气