Przesyłanie pliku Razor MVC 4

249

Jestem nowy w MVC 4 i próbuję wdrożyć kontrolę przesyłania plików w mojej witrynie. Nie mogę znaleźć błędu. Otrzymuję wartość zerową w moim pliku.

Kontroler:

public class UploadController : BaseController
    {
        public ActionResult UploadDocument()
        {
            return View();
        }

       [HttpPost]
       public ActionResult Upload(HttpPostedFileBase file)
       {
           if (file != null && file.ContentLength > 0)
           {
               var fileName = Path.GetFileName(file.FileName);
               var path = Path.Combine(Server.MapPath("~/Images/"), fileName);
               file.SaveAs(path);
           }

           return RedirectToAction("UploadDocument");
        }
    }

Widok:

@using (Html.BeginForm("Upload", "Upload", FormMethod.Post, new { enctype = "multipart/form-data" }))
{ 
    <input type="file" name="FileUpload" />
    <input type="submit" name="Submit" id="Submit" value="Upload" />
}
Liam
źródło
możliwy duplikat wczytywania pliku ASP.NET MVC 3.0
Liam
1
musisz tylko zmienić publiczne przesyłanie ActionResult (plik HttpPostedFileBase) <input type = "file" name = "FileUpload" />
Muhammad Asad
sprawdź moją implementację tutaj stackoverflow.com/a/40990080/4251431
Basheer AL-MOMANI
2
Opuszczenie enctypeformularza kosztowało mnie godzinę
Savage
Gdzie jest połączenie między metodą Upload () a przyciskiem. Czy powinno być zdarzenie onClick? Nowy na asp.net Jestem
pnizzle

Odpowiedzi:

333

Parametr Uploadmetody HttpPostedFileBasemusi mieć taką samą nazwę jak file input.

Więc po prostu zmień dane wejściowe na to:

<input type="file" name="file" />

Można również znaleźć pliki w Request.Files:

[HttpPost]
public ActionResult Upload()
{
     if (Request.Files.Count > 0)
     {
         var file = Request.Files[0];

         if (file != null && file.ContentLength > 0)
         {
            var fileName = Path.GetFileName(file.FileName);
            var path = Path.Combine(Server.MapPath("~/Images/"), fileName);
            file.SaveAs(path);
         }
     }

     return RedirectToAction("UploadDocument");
 }
Cristi Pufu
źródło
2
nie zrobi tego przez Index out of boundswyjątek, jeśli nie ma pliku w Request.Fileskolekcji ..?
shashwat
2
Właściwie to rzuci ArgumentOutOfRangeException, ale masz rację, zaktualizowałem
Cristi Pufu
2
Pamiętaj, że parametrami Html.BeginForm są nazwa akcji i nazwa kontrolera (bez postfiksu „kontroler”. Na przykład: Home zamiast HomeController). Inną ważną rzeczą jest nie umieszczanie tagu <form> w środku, ponieważ jest to BeginForm, który otwiera tag
pocjoc
5
Innymi słowy - nazwa właściwości modelu widoku musi być zgodna z nazwą typu danych wejściowych. Jeśli twoja viewmodelnazwa nieruchomości jest nazwana AgentPhoto, musisz mieć następujące informacje:<input type="file" name="AgentPhoto"/>
Dayan
var path = Path.Combine(Server.MapPath("~/Images/"), fileName);, nie znaleziono klasy „Serwer”, którego pakietu użyć?
Danilo Pádua,
65

Wyjaśniając to. Model:

