【问题标题】:ASP.NET Core file upload form binding problemsASP.NET Core 文件上传表单绑定问题
【发布时间】:2019-02-20 15:27:54
【问题描述】:

我尝试将视图的表单绑定到控制器的上传方法,使用大量教程,例如:

所以,据我所知,如果我创建一个控制器和视图,那么一切都应该工作。 控制器:

(此处禁用异步,但两种情况下结果相同)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

// For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace ExcelParser.Controllers
{
    public class HomeController : Controller
    {
        static HttpClient httpClient = new HttpClient();

        // GET: /<controller>/
        public IActionResult Index()
        {
            if (httpClient.BaseAddress == null)
            {
                httpClient.BaseAddress = new Uri("http://localhost:51313");
            }
            var response = httpClient.GetAsync("api/file").Result;
            ViewBag.Templates = response.Content.ReadAsAsync<IEnumerable<string>>().Result;

            return View();
        }

        public IActionResult AddFile()
        {
            return View();
        }

        /*[HttpPost]
        public async Task<IActionResult> UploadFile(IFormFile file)
        {
            Console.WriteLine("======UPLOAD======");
            Console.WriteLine(file.FileName);
            string msg = "i go there";
            return RedirectToAction("Index");
        }*/

        [HttpPost]
        public IActionResult UploadFile(IFormFile file)
        {
            Console.WriteLine("======UPLOAD======");
            Console.WriteLine(file.FileName);
            string msg = "i go there";
            return RedirectToAction("Index");
        }

    }
}

视图AddFile.cshtml:

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>AddFile</title>
</head>
<body>
    <form asp-controller="Home" asp-action="UploadFile" method="post"
          enctype="multipart/form-data">

        <input type="file" name="file" />
        <button type="submit">Upload File</button>
    </form>
</body>
</html>

所以,我在控制器的string msg = "i go there"; 中放置断点并转到网页http://myhost:port/addfile。因此,视图 AddFile 被呈现,但是当我选择一个文件并按下提交按钮时,什么也没有发生。因此,我的控制器没有收到 UploadFile 操作的调用的问题。我尝试了很多示例和教程,结果都是一样的——绑定不起作用。 我使用 ASP.NET Core 2.2


在浏览器中检查了 html 代码(Chrome 72 for Win)。我预计元素属性将被 Razor 转换。浏览器代码:

<html><head>
    <meta name="viewport" content="width=device-width">
    <title>AddFile</title>
</head>
<body>
    <form asp-controller="Home" asp-action="UploadFile" method="post" enctype="multipart/form-data">

        <input type="file" name="file">
        <button type="submit">Upload File</button>
    </form>


</body></html>

所以,看来 Razor 不起作用,并且异步方法 UploadFile 没有被触发。

[HttpPost]
        public async Task<IActionResult> UploadFile(IFormFile file)
        {
            Console.WriteLine("======UPLOAD======");
            Console.WriteLine(file.FileName);
            await Task.Run(() =>
            {
                Thread.Sleep(2000);
                Console.WriteLine("======ASYNC======");
            });
            string msg = "i go there";
            return RedirectToAction("Index");
        }

那么,也许我丢失了一些参考资料?这是我的 .cspjoj 文件:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <UserSecretsId>bf953a4d-5fe0-4538-aeb5-27f9b4437de6</UserSecretsId>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="EPPlus" Version="4.5.3.1" />
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.0" />
  </ItemGroup>

  <ItemGroup>
    <Folder Include="wwwroot\Upload\" />
  </ItemGroup>

  <ItemGroup>
    <None Include="wwwroot\Templates\test.xlsx" />
  </ItemGroup>

</Project>

当我按下提交按钮时,网络(开发工具)选项卡中的手表 REST 查询会运行.... addfile POST 查询,网址为 https://localhost:44351/home/addfile。但是为什么会发生,我找不到。

UPD0。添加并尝试了 [HttpPost] 方法属性。没有结果

UPD1。添加了来自浏览器的 html 和来自 csproj 文件的引用。

【问题讨论】:

  • 听起来你的标签助手可能没有运行。检查浏览器的开发者工具,看看asp-controllerasp-action 属性是否已转换为有效的action 属性。
  • @KirkLarkin 感谢您的想法。你能给我看一个有效的动作属性示例吗?
  • 就像/Home/UploadFile
  • @KirkLarkin 看来标签转换根本不起作用。
  • @KirkLarkin 最后,我找到了解决方案。你是对的,标签助手不起作用。我将@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 添加到我的cshtml 顶部,助手开始工作!我请你写一个答案

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


【解决方案1】:

如果你没有指定哪些 HTTP 动词对一个动作有效,MVC 将只匹配 GET 请求。由于您在表单中发出 POST 请求,因此它找不到匹配的操作(它正在寻找 POST Home/UploadFile,但只找到 GET Home/UploadFile)。

HttpPost 属性添加到您的操作将修复它。

[HttpPost]
public IActionResult UploadFile(IFormFile file)
{
     ...
}

附注:我建议您使用HttpClientFactory 而不是自己创建HttpClient。它比在您的操作中包含客户端配置代码更有效,也更清洁。

【讨论】:

  • 你好。谢谢,但我也尝试添加 [HttpPost] 属性,检查了异步和同步调用 - 仍然没有结果。也许,当我有工作应用程序时,我会考虑使用 HttpClientFactory。但现在我只需要这个简单的应用程序才能工作。
【解决方案2】:

补充我之前的回答:

form 元素的asp-action 属性引用了UploadFileAsync 方法,该方法在您的控制器中不存在,因为它实际上被称为UploadFile(没有异步)。解决这个问题应该会让你更进一步。

【讨论】:

  • 我取消注释异步方法(请参阅更新的问题),添加一些 2s 任务 - 仍然没有结果。
  • 我建议通过删除 Async 后缀来更正 cshtml 文件 中的操作名称。找不到您引用的操作,因为它不存在。您的问题与实际上是异步或同步的方法完全无关。
  • 谢谢。这也是问题,但不是主要的))
猜你喜欢
  • 2017-11-26
  • 1970-01-01
  • 1970-01-01
  • 2018-07-28
  • 1970-01-01
  • 2021-08-02
  • 2019-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多