ASP.NET Core文件上传表单绑定问题

时间:2019-02-20 15:27:54

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

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

据我所知,如果我创建一个控制器并进行查看,那么所有这些都应该可以工作。 控制器:

(此处禁用了异步功能,但在两种情况下结果都是相同的)

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,但是当我选择一个文件并按下Submit按钮时,什么也没发生。因此,我的控制器未收到对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查询将运行。...添加文件POST查询,URL为https://localhost:44351/home/addfile。但是为什么会发生,我找不到。

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

UPD1。从浏览器添加了html,并从csproj文件添加了引用。

2 个答案:

答案 0 :(得分:1)

如果您没有指定对动作有效的HTTP动词,则MVC仅将其与GET请求匹配。由于您是在表单中发出POST请求,因此它找不到匹配的操作(它正在寻找library(sf) library(dplyr) library(sp) set.seed(12) for (i in 1:10) { p1 <- c(400000, 401000) p2 <- c(5600000, 5601000) l1 <- as.data.frame( st_as_sf(SpatialLines(list(Lines(Line(cbind(p1, p2)), ID="a"))) %>% st_make_grid(n=100, what = "centers") %>% as("Spatial") ) l2 <- as.data.frame( st_as_sf(SpatialLines(list(Lines(Line(cbind(p1, p2)), ID="a"))) %>% st_make_grid(n=100, what = "centers") %>% as("Spatial") ) print(all.equal(l1, l2)) } # [1] TRUE # [1] TRUE # [1] TRUE # [1] TRUE # [1] TRUE # [1] TRUE # [1] TRUE # [1] TRUE # [1] TRUE # [1] TRUE ,而只是寻找POST Home/UploadFile)。

GET Home/UploadFile属性添加到您的操作即可对其进行修复。

HttpPost

一个小注释:我建议您使用HttpClientFactory而不是自己创建[HttpPost] public IActionResult UploadFile(IFormFile file) { ... } 。与将客户端配置代码包含在您的操作中相比,它效率更高,也更清洁。

答案 1 :(得分:1)

除了我以前的回答:

您的asp-action元素的form属性引用了UploadFileAsync方法,该方法在您的控制器中不存在,因为它实际上被称为UploadFile(无异步) 。解决此问题将使您更进一步。