Hochladen von MVC 3-Dateien und Modellbindung


91

Ich habe einen Formular-Upload, der funktioniert, aber ich möchte Modellinformationen für meine Datenbank übergeben, um die Datei natürlich unter einem anderen Namen zu speichern.

Hier ist meine Rasiermesseransicht:

@model CertispecWeb.Models.Container

@{
  ViewBag.Title = "AddDocuments";
}

<h2>AddDocuments</h2>

@Model.ContainerNo

@using (Html.BeginForm("Uploadfile", "Containers", FormMethod.Post, 
            new { enctype = "multipart/form-data" }))
{
    <input type='file' name='file' id='file' />
    <input type="submit" value="submit" />
}

Hier ist mein Controller:

[HttpPost]
public ActionResult Uploadfile(Container containers, HttpPostedFileBase file)
{
     if (file.ContentLength > 0)
     {
        var fileName = Path.GetFileName(file.FileName);
        var path = Path.Combine(Server.MapPath("~/App_Data/Uploads"),
                       containers.ContainerNo);
        file.SaveAs(path);
     }

     return RedirectToAction("Index");
}

Die Modellinformationen werden nicht an die Steuerung weitergegeben. Ich habe gelesen, dass ich das Modell möglicherweise aktualisieren muss. Wie würde ich das tun?


2
Siehe stackoverflow.com/questions/9411563/… für ein verwandtes Problem
LCJ

Antworten:


123

Ihr Formular enthält kein anderes Eingabe-Tag als die Datei, sodass Sie in Ihrer Controller-Aktion nicht erwarten können, dass Sie etwas anderes als die hochgeladene Datei erhalten (das ist alles, was an den Server gesendet wird). Eine Möglichkeit, dies zu erreichen, besteht darin, ein verstecktes Tag mit der ID des Modells einzuschließen, mit dem Sie es aus Ihrem Datenspeicher innerhalb der Controller-Aktion abrufen können, an die Sie senden (verwenden Sie diese Option, wenn der Benutzer das Modell nicht ändern soll, aber einfach eine Datei anhängen):

