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?
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);
}
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);
}
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:
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.
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.
}