我尝试使用大量教程将 View 的表单绑定(bind)到 Controller 的上传方法,例如:
https://learn.microsoft.com/ru-ru/aspnet/core/mvc/models/file-uploads?view=aspnetcore-2.2
- https://www.c-sharpcorner.com/article/upload-download-files-in-asp-net-core-2-0/
所以,据我了解,如果我创建一个 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/