@using (Html.BeginForm("Uploadfile", "Containers", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.HiddenFor(x => x.Id)
    <input type="file" name="file" id="file" />
    <input type="submit" value="submit" />
}

und dann in Ihrer Controller-Aktion:

[HttpPost]
public ActionResult Uploadfile(int id, HttpPostedFileBase file)
{
    Containers containers = Repository.GetContainers(id);
    ...
}

Wenn Sie dem Benutzer jedoch erlauben möchten, dieses Modell zu ändern, müssen Sie die richtigen Eingabefelder für jedes Feld Ihres Modells einfügen, das an den Server gesendet werden soll:

@using (Html.BeginForm("Uploadfile", "Containers", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.TextBoxFor(x => x.Prop1)
    @Html.TextBoxFor(x => x.Prop2)
    @Html.TextBoxFor(x => x.Prop3)
    <input type="file" name="file" id="file" />
    <input type="submit" value="submit" />
}

Anschließend wird der Standardmodellordner dieses Modell aus der Anforderung rekonstruieren:

[HttpPost]
public ActionResult Uploadfile(Container containers, HttpPostedFileBase file)
{
    ...
}

1
Ich bekomme fileals nullund Request.Files.Countist auch 0, würde es einen Unterschied geben, wenn das ein formist AjaxFormund es auch gibt routeValues?
Bjan

8

Gelöst

Modell

public class Book
{
public string Title {get;set;}
public string Author {get;set;}
}

Regler

public class BookController : Controller
{
     [HttpPost]
     public ActionResult Create(Book model, IEnumerable<HttpPostedFileBase> fileUpload)
     {
         throw new NotImplementedException();
     }
}

Und ansehen

@using (Html.BeginForm("Create", "Book", FormMethod.Post, new { enctype = "multipart/form-data" }))
{      
     @Html.EditorFor(m => m)

     <input type="file" name="fileUpload[0]" /><br />      
     <input type="file" name="fileUpload[1]" /><br />      
     <input type="file" name="fileUpload[2]" /><br />      

     <input type="submit" name="Submit" id="SubmitMultiply" value="Upload" />
}

Beachten Sie, dass der Titel des Parameters aus der Controller-Aktion mit dem Namen der Eingabeelemente übereinstimmen muss IEnumerable<HttpPostedFileBase> fileUpload->name="fileUpload[0]"

fileUpload muss passen


2
Diese Lösung ist die einzige Lösung, die ich für mehrere Dateien gefunden habe. Vielen Dank, dass Sie Ihren Code geteilt haben.
Rojan Gh.

6

Wenn Sie nicht immer Bilder für Ihre Aktion veröffentlichen, können Sie Folgendes tun:

[HttpPost]
public ActionResult Uploadfile(Container container, HttpPostedFileBase file) 
{
    //do container stuff

    if (Request.Files != null)
    {
        foreach (string requestFile in Request.Files)
        {
            HttpPostedFileBase file = Request.Files[requestFile]; 
            if (file.ContentLength > 0)
            {
                string fileName = Path.GetFileName(file.FileName);
                string directory = Server.MapPath("~/App_Data/uploads/");
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }
                string path = Path.Combine(directory, fileName);
                file.SaveAs(path);
            }
        }
    }

} 

1

Für mehrere Dateien; Beachten Sie das neuere " multiple " Attribut für die Eingabe:

Bilden:

@using (Html.BeginForm("FileImport","Import",FormMethod.Post, new {enctype = "multipart/form-data"}))
{
    <label for="files">Filename:</label>
    <input type="file" name="files" multiple="true" id="files" />
    <input type="submit"  />
}

Regler:

[HttpPost]
public ActionResult FileImport(IEnumerable<HttpPostedFileBase> files)
{
    return View();
}

1

1. Laden Sie die Datei jquery.form.js von der folgenden URL herunter

http://plugins.jquery.com/form/

Schreiben Sie den folgenden Code in cshtml

@using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data", id = "frmTemplateUpload" }))
{
    <div id="uploadTemplate">

        <input type="text" value="Asif" id="txtname" name="txtName" />


        <div id="dvAddTemplate">
            Add Template
            <br />
            <input type="file" name="file" id="file" tabindex="2" />
            <br />
            <input type="submit" value="Submit" />
            <input type="button" id="btnAttachFileCancel" tabindex="3" value="Cancel" />
        </div>

        <div id="TemplateTree" style="overflow-x: auto;"></div>
    </div>

    <div id="progressBarDiv" style="display: none;">
        <img id="loading-image" src="~/Images/progress-loader.gif" />
    </div>

}


<script type="text/javascript">

    $(document).ready(function () {
        debugger;
        alert('sample');
        var status = $('#status');
        $('#frmTemplateUpload').ajaxForm({
            beforeSend: function () {
                if ($("#file").val() != "") {
                    //$("#uploadTemplate").hide();
                    $("#btnAction").hide();
                    $("#progressBarDiv").show();
                    //progress_run_id = setInterval(progress, 300);
                }
                status.empty();
            },
            success: function () {
                showTemplateManager();
            },
            complete: function (xhr) {
                if ($("#file").val() != "") {
                    var millisecondsToWait = 500;
                    setTimeout(function () {
                        //clearInterval(progress_run_id);
                        $("#uploadTemplate").show();
                        $("#btnAction").show();
                        $("#progressBarDiv").hide();
                    }, millisecondsToWait);
                }
                status.html(xhr.responseText);
            }
        });

    });


</script>

Aktionsmethode: -

 public ActionResult Index()
        {
            ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";

            return View();
        }

 public void Upload(HttpPostedFileBase file, string txtname )
        {

            try
            {
                string attachmentFilePath = file.FileName;
                string fileName = attachmentFilePath.Substring(attachmentFilePath.LastIndexOf("\\") + 1);

           }
            catch (Exception ex)
            {

            }
        }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.