c# - ASP.NET Core文件上传表单绑定(bind)问题

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

我尝试使用大量教程将 View 的表单绑定(bind)到 Controller 的上传方法,例如:

所以,据我了解,如果我创建一个 Controller 和 View ,一切都应该有效。 Controller :

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

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

    }
}

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

因此,我在 Controller 的 string msg = "i go There"; 中放置断点,然后转到网页 http://myhost:port/addfile 。因此, View AddFile 已呈现,但是当我选择文件并按下提交按钮时,没有任何反应。因此,我的 Controller 没有收到对 UploadFile 操作的调用的问题。我尝试了很多示例和教程,结果都是一样的——绑定(bind)不起作用。 我使用 ASP.NET Core 2.2


在浏览器(Chrome 72 for Win)中检查了 html 代码。我预计元素属性将被 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>

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

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

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

最佳答案

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

HttpPost 属性添加到您的操作中即可修复该问题。

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

一点说明:我建议您使用 HttpClientFactory而不是自己创建 HttpClient 。它比在操作中包含客户端配置代码更高效,也更简洁。

关于c# - ASP.NET Core文件上传表单绑定(bind)问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54789819/

相关文章:

c# - AES 计数器模式 C# 等效

c# - ASP.NET Core 身份验证 cookie 只收到一次

c# - 如何知道选中了哪个单选按钮?

c# - 操作而不是查询拦截器(WCF 数据服务)

c# - 无法跟踪实体类型 ''的实例

javascript - 如何使用 Google 应用脚本一次上传多个文件到 Google Drive?

ruby-on-rails - Carrierwave如何获取文件扩展名

python - 如何为使用 Django-CKEditor 上传的图像创建 uuid4 文件名?

c# - 500, 无效操作异常 : No route matches the supplied values

c# - 如何在 Moq 中设置它以给我 null 或对象?