Проблемы с привязкой формы загрузки файла в ASP.NET Core - PullRequest
0 голосов
/ 20 февраля 2019

Я пытаюсь привязать форму моего представления для загрузки метода контроллера, используя тонны обучающих программ, например:

Так что, как я понимаю, если я создаю контроллер и просматриваю, все должно работать.Контроллер:

(асинхронизация здесь отключена, но в обоих случаях результат один и тот же)

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 для 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 запрашивают на вкладке Сеть (Dev Tools), он запускает .... POST-запрос addfile с URL-адресом https://localhost:44351/home/addfile. Но почему это происходит, я не могу найти.

UPD0.Добавлен и опробован атрибут метода [HttpPost].Нет результата

UPD1.Добавлен HTML из браузера и ссылки из файла csproj.

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Дополнение к моему предыдущему ответу:

Атрибут asp-action вашего элемента form ссылается на метод UploadFileAsync, которого нет в вашем контроллере, поскольку он на самом деле называется UploadFile(без асинхронности).Исправив это, вы должны сделать еще один шаг вперед.

0 голосов
/ 20 февраля 2019

Если вы не укажете, какие HTTP-глаголы действительны для действия, MVC будет сопоставлять его только с запросами GET.Поскольку вы делаете запрос POST в своей форме, он не может найти соответствующее действие (он ищет POST Home/UploadFile, но только находит GET Home/UploadFile).

Добавление атрибута HttpPost к вашему действию исправитit.

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

Небольшое примечание: я бы порекомендовал вам использовать HttpClientFactory вместо того, чтобы создавать HttpClient самостоятельно.Это более эффективно и намного чище, чем использование кода конфигурации клиента в ваших действиях.

...