IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ASP.NET MVC Discussion :

MVC5 input file avec razor, le binding ne fonctionne pas correctement


Sujet :

ASP.NET MVC

  1. #1
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2010
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 76
    Points : 127
    Points
    127
    Par défaut MVC5 input file avec razor, le binding ne fonctionne pas correctement
    Bonjour à tous,

    J'ai un modèle nommé Posts avec un champ Photo dans lequel je sauvegarde le chemin où la photo est uploadé.
    J'ai un contrôleur avec une action Create et une action Edit, par chacune de ces actions j'ai une vue qui, respectivement, affiche un formulaire pour créer un Posts et un formulaire pour modifier un Posts. Ce formulaire contient un input de type file pour uploader la photo.

    Mon problème est le suivant, j'arrive à uploader ma Photo lorsque que je crée un Post, le chemin de la photo est correctement enregistrer dans ma base. Par contre quand je modifie le Post précédemment créé et que je sauvegarde sans modifier la photo, le chemin renvoyé est null et du coup je perd le chemin vers ma photo. Pourtant, dans le html généré, le champ value de mon input file contient bien le chemin de la photo.

    Voici mon model :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [DataType(DataType.Upload)]
            public string Photo { get; set; }
    Voici mon input dans mon formulaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <div class="form-group">
                @Html.LabelFor(model => model.Photo, htmlAttributes: new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(model => model.Photo, new { htmlAttributes = new { @class = "form-control", type = "file" }})
                    @Html.ValidationMessageFor(model => model.Photo, "", new { @class = "text-danger" })
            </div>
    Voici le html génénré :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <input class="form-control text-box single-line" id="Photo" name="Photo" type="file" value="E:\Dev\DecoBlog\Blog\Images\20140201_115225.jpg">
    et voici mon action dans mon controleur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
            [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Edit(Posts posts)
            {
                if (ModelState.IsValid)
                {
                    if (Request.Files != null && Request.Files.Count != 0)
                    {
                        if (!String.IsNullOrEmpty(Request.Files[0].FileName))
                        {
                            var path = Path.Combine(Server.MapPath("~/Images/"), Request.Files[0].FileName);
                            posts.Photo = path;
                            Request.Files[0].SaveAs(path);
                        }
                    }
                    db.Entry(posts).State = EntityState.Modified;
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
                ViewBag.CategorieId = new SelectList(db.Categories, "Id", "Name", posts.CategorieId);
                return View(posts);
            }
    Je ne comprend pas pourquoi l'attribut value n'est pas pris en compte, avez-vous une idée ?

    Merci d'avance

  2. #2
    Rédacteur/Modérateur
    Avatar de Skalp
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2006
    Messages
    1 694
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 694
    Points : 2 927
    Points
    2 927
    Par défaut
    Pour des raisons de sécurité, il n'est pas possible d'attribuer une valeur à champ input de type file par programmation.

    Imagine une page du genre :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <form name="formulaire" method="post" enctype="multipart/form-data">
        <input type="file" value="C:/MesMotDePasses.txt">
    </form>
    <script>document.formulaire.submit();</script>
    Cela signifie qu'au moment même où tu affiches cette page, le formulaire est immédiatement validé et le fichier (s'il existe bien sûr) est uploadé sur le serveur.

    Apparemment, ASP.NET MVC génère "naïvement" ce code, mais il est rassurant que le navigateur ne le prenne pas en compte.

    Tu dois donc gérer le cas particulier où input est null.

    Ceci dit, fais très attention à ce que tu fais : tu enregistres en base un chemin que tu as généré côté serveur :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var path = Path.Combine(Server.MapPath("~/Images/"), Request.Files[0].FileName);
    posts.Photo = path;
    Jusque là tout va bien, mais après la sauvegarde, tu réaffiches ce chemin à l'utilisateur. Ce qui a deux conséquences plutôt graves :
    1. Un chemin serveur est affiché au client
    2. Le chemin serveur n'est pas le même que le chemin client, donc la photo ne sera pas retrouvée (m'enfin, la valeur n'est pas prise en compte, donc peu importe, en fait)
    J'imagine que pendant que tu développes, le serveur et le client sont la même machine, donc tu ne vois pas de problème pour le moment, mais il faut bien faire la distinction entre le serveur et le client quand on fait du dév web.

  3. #3
    Membre habitué
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2010
    Messages
    76
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 76
    Points : 127
    Points
    127
    Par défaut
    Merci pour ta réponse.

    Effectivement je n'avais pas pensé à cela.
    Je vais chercher.

    Je mettrais à jour l'article quand j'aurai trouvé une solution.

Discussions similaires

  1. Réponses: 3
    Dernier message: 02/06/2014, 13h55
  2. [TinyMCE] input file avec tinymce ?
    Par forst dans le forum Bibliothèques & Frameworks
    Réponses: 0
    Dernier message: 05/09/2013, 21h26
  3. [AJAX] input file avec AJAX
    Par ju0123456789 dans le forum AJAX
    Réponses: 15
    Dernier message: 07/09/2010, 12h32
  4. gérer input file avec fonction javascript
    Par frboyer dans le forum Général JavaScript
    Réponses: 13
    Dernier message: 16/04/2009, 16h17
  5. Réponses: 6
    Dernier message: 04/09/2007, 00h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo