2016-08-01 25 views
2

ich diesen Code einreichen,Kann nicht Formulardaten und hochgeladene Datei in Controller binden

$('#form').on('submit',function (e) { 
    e.preventDefault(); 
    //var file = $("#productImg"); 
    var fileUpload = $("#productImg").get(0); 
    var files = fileUpload.files; 


    var form = $("#form"); 
    var formData = new FormData(); 
    formData.append("product", form.serialize()); 

    // Looping over all files and add it to FormData object 
    for (var i = 0; i < files.length; i++) { 
     formData.append(files[i].name, files[i]); 
    } 
    //formData.append("file", file); 

    $.ajax({ 
     type: 'POST', 
     url: baseUrl + 'Controller/Action', 
     data: formData, 
     processData: false, 
     contentType: false, 
     success: function (data) { 
     } 
    }); 
}); 

Dies ist mein Controller:

public JsonResult AddProduct(ProductModel product) // data is binded in the model if I remove content type property 
    { 
     var isSuccess = false; 

     if (product != null) 
     { 
      try 
      { 
       if (Request.Files.Count > 0) // works ok if I added the content type property 
       { 
        var sadas = "sad"; 
       } 

Was geschieht hier ich die serialized form Daten in Mvc Controller sendet zusammen mit der hochgeladenen Datei.

Das Problem hier ist, wenn ich diese Ajax-Eigenschaft contentType: false, hinzugefügt habe, kann ich die Dateien erfolgreich postback, aber das binded-Modell ist null.

Auf der anderen Seite, wenn ich diese Eigenschaft entfernen, funktioniert das binded-Modell OK. Aber das Problem ist, dass die Datei nicht auf dem Server gesendet wurde.

Wie kann ich das schaffen? Ich möchte, dass sowohl das Formular als auch die Bilder serverseitig gesendet werden.

UPDATE Dies funktioniert nun, die einzige Linie änderte ich ist diese

formData.append("product", form.serialize());

TO

var other_data = $('#addProductForm').serializeArray(); $.each(other_data, function (key, input) { formData.append(input.name, input.value); });

Kann mir jemand erklären, was passiert ist? Ich habe keine Ahnung

+1

Unter der Annahme, dass die Fil-Eingaben auch in Ihren Form-Tags sind, brauchen Sie nur 'var formData = new FormData ($ ("# form"). Get (0)); '- siehe [diese Antwort] (http: // stackoverflow.com/questions/29293637/how-to-append-whole-set-of-model-to-formdata-and-obtain-it-in-mvc/29293681#29293681) –

+0

@StephenMuecke danke! Dies kann meinen Code vereinfachen – Sherlock

Antwort

5

Leider die jQuery Methode wird keine Eingabe Dateielemente enthalten. Ihre Dateien werden also nicht in den serialisierten Wert aufgenommen.

Was Sie tun können, ist ein FormData Objekt erstellen, hängen Sie die Dateien an. Sie müssen die Formularfeldwerte auch an dasselbe FormData-Objekt anfügen. Sie können einfach das gesamte Eingabefeld durchlaufen und es hinzufügen.

Wenn Sie die Dateien hinzufügen, um Daten zu bilden, müssen Sie einen Namen angeben, der mit dem Parameter übereinstimmt, den Sie in Ihrer HttpPost-Aktionsmethode verwenden.

Dies sollte funktionieren.

var fileUpload = $("#productImg").get(0); 
var files = fileUpload.files; 

var formData = new FormData(); 

// Looping over all files and add it to FormData object 
for (var i = 0; i < files.length; i++) { 
    console.log('(files[i].name:' + files[i].name); 
    formData.append('productImg', files[i]); 
} 

// You can update the jquery selector to use a css class if you want 
$("input[type='text'").each(function (x, y) { 
    formData.append($(y).attr("name"), $(y).val()); 
}); 

$.ajax({ 
    type: 'POST', 
    url: 'ReplaceHereYourUrltotheActionMethod', 
    data: formData, 
    processData: false, 
    contentType: false, 
    success: function (data) { 
    } 
}); 

und Ihre Aktion-Methode können Sie einen anderen Parameter von IEnumerable<HttpPostedFileBase> Typ hinzufügen mit dem Namen gleiche wie das, was wir eingestellten Daten zu bilden, die productImg ist.

[HttpPost] 
public virtual ActionResult Index(ProductModel model, 
               IEnumerable<HttpPostedFileBase> productImg) 
{ 
    // to do :Look through productImg and do something 
} 
+0

Können Sie meine aktualisierte Frage erklären? Deine Antwort ist richtig, übrigens – Sherlock

0

Für ASP.NET-Core, können Sie dies tun, indem Sie mit Ihrem Modell starten:

public class FilesViewModel 
{ 
    public Guid? ParentObjectId { get; set; } // if you wish to associate these files with some parent record 
    public IEnumerable<IFormFile> Files { get; set; } 
} 

Ihr Controller:

[HttpPost] 
public JsonResult UploadFiles(FilesViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     // your code here 
     // see https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads 
    } 
} 

Ihre Ansicht (oder Ansicht Komponente):

@model YourProject.ViewModels.EventFilesViewModel 
<form method="post" enctype="multipart/form-data"> 
    <input type="hidden" asp-for="ParentObjectId" /> 
    <input type="file" asp-for="Files" multiple /> 
    <span asp-validation-for="Files" class="text-danger"></span> 
    <input type="button" id="btnEventFilesUpload" value="Upload Selected Files" class="btn btn-default" /> 
</form> 

Und schließlich die Javascript (wie von Shyjus Antwort geändert, um die ParentObjectId zu übergeben):

$(function() { 
    $("#btnEventFilesUpload").click(function (evt) { 
     var fileUpload = $("#Files").get(0); 
     var files = fileUpload.files; 
     var data = new FormData(); 
     for (var i = 0; i < files.length; i++) { 
      data.append('Files', files[i]); 
     } 
     // if you wish to associate these files with some parent record 
     data.append('ParentObjectId', $('#ParentObjectId').val()); 
     $.ajax({ 
      type: "POST", 
      url: "/Event/UploadFiles", 
      contentType: false, 
      processData: false, 
      data: data, 
      success: function (message) { 
       alert(message); 
      }, 
      error: function() { 
       alert("There was error uploading files!"); 
      } 
     }); 
    }); 
});