Как я могу загрузить файл в MVC 6 под vNext?

В MVC 5 я делал это:

var context = (HttpContextBase)Request.Properties["MS_HttpContext"];
var file = (HttpPostedFileBase)context.Request.Files[0];

Теперь они недоступны в MVC 6 под vNext. Как я могу получить файл(ы) из запроса?


person Adam Szabo    schedule 18.10.2014    source источник


Ответы (4)


FileUpload еще не реализован в MVC6, см. эту проблему и связанные с ней проблемы, такие как < href="https://github.com/aspnet/HttpAbstractions/issues/139" rel="nofollow">этот для статуса.

Вы можете опубликовать XMLHttpRequest из JavaScript и перехватить его с помощью чего-то вроде этот код:

public async Task<IActionResult> UploadFile()
{
    Stream bodyStream = Context.Request.Body;

    using(FileStream fileStream = File.Create(string.Format(@"C:\{0}", fileName)))
    {

        await bodyStream.CopyToAsync(fileStream);

    }

  return new HttpStatusCodeResult(200);
}

Изменить: если вы видите связанные проблемы, они теперь закрыты. Теперь вы можете использовать более обычный способ загрузки файлов в MVC6.

person AndersNS    schedule 18.10.2014
comment
Спасибо! Стоит упомянуть, что, поскольку это захватывает тело запроса как есть, оно работает только с нефрагментированными загрузчиками файлов (например, Valums), но не работает с более новыми, которые загружают в фрагментированном формате (например, Flow) - person Adam Szabo; 19.10.2014

Ответ ниже касается версии beta6.

Сейчас он в рамках. С некоторыми оговорками, чтобы получить имя загруженного файла, вам нужно проанализировать заголовки. И вам нужно внедрить IHostingEnvironment в свой контроллер, чтобы добраться до папки wwwroot, потому что Server.MapPath() больше нет.

Возьмите это в качестве примера:

public class SomeController : Controller
{

    private readonly IHostingEnvironment _environment;

    public SomeController(IHostingEnvironment environment)
    {       
        _environment = environment;
    }

    [HttpPost]
    public ActionResult UploadFile(IFormFile file)//, int Id, string Title)
    {

        if (file.Length > 0)
        {
            var targetDirectory = Path.Combine(_environment.WebRootPath, string.Format("Content\\Uploaded\\"));
            var fileName = GetFileName(file);
            var savePath = Path.Combine(targetDirectory, fileName);

            file.SaveAs(savePath);
            return Json(new { Status = "Ok" });
        }
        return Json(new { Status = "Error" });
    }

    private static string GetFileName(IFormFile file) => file.ContentDisposition.Split(';')
                                                                .Select(x => x.Trim())
                                                                .Where(x => x.StartsWith("filename="))
                                                                .Select(x => x.Substring(9).Trim('"'))
                                                                .First();

}
person Alexander Taran    schedule 17.08.2015
comment
Я не могу заставить это работать - IFormFile всегда равен нулю. Всегда получайте этот журнал: Выполнение метода действия ‹мой контроллер› с аргументами () - ModelSate действителен' - person RichardM; 01.12.2015
comment
Это не будет работать, если вы не установите enctype=multipart/form-data в теге формы! - person EvAlex; 06.01.2016
comment
Спасибо @EvAlex, это наставило меня на правильный путь. Магия Postman и vNext заключается в том, что имя ключа для вашего файла точно соответствует имени аргумента IFormFile в вашем методе POST. - person RichardM; 08.02.2016
comment
Это работает хорошо, но мне нужно также получить одно или несколько текстовых значений (<input type="text">) вместе с файлом. Предположим, у меня есть страница обновления профиля, которая включает в себя одно изображение профиля и три-четыре обычных текстовых поля. Как бы вы разобрали такой запрос на стороне сервера? Я действительно сталкиваюсь с этой проблемой уже давно и не могу найти решение до сих пор. stackoverflow.com/q/40629947/1306394 - person shashwat; 17.11.2016
comment
Что если вы опубликуете с [HttpPost] public JsonResult Upload(), например, с загрузкой blueimp jquery? - person JoshYates1980; 29.01.2017

Реализован биндер для загрузки файлов. См. коммит:

https://github.com/aspnet/Mvc/commit/437eb93bdec0d9238d672711ebd7bd3097b6537d#diff-be9198f9b55d07e00edc73349c34536aR118

person Boglen    schedule 16.01.2015

Самый простой способ загрузить файл в ASP.NET Core 1.0 (MVC 6)
представление (cshtml):

<form method="post" asp-action="Upload" asp-controller="Home" enctype="multipart/form-data">
    <input type="file" name="file" />
    <input type="submit" value="upload"/>
</form>

контроллер (CS):

[HttpPost]
public IActionResult Upload(IFormFile file)
{
    if (file == null || file.Length == 0)
        throw new Exception("file should not be null");

    // RC1
    // var originalFileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');    
    // file.SaveAs("your_file_full_address");

   // RC2
   using (var fileStream = new FileStream("path_address", FileMode.Create))
   {
       await file.CopyTo(fileStream);
   }
}
person Soren    schedule 19.06.2016
comment
Позволяет ли это загружать файл частями? - person Rob McCabe; 10.11.2017