使用输入标签助手 "name" 并使输入值为空。 ASP.NET MVC (.NET 5)

Using input tag helper "name" and getting input value empty. ASP.NET MVC (.NET 5)

我有创建项目的简单表格

    <form asp-action="CreateItem" enctype="multipart/form-data">
            <div class="form-group">
                <label asp-for="@Model.ItemPhoto" class="control-label"></label>
                <input type="file" asp-for="@Model.ItemPhoto" name="Photo" class="form-control-file" />
                <span asp-validation-for="@Model.ItemPhoto" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="@Model.Name" class="control-label"></label>
                <input asp-for="@Model.Name" class="form-control" />
                <span asp-validation-for="@Model.Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="@Model.ItemType" class="control-label"></label>
                <select asp-for="@Model.ItemType" class="form-control">
                    @foreach (var itemType in Enum.GetValues(typeof(RandApp.Enums.ItemType)))
                    {
                        <option value="@itemType.ToString()">@itemType</option>
                    }
                </select>
                <span asp-validation-for="@Model.ItemType" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="@Model.MaterialType" class="control-label"></label>
                <select asp-for="@Model.MaterialType" class="form-control">
                    @foreach (var materialType in Enum.GetValues(typeof(RandApp.Enums.MaterialType)))
                    {
                        <option value="@materialType.ToString()">@materialType</option>
                    }
                </select>
                <span asp-validation-for="@Model.MaterialType" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="@Model.Color" class="control-label"></label>
                <select asp-for="@Model.Color" class="form-control">
                    @foreach (var color in Enum.GetValues(typeof(RandApp.Enums.ItemColor)))
                    {
                        <option value="@color.ToString()">@color</option>
                    }
                </select>
                <span asp-validation-for="@Model.Color" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="@Model.Size" class="control-label"></label>
                <select asp-for="@Model.Size" class="form-control">
                    @foreach (var size in Enum.GetValues(typeof(RandApp.Enums.ItemSize)))
                    {
                        <option value="@size.ToString()">@size</option>
                    }
                </select>
                <span asp-validation-for="@Model.Size" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="@Model.DesignedFor" class="control-label"></label>
                <select asp-for="@Model.DesignedFor" class="form-control">
                    @foreach (var desigendFor in Enum.GetValues(typeof(RandApp.Enums.DesignedFor)))
                    {
                        <option value="@desigendFor.ToString()">@desigendFor</option>
                    }
                </select>
                <span asp-validation-for="@Model.DesignedFor" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="@Model.Price" class="control-label"></label>
                <input asp-for="@Model.Price" class="form-control" />
                <span asp-validation-for="@Model.Price" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="@Model.Description" class="control-label"></label>
                <textarea asp-for="@Model.Description" class="form-control"></textarea>
                <span asp-validation-for="@Model.Description" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>

有它的控制器

public async Task<IActionResult> CreateItem(Item item, IFormFile Photo)
        {
            if (ModelState.IsValid)
            {
                var path = Path.Combine(_webHostEnvironment.WebRootPath, "assets", Photo.FileName);
                var stream = new FileStream(path, FileMode.Create);
                await Photo.CopyToAsync(stream);
                item.ItemPhoto = Photo.FileName;
                await _itemRepo.CreateAsync(item);
                ViewBag.Item = item;
                return RedirectToAction("ReadItems");
            }

            return View();
        }

我的目标是获取所选照片的​​路径并将其保存在名为“assets”的文件夹中(位于“wwwroot”文件夹中)。 问题是,当我填写字段并提交值时,我得到 item.ItemPhoto 值 null 并且我无法在 if 语句中输入。 (见下面的照片)。 [1]: https://i.stack.imgur.com/H2aLt.png

我找到的一个解决方案是从表单中删除“enctype=”multipart/form-data”并从输入中删除“name=”标签助手

<form asp-action="CreateItem" enctype="multipart/form-data">
            <div class="form-group">
                <label asp-for="@Model.ItemPhoto" class="control-label"></label>
                <input type="file" asp-for="@Model.ItemPhoto" name="Photo" class="form-control-file" />
                <span asp-validation-for="@Model.ItemPhoto" class="text-danger"></span>
            </div>

但在这种情况下我无法正确获取路径。 我该怎么做才能解决这个问题,为什么我从输入中得到空值?

文件和字符串类型无法通过相同的名称自动一起传递,并且无法通过仅使用一个输入来实现此要求。可以给ItemPhoto设置隐藏输入,用js设置文件变化时的值:

@model Item
<form asp-action="CreateItem" enctype="multipart/form-data">
            <div class="form-group">
                <label asp-for="@Model.ItemPhoto" class="control-label"></label>
                                    //change here...
                <input type="file" name="ItemPhoto" class="form-control-file" onchange="SetValue(this)"  />
                             //add hidden input......
                <input asp-for="@Model.ItemPhoto" hidden/>
                <span asp-validation-for="@Model.ItemPhoto" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="@Model.Name" class="control-label"></label>
                <input asp-for="@Model.Name" class="form-control" />
                <span asp-validation-for="@Model.Name" class="text-danger"></span>
            </div>
            <input type="submit" value="Create"/>
</form>
@section Scripts
{
    <script>
        function SetValue(input) {
            var fileName = input.files[0].name;
            //asp-for will generate the id and name
            //so you can get the selector by using $("#ItemPhoto")
            $("#ItemPhoto").val(fileName);          
        }
    </script>
}

后端(name 属性应始终与 parameter/property name 匹配):

public async Task<IActionResult> CreateItem(Item item, IFormFile ItemPhoto)
{
    //....
    return View();
}