Przesyłanie / wyświetlanie obrazów w MVC 4

84

Czy ktoś zna jakieś samouczki krok po kroku dotyczące przesyłania / wyświetlania obrazów z bazy danych przy użyciu Entity Framework? Sprawdziłem fragmenty kodu, ale nadal nie wiem, jak to działa. Nie mam kodu, bo poza napisaniem formularza wczytywania jestem zgubiony. Każda (i mam na myśli każdą) pomoc jest bardzo ceniona.

Na marginesie, dlaczego żadne książki nie obejmują tego tematu? Mam zarówno Pro ASP.NET MVC 4, jak i Professional MVC4 i nie wspominają o tym.

przyjąłem
źródło
6
Jeśli zastosujesz się Pro ASP MVC 4do SportsStore Tutorialtego, page 292
zacznij
masz rację. Nawet nie zauważyłem. Szukałem rozdziału na ten temat. Dzięki
rogerthat
2
Wiem, że dotyczy to MVC 4, ale to pytanie nadal będzie się pojawiać podczas wyszukiwania MVC 5. - Znalazłem świetny samouczek, który obejmuje zarówno przesyłanie do bazy danych, jak i przesyłanie na serwer plików w MVC 5 przy użyciu EF 6 w MikesDotNetting mikesdotnetting. com / article / 259 /…
Vahx
Rozdział w książce dotyczy przesyłania obrazów do bazy danych, w której większość ludzi chce zapisać ścieżkę do bazy danych i obraz do folderu.
trzepaczka

Odpowiedzi:

144

Spójrz na poniższe

@using (Html.BeginForm("FileUpload", "Home", FormMethod.Post, 
                            new { enctype = "multipart/form-data" }))
{  
    <label for="file">Upload Image:</label> 
    <input type="file" name="file" id="file" style="width: 100%;" /> 
    <input type="submit" value="Upload" class="submit" /> 
}

Twój kontroler powinien mieć metodę akcji, która zaakceptowałaby HttpPostedFileBase;

 public ActionResult FileUpload(HttpPostedFileBase file)
    {
        if (file != null)
        {
            string pic = System.IO.Path.GetFileName(file.FileName);
            string path = System.IO.Path.Combine(
                                   Server.MapPath("~/images/profile"), pic); 
            // file is uploaded
            file.SaveAs(path);

            // save the image path path to the database or you can send image 
            // directly to database
            // in-case if you want to store byte[] ie. for DB
            using (MemoryStream ms = new MemoryStream()) 
            {
                 file.InputStream.CopyTo(ms);
                 byte[] array = ms.GetBuffer();
            }

        }
        // after successfully uploading redirect the user
        return RedirectToAction("actionname", "controller name");
    }

Zaktualizuj 1

Jeśli chcesz przesyłać pliki za pomocą jQuery asynchronicznie, wypróbuj ten artykuł .

kod do obsługi po stronie serwera (do wielokrotnego przesyłania) to;

 try
    {
        HttpFileCollection hfc = HttpContext.Current.Request.Files;
        string path = "/content/files/contact/";

        for (int i = 0; i < hfc.Count; i++)
        {
            HttpPostedFile hpf = hfc[i];
            if (hpf.ContentLength > 0)
            {
                string fileName = "";
                if (Request.Browser.Browser == "IE")
                {
                    fileName = Path.GetFileName(hpf.FileName);
                }
                else
                {
                    fileName = hpf.FileName;
                }
                string fullPathWithFileName = path + fileName;
                hpf.SaveAs(Server.MapPath(fullPathWithFileName));
            }
        }

    }
    catch (Exception ex)
    {
        throw ex;
    }

ta kontrolka zwraca również nazwę obrazu (w wywołaniu zwrotnym javascript), którego następnie możesz użyć do wyświetlenia obrazu w DOM.

AKTUALIZACJA 2

Alternatywnie możesz wypróbować Async File Upload w MVC 4 .

Idrees Khan
źródło
łał. Dzięki. Wypróbuję to. Jakieś zasoby, o których myślisz, mogę przeczytać, aby pogłębić swoją wiedzę na ten temat? Nie mogę nic znaleźć.
rogerthat
1
po wykonaniu tej czynności, w file.SaveAs(path)jaki sposób mogę usunąć plik z tej ścieżki?
J86,
Używanie angularjs do wysyłania obrazu typu pliku html na serwer jest łatwiejsze, stackoverflow.com/a/26409100/900284
Frank Myat Thu
@FrankMyatThu używa angulara tylko do przesyłania zdjęć? czy to nie brzmi trochę dziwnie?
Idrees Khan
1
@DotNetDreamer Sprawdziłbym twoją stronę jak najszybciej, ponieważ jest tam szczegółowy błąd podczas logowania, ujawniający w tej chwili dość ważne informacje ...
Gareth
46