public class ContactUsModel
{
    public string FirstName { get; set; }             
    public string LastName { get; set; }              
    public string Email { get; set; }                 
    public string Phone { get; set; }                 
    public HttpPostedFileBase attachment { get; set; }

Po akcji

public virtual ActionResult ContactUs(ContactUsModel Model)
{
 if (Model.attachment.HasFile())
 {
   //save the file

   //Send it as an attachment 
    Attachment messageAttachment = new Attachment(Model.attachment.InputStream,       Model.attachment.FileName);
  }
}

Wreszcie metoda Extension do sprawdzania pliku hasFile

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace AtlanticCMS.Web.Common
{
     public static class ExtensionMethods 
     {
         public static bool HasFile(this HttpPostedFileBase file)
         {
             return file != null && file.ContentLength > 0;
         }        
     }
 }
Bishoy Hanna
źródło
publiczny załącznik HttpPostedFileBase {get; zestaw; } / załącznik nie jest identyfikatorem
Codeone
Myślę, że Cola odnosi się do niezdefiniowanego typu załącznika.
Karson,
2
Widok może być używany zgodnie z opisem użytkownika2028367. Właściwie zapomniałem dołączyć nowy {enctype = "multipart / form-data"} w części Html.BeginForm, więc nie mogłem wyświetlić pliku w mojej akcji. Świetna odpowiedź. +1 za pokazywanie w klasie modelu i metodzie rozszerzenia.
Arjun,
@BishoyHanna Jak założyłem w formularzu załącznik. W przypadku innych wartości brzytwa zapewnia nam prostą składnię, ale jak to zrobić dla tego pliku?
Denis V
1
cześć, @ClintEastwood, ten post był do przesłania jednego pliku, szukałem w Internecie czegoś, co pasuje do wielu przesłanych plików (dla ciebie) i znalazłem ten, który moim zdaniem będzie działał. Ponownie, oparty na modelu, który nie korzysta z
pliku
17

Obejrzyj stronę

@using (Html.BeginForm("ActionmethodName", "ControllerName", FormMethod.Post, new { id = "formid" }))
 { 
   <input type="file" name="file" />
   <input type="submit" value="Upload" class="save" id="btnid" />
 }

plik skryptu

$(document).on("click", "#btnid", function (event) {
        event.preventDefault();
        var fileOptions = {
            success: res,
            dataType: "json"
        }
        $("#formid").ajaxSubmit(fileOptions);
    });

W kontrolerze

    [HttpPost]
    public ActionResult UploadFile(HttpPostedFileBase file)
    {

    }
Jagadisha BS
źródło
2
Zgadzam się z @Muflix, nie potrzebujesz AJAXtutaj. Html.BeginFormwykonuje już pracę. AJAX jest potrzebny tylko wtedy, gdy nie chcesz przekierowywać do<form action=LINK>
jAC
1
Ajax jest lepszy dla większych plików, ponieważ pozwala poprawić wrażenia użytkownika.
markthewizard1234
6

po prostu musisz zmienić nazwę wpisanego pliku, ponieważ taka sama nazwa jest wymagana w parametrze, a nazwa pola wejściowego wystarczy zastąpić ten wiersz Twój kod działa dobrze

 <input type="file" name="file" />
Muhammad Asad
źródło
2

Myślę, że lepszym sposobem jest użycie HttpPostedFileBase w kontrolerze lub interfejsie API. Następnie możesz łatwo wykryć rozmiar, typ itp.

Właściwości pliku można znaleźć tutaj:

MVC3 Jak sprawdzić, czy HttpPostedFileBase jest obrazem

Na przykład ImageApi:

[HttpPost]
[Route("api/image")]  
public ActionResult Index(HttpPostedFileBase file)  
{  
    if (file != null && file.ContentLength > 0)  
        try 
        {  
            string path = Path.Combine(Server.MapPath("~/Images"),  
               Path.GetFileName(file.FileName));

            file.SaveAs(path);  
            ViewBag.Message = "Your message for success";  
        }  
        catch (Exception ex)  
        {  
            ViewBag.Message = "ERROR:" + ex.Message.ToString();  
        }  
    else 
    {  
        ViewBag.Message = "Please select file";  
    }  
    return View();  
}

Mam nadzieję, że to pomoże.

Petr Tomášek
źródło
Lepsze niż co? OP już używa HttpPostedFileBase.
jpaugh