web-dev-qa-db-fra.com

Comment télécharger des fichiers dans le noyau asp.net?

Comment télécharger des fichiers ou des images à l'aide d'Asp.net MVC 6 avec des données de modèle? Exemple, j'ai un formulaire comme celui-ci;

<form>
    <input type="file">
    <input type="text" placeholder="Image name...">
    <input type="text" placeholder="Image description...">
    <input type="submit" value="Submit">
</form>

J'ai lu de nombreux tutoriels sur la façon de télécharger, mais je ne vois rien télécharger avec certaines données comme le formulaire ci-dessus.

En outre, existe-t-il une bibliothèque de manipulation d'image pour le redimensionnement et le tatouage d'image identique à la classe de manipulation d'image Codeigniter? ( https://codeigniter.com/user_guide/libraries/image_lib.html

22
ryzskzkhie

Vous pouvez ajouter une nouvelle propriété de type IFormFile à votre modèle de vue

public class CreatePost
{
   public string ImageCaption { set;get; }
   public string ImageDescription { set;get; }
   public IFormFile MyImage { set; get; }
}

et dans votre méthode d'action GET, nous allons créer un objet de ce modèle de vue et l'envoyer à la vue.

public IActionResult Create()
{
   return View(new CreatePost());
}

Maintenant, dans votre vue Créer, qui est fortement typée dans notre modèle de vue, disposez d'une balise form dont l'attribut enctype est défini sur "multipart/form-data"

@model CreatePost
<form asp-action="Create" enctype="multipart/form-data">   

    <input asp-for="ImageCaption"/>
    <input asp-for="ImageDescription"/>
    <input asp-for="MyImage"/>

    <input type="submit"/>
</form>

Et votre action HttpPost pour gérer la publication du formulaire

[HttpPost]
public IActionResult Create(CreatePost model)
{
   var img = model.MyImage;
   var imgCaption = model.ImageCaption;

   //Getting file meta data
   var fileName = Path.GetFileName(model.MyImage.FileName);
   var contentType = model.MyImage.ContentType;

   // do something with the above data
   // to do : return something
}

Si vous souhaitez télécharger le fichier dans un répertoire de votre application, vous devez utiliser IHostingEnvironment pour obtenir le chemin racine Web. Voici un exemple de travail.

public class HomeController : Controller
{
    private readonly IHostingEnvironment hostingEnvironment;
    public HomeController(IHostingEnvironment environment)
    {
        hostingEnvironment = environment;
    }
    [HttpPost]
    public IActionResult Create(CreatePost model)
    {
        // do other validations on your model as needed
        if (model.MyImage != null)
        {
            var uniqueFileName = GetUniqueFileName(model.MyImage.FileName);
            var uploads = Path.Combine(hostingEnvironment.WebRootPath, "uploads");
            var filePath = Path.Combine(uploads,uniqueFileName);
            model.MyImage.CopyTo(new FileStream(filePath, FileMode.Create)); 

            //to do : Save uniqueFileName  to your db table   
        }
        // to do  : Return something
        return RedirectToAction("Index","Home");
    }
    private string GetUniqueFileName(string fileName)
    {
        fileName = Path.GetFileName(fileName);
        return  Path.GetFileNameWithoutExtension(fileName)
                  + "_" 
                  + Guid.NewGuid().ToString().Substring(0, 4) 
                  + Path.GetExtension(fileName);
    }
}

Cela enregistrera le fichier dans le dossier uploads dans le répertoire wwwwroot de votre application avec un nom de fichier aléatoire généré à l'aide de Guids (pour éviter d'écraser les fichiers portant le même nom)

Ici, nous utilisons une méthode GetUniqueName très simple qui ajoutera 4 caractères d'un guid à la fin du nom de fichier pour le rendre quelque peu unique. Vous pouvez mettre à jour la méthode pour la rendre plus sophistiquée selon vos besoins.

Devriez-vous stocker l'URL complète de l'image téléchargée dans la base de données?

Non. Ne stockez pas l'URL complète de l'image dans la base de données. Et si demain votre entreprise décide de changer le nom de votre entreprise/produit de www.thefacebook.com à www.facebook.com? Vous devez maintenant corriger toutes les URL du tableau!

Que devez-vous stocker?

Vous devez stocker le nom de fichier unique que vous avez généré ci-dessus ( la uniqueFileName varibale que nous avons utilisée ci-dessus ) pour stocker le nom de fichier. Lorsque vous souhaitez afficher à nouveau l'image, vous pouvez utiliser cette valeur (le nom de fichier) et créer l'URL de l'image.

Par exemple, vous pouvez le faire dans votre vue.

@{
    var imgFileName = "cats_46df.png";
}
<img src="~/uploads/@imgFileName"  alt="my img"/>

Je viens de coder en dur un nom d'image en variable imgFileName et de l'utiliser. Mais vous pouvez lire le nom du fichier stocké dans votre base de données et définir votre propriété de modèle de vue et l'utiliser. Quelque chose comme

<img src="~/uploads/@Model.FileName"  alt="my img"/>

Stockage de l'image dans un tablea

Si vous souhaitez enregistrer le fichier en tant que bytearray/varbinary dans votre base de données, vous pouvez convertir l'objet IFormFile en tableau d'octets comme celui-ci

private byte[] GetByteArrayFromImage(IFormFile file)
{
    using (var target = new MemoryStream())
    {
        file.CopyTo(target);
        return target.ToArray();
    }
}

Maintenant, dans votre méthode d'action de publication http, vous pouvez appeler cette méthode pour générer le tableau d'octets à partir de IFormFile et l'utiliser pour enregistrer dans votre table. l'exemple ci-dessous tente d'enregistrer un objet d'entité Post à l'aide du cadre d'entité.

[HttpPost]
public IActionResult Create(CreatePost model)
{
    //Create an object of your entity class and map property values
    var post=new Post() { ImageCaption = model.ImageCaption };

    if (model.MyImage != null)
    {
       post.Image =  GetByteArrayFromImage(model.MyImage);
    }
    _context.Posts.Add(post);
    _context.SaveChanges();
    return RedirectToAction("Index","Home");
}
58
Shyju
 <form class="col-xs-12" method="post" action="/News/AddNews" enctype="multipart/form-data">

     <div class="form-group">
        <input type="file" class="form-control" name="image" />
     </div>

     <div class="form-group">
        <button type="submit" class="btn btn-primary col-xs-12">Add</button>
     </div>
  </form>

Mon action est

        [HttpPost]
        public IActionResult AddNews(IFormFile image)
        {
            Tbl_News tbl_News = new Tbl_News();
            if (image!=null)
            {

                //Set Key Name
                string ImageName= Guid.NewGuid().ToString() + Path.GetExtension(image.FileName);

                //Get url To Save
                string SavePath = Path.Combine(Directory.GetCurrentDirectory(),"wwwroot/img",ImageName);

                using(var stream=new FileStream(SavePath, FileMode.Create))
                {
                    image.CopyTo(stream);
                }
            }
            return View();
        }
0
Diako Hasani