Oto krótki samouczek:

Model:

namespace ImageUploadApp.Models
{
    using System;
    using System.Collections.Generic;

    public partial class Image
    {
        public int ID { get; set; }
        public string ImagePath { get; set; }
    }
}

Widok:

  1. Stwórz:

    @model ImageUploadApp.Models.Image
    @{
        ViewBag.Title = "Create";
    }
    <h2>Create</h2>
    @using (Html.BeginForm("Create", "Image", null, FormMethod.Post, 
                                  new { enctype = "multipart/form-data" })) {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)
        <fieldset>
            <legend>Image</legend>
            <div class="editor-label">
                @Html.LabelFor(model => model.ImagePath)
            </div>
            <div class="editor-field">
                <input id="ImagePath" title="Upload a product image" 
                                      type="file" name="file" />
            </div>
            <p><input type="submit" value="Create" /></p>
        </fieldset>
    }
    <div>
        @Html.ActionLink("Back to List", "Index")
    </div>
    @section Scripts {
        @Scripts.Render("~/bundles/jqueryval")
    }
    
  2. Indeks (do wyświetlania):

    @model IEnumerable<ImageUploadApp.Models.Image>
    
    @{
        ViewBag.Title = "Index";
    }
    
    <h2>Index</h2>
    
    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
    <table>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.ImagePath)
            </th>
        </tr>
    
    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.ImagePath)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
                @Html.ActionLink("Details", "Details", new { id=item.ID }) |
                @Ajax.ActionLink("Delete", "Delete", new {id = item.ID} })
            </td>
        </tr>
    }
    
    </table>
    
  3. Kontroler (Utwórz)

    public ActionResult Create(Image img, HttpPostedFileBase file)
    {
        if (ModelState.IsValid)
        {
            if (file != null)
            {
                file.SaveAs(HttpContext.Server.MapPath("~/Images/") 
                                                      + file.FileName);
                img.ImagePath = file.FileName;
            }  
            db.Image.Add(img);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(img);
    }
    

Mam nadzieję, że to pomoże :)

Миле Милошески
źródło
Wow, bardzo za to dziękuję. A co jeśli chciałbym ograniczyć obraz do jpeg?
Kala J
@KalaJ Jeśli chcesz ograniczyć przesyłane obrazy tylko do jpg, możesz dodać atrybut accept (Html5 działa tylko w Chrome, a FF nie IE). Lub możesz sprawdzić rozszerzenie w kontrolerze filename.LastIndexOf(".")coś takiego. Mam nadzieję, że to pomoże
Jordy van Eijk
@JordyvanEijk, użyłem atrybutu accept, ale działa tylko w Chrome. Nie działa w FF ani IE. Potrzebuję innej formy walidacji.
Kala J
1
@KalaJ Majbe, możesz coś zrobić za pomocą interfejsu API plików Html5 Jeśli potrzebujesz samouczka. Oto on
Jordy van Eijk
2
Hakerzy mogliby przesyłać złośliwe pliki bez weryfikacji po stronie serwera.
arao6
-16
        <input type="file" id="picfile" name="picf" />
       <input type="text" id="txtName" style="width: 144px;" />
 $("#btncatsave").click(function () {
var Name = $("#txtName").val();
var formData = new FormData();
var totalFiles = document.getElementById("picfile").files.length;

                    var file = document.getElementById("picfile").files[0];
                    formData.append("FileUpload", file);
                    formData.append("Name", Name);

$.ajax({
                    type: "POST",
                    url: '/Category_Subcategory/Save_Category',
                    data: formData,
                    dataType: 'json',
                    contentType: false,
                    processData: false,
                    success: function (msg) {

                                 alert(msg);

                    },
                    error: function (error) {
                        alert("errror");
                    }
                });

});

 [HttpPost]
    public ActionResult Save_Category()
    {
      string Name=Request.Form[1]; 
      if (Request.Files.Count > 0)
        {
            HttpPostedFileBase file = Request.Files[0];
         }


    }
user3789888
źródło
Jak więc wyświetlić „msg” jako obraz do img?
eaglei
Powinieneś usunąć tę odpowiedź i odzyskać punkty reputacji.
noobprogrammer