Upload / exibição de imagens em MVC 4

83

Alguém conhece algum tutorial passo a passo sobre como fazer upload / exibir imagens de um banco de dados usando o Entity Framework? Eu verifiquei trechos de código, mas ainda não tenho certeza de como funciona. Não tenho nenhum código, porque além de escrever um formulário de upload, estou perdido. Qualquer (e quero dizer, qualquer) ajuda é muito apreciada.

Em uma nota lateral, por que nenhum livro cobre esse tópico? Eu tenho o Pro ASP.NET MVC 4 e o Professional MVC4, e eles não mencionam isso.

entendido
fonte
6
Se você seguir Pro ASP MVC 4o SportsStore Tutorialcobre isso começando empage 292
Komengem
você está certo. Eu nem percebi. Estava procurando um capítulo sobre isso. Obrigado
rogerthat
2
Eu sei que isso é para MVC 4, mas esta questão ainda aparecerá quando procurar MVC 5. - Eu encontrei um ótimo tutorial que cobre tanto Upload para um Banco de Dados quanto Upload para um servidor de arquivos em Mvc 5 usando EF 6 em MikesDotNetting mikesdotnetting. com / artigo / 259 /…
Vahx
O capítulo do livro cobre o upload de imagens para o banco de dados, onde a maioria das pessoas deseja salvar o caminho para o banco de dados e a imagem para uma pasta.
bata em

Respostas:

142

Dê uma olhada no seguinte

@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" /> 
}

seu controlador deve ter um método de ação que aceite 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");
    }

Atualização 1

Caso você queira fazer upload de arquivos usando jQuery com assincronia, tente este artigo .

o código para lidar com o lado do servidor (para upload múltiplo) é;

 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;
    }

este controle também retorna o nome da imagem (em um retorno de chamada de javascript) que pode ser usado para exibir a imagem no DOM.

ATUALIZAÇÃO 2

Como alternativa, você pode tentar Uploads de arquivos assíncronos no MVC 4 .

Idrees Khan
fonte
Uau. Obrigado. Vou testá-lo. Algum recurso, que você possa pensar, eu posso ler para aprofundar meu conhecimento sobre este assunto? Não consigo encontrar nada.
rogerthat
1
depois de fazer file.SaveAs(path)como posso excluir o arquivo desse caminho?
J86
Usar angularjs para enviar imagem de tipo de arquivo html para o servidor é mais fácil, stackoverflow.com/a/26409100/900284
Frank Myat Qui
@FrankMyatThu usando angular apenas para enviar imagens? isso não soa um pouco estranho?
Idrees Khan
1
@DotNetDreamer Eu verificaria o seu site o mais rápido possível, pois há erros detalhados de login, expondo algumas informações bastante importantes no momento ...
Gareth
46

Aqui está um breve tutorial:

Modelo:

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

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

Visão:

  1. Crio:

    @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. Índice (para exibição):

    @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. Controlador (Criar)

    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);
    }
    

Espero que isso ajude :)

Миле Милошески
fonte
Uau, muito obrigado por isso. E se eu quisesse restringir a imagem a jpeg?
Kala J
@KalaJ Se você quiser restringir as imagens carregadas a apenas jpg, você pode adicionar o atributo de aceitação (Html5 funciona apenas no Chrome e FF não no IE). Ou você pode verificar a extensão no controlador de filename.LastIndexOf(".")algo parecido. Espero que isso ajude
Jordy van Eijk
@JordyvanEijk, usei o atributo accept, porém ele só funciona no Chrome. Não funciona em FF ou IE. Eu preciso de alguma outra forma de validação.
Kala J
1
@KalaJ Majbe, você pode fazer algo com o arquivo API Html5 Se precisar de algum tutorial Aqui está
Jordy van Eijk
2
Os hackers seriam capazes de enviar arquivos maliciosos sem validação do lado do servidor.
arao6 de
-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
fonte
Então, como você exibiria "msg" como uma imagem para o img?
eaglei22
Você deve excluir esta resposta e obter seus pontos de Reputação de volta.
noobprogrammer