web-dev-qa-db-fra.com

le fichier de téléchargement mvc avec le modèle - le deuxième fichier publié avec paramètre est null

J'ai un modèle simple avec 1 propriété de chaîne que je rend sur une vue simple.

la vue ressemble à la suivante:

@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { encType="multipart/form-data" }))
{
    @Html.TextBoxFor(m => m.FirstName)
    <br /><br />

    <input type="file" name="fileUpload" /><br /><br />
    <input type="submit" value="submit me" name="submitme" id="submitme" />
}

Le contrôleur est ceci:

[HttpPost]
public ActionResult UploadFile(UploadFileModel model, HttpPostedFileBase file)
{
   // DO Stuff
   return View(model);
}

Maintenant, lorsque je soumets, le modèle est rempli mais le deuxième paramètre, HttpPostedFileBase, est null. Cependant, lorsque vous exécutez Request.Files, il semble indiquer qu'un fichier de la demande est en cours de publication . Comment puis-je obtenir le deuxième paramètre à lier? 

18
Ahmed ilyas

Pourquoi ne pas ajouter les fichiers téléchargés à votre modèle comme ceci:

public class UploadFileModel 
{
    public UploadFileModel()
    {
        Files = new List<HttpPostedFileBase>();
    }

    public List<HttpPostedFileBase> Files { get; set; }
    public string FirstName { get; set; }
    // Rest of model details
}

Puis changez votre vue pour ceci:

@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { encType="multipart/form-data" }))
{
    @Html.TextBoxFor(m => m.FirstName)
    <br /><br />

    @Html.TextBoxFor(m => m.Files, new { type = "file", name = "Files" })<br /><br />
    <input type="submit" value="submit me" name="submitme" id="submitme" />
}

Ensuite, vos fichiers seront affichés comme suit:

public ActionResult UploadFile(UploadFileModel model)
{
    var file = model.Files[0];
    return View(model);
}
32
hutchonoid

Changez votre nom file en fileUpload et enctype c'est du travail

@using (Html.BeginForm("UploadFile", "Home", FormMethod.Post, new { enctype="multipart/form-data" }))
{
    @Html.TextBoxFor(m => m.FirstName)
    <br /><br />

    <input type="file" name="fileUpload" /><br /><br />
    <input type="submit" value="submit me" name="submitme" id="submitme" />
}

[HttpPost]
public ActionResult UploadFile(UploadFileModel model, HttpPostedFileBase fileUpload)
{
   // DO Stuff
   return View(model);
}
6
Jaimin

Pour traiter une entrée de fichier unique, vous pouvez définir une propriété HttpPostedFileBase au sein de ViewModel

public class SomeModel() 
{ 
    public SomeModel() 
    {
    }

    public HttpPostedFileBase SomeFile { get; set; }
}

Et puis implémentez-le de la manière suivante:

Vue:

@model SomeModel

@using (Html.BeginForm(
    "Submit", 
    "Home", 
    FormMethod.Post, 
    new { enctype="multipart/form-data" }))
{
    @Html.TextBoxFor(m => m.SomeFile, new { type = "file" })
    <input type="submit" value="Upload" 
        name="UploadButton" id="UploadButton" />
}

Manette:

[HttpPost]
public ActionResult Submit(SomeModel model)
{
    // do something with model.SomeFile

    return View();
}

Si vous avez besoin de gérer plusieurs fichiers, vous pouvez soit:

  • créez plusieurs propriétés et implémentez-les séparément, tout comme celle ci-dessus;
  • remplacez la propriété public HttpPostedFileBase SomeFile par quelque chose comme public List<HttpPostedFileBase> SomeFiles, puis étendez plusieurs contrôles @Html.TextBoxFor(m => m.SomeFile, new { type = "file" }) pour les avoir tous dans cette liste.

Au cas où vous auriez besoin d’informations supplémentaires, consultez cet article de blog que j’ai écrit sur le sujet.

3
Darkseal

Sinon, si vous le souhaitez, supprimez l'annotation de validation [Required] pour votre fichier de votre modèle et recherchez le fichier dans votre action Controller, puis ajoutez une erreur si elle n'est pas trouvée:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ActionWithFileUpload(ViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        if (Request.Files.Count > 0)
        {
            var postedFile = Request.Files[0];
            if (postedFile != null && postedFile.ContentLength > 0)
            {
                string imagesPath = HttpContext.Server.MapPath("~/Content/Images"); // Or file save folder, etc.
                string extension = Path.GetExtension(postedFile.FileName);
                string newFileName = $"NewFile{extension}";
                string saveToPath = Path.Combine(imagesPath, newFileName);
                postedFile.SaveAs(saveToPath);
            }
        }
        else
        {
            ModelState.AddModelError(string.Empty, "File not selected.");
        }
    }

    return RedirectToAction("Index"); // Or return view, etc.
}
0
Tim Tyler