0

I am using ajax post in my project even the image and text parts comes as valid in the model the extra attachments comes null and in the error part, the number of errors equals the number of attachments I send to the backend and seems as object File ModelState.values[8]Value.AttemptedValue = [object File],[object File],[object File],[object File],[object File].... so on

my controller

[HttpPost]
    public ActionResult CreateTheIdea(OneIdeaModel model)
    {
        string imgResult = "";
        string attachmentResult = "OK";
        if (ModelState.IsValid)
        {

        }
    }

my view

function sendBasicIdeaInfo() {

    var totalFiles = document.getElementById("coverImage").files.length;
    var covImg = document.getElementById("coverImage").files[0];

    newForm.append("title", $("#title").val());
    newForm.append("coverImage", covImg);
    newForm.append("description", encodeURI($("#description").val()));
    newForm.append("whyThis", encodeURI($("#whyThis").val()));
    newForm.append("detail", encodeURI($("#detail").val()));
    newForm.append("ideaType", encodeURI(ideaType));
    newForm.append("contentId", encodeURI(contentId));
    newForm.append("status", encodeURI(recordType));
    var totalFiles = document.getElementById("uploadBtn").files.length;
    console.log(totalFiles);
    if (totalFiles > 0) {
        for (var i = 0; i < totalFiles; i++) {
            files[i] = document.getElementById("uploadBtn").files[i];
            //console.log(files["name"]);
        }
        newForm.append("attachment", files);
        newForm.append("contentType", "@ContentTypeEnum.IDEA.ToString()");
        //newForm.append("contentId", newIdeaId);
    }

    $.ajax({
        type: 'post',
        url: '/@activeLanguage/Idea/CreateTheIdea',
        data: newForm,
        dataType: 'json',
        contentType: false,
        processData: false,
        success: function (response) {
            if (Number.isInteger(parseInt(response))) {
                complete();
            }
            else
            {
                openVSnackBar("@Resources.errAnError", "error");
            }
        },
        error: function (error) {
            openVSnackBar("@Resources.errAnError", "error");
        }
    });
}

my model

public class OneIdeaModel
{

    //Idea text part
    public int id { get; set; }
    public string title { get; set; }
    public string description { get; set; }
    public string whyThis { get; set; }
    public string detail { get; set; }
    public string ideaType { get; set; }
    public string contentId { get; set; }
    public string status { get; set; }
    public int attachmentCount { get; set; }
    public string langCode { get; set; }
    public int userId { get; set; }

    //Idea attachment part
    public string contentType { get; set; }
    public virtual HttpPostedFileBase[] attachment { get; set; }
    public string fileType { get; set; }
    public string fileName { get; set; }

    //Idea image part
    public virtual HttpPostedFileBase thumbImage { get; set; }
    public virtual HttpPostedFileBase coverImage { get; set; }

    public bool isImageFormatValid(HttpPostedFileBase img)
    {
        List<string> types = new List<string>() { "jpeg", "jpg", "png" };
        if (types.Contains(img.FileName.Split('.')[img.FileName.Split('.').Length - 1].ToLower())) return true;
        else return false;
    }

    public bool isAttachmentFormatValid(HttpPostedFileBase attachment)
    {
        List<string> types = new List<string>() { "application/pdf", "text/plain", "application/vnd.ms-excel.sheet.binary.macroenabled.12", "application/vnd.ms-excel.addin.macroenabled.12", "application/vnd.ms-excel", "application/msword" };
        if (types.Contains(attachment.ContentType)) return true;
        else return false;
    }
}

As I told all values comes except the attachment. It comes null Idk why. If you can help I would appreciate that

payload

------WebKitFormBoundaryJBAmObnu25KFXIzw
Content-Disposition: form-data; name="title"

123
------WebKitFormBoundaryJBAmObnu25KFXIzw
Content-Disposition: form-data; name="coverImage";                     
filename="35205568_10156471428459494_5451669252295622656_n.jpg"
Content-Type: image/jpeg

------WebKitFormBoundaryJBAmObnu25KFXIzw
Content-Disposition: form-data; name="description"

123
------WebKitFormBoundaryJBAmObnu25KFXIzw
Content-Disposition: form-data; name="whyThis"

123
------WebKitFormBoundaryJBAmObnu25KFXIzw
Content-Disposition: form-data; name="detail"

123123123123
------WebKitFormBoundaryJBAmObnu25KFXIzw
Content-Disposition: form-data; name="ideaType"

Category
------WebKitFormBoundaryJBAmObnu25KFXIzw
Content-Disposition: form-data; name="contentId"

0
------WebKitFormBoundaryJBAmObnu25KFXIzw
Content-Disposition: form-data; name="status"

PUBLISHED
------WebKitFormBoundaryJBAmObnu25KFXIzw
Content-Disposition: form-data; name="attachment"

[object File],[object File],[object File]
------WebKitFormBoundaryJBAmObnu25KFXIzw
Content-Disposition: form-data; name="contentType"

IDEA
------WebKitFormBoundaryJBAmObnu25KFXIzw--
Eray
  • 7
  • 2
  • You need to append each individual file to the `FormData` (you cannot append an array) –  Jun 25 '18 at 11:28
  • but I don't know how many files will be uploaded @StephenMuecke what else do you suggest ? – Eray Jun 25 '18 at 11:39
  • You just add each individual file inside the `for` loop –  Jun 25 '18 at 11:41
  • @StephenMuecke how should my model catch those dynamic stated values at the backend that would be great if you have an answer – Eray Jun 25 '18 at 12:47
  • `for (var i = 0; i < totalFiles; i++) { newForm.append("attachment", document.getElementById("uploadBtn").files[i]);` (but there is too much other code in your question that makes no sense, and if you have generated you view correctly, then it would be just `var formdata = new FormData($('form').get(0));` to serialize everything (refer [How to append whole set of model to formdata and obtain it in MVC](https://stackoverflow.com/questions/29293637/how-to-append-whole-set-of-model-to-formdata-and-obtain-it-in-mvc/29293681#29293681)) –  Jun 25 '18 at 12:50

2 Answers2

1

Try this

if (totalFiles > 0) {
        newForm.append("numberOfAttachment", totalFiles);
        for (var i = 0; i < totalFiles; i++) {
            newForm.append("attachment[" + i + "]", document.getElementById("uploadBtn").files[i]);
        }
    }
alkanschtein
  • 305
  • 1
  • 13
0

Assuming you are trying to upload multiple files and trying to bind to 'attachment' property. This will be the javascript code for your case-

function sendBasicIdeaInfo() {
    if (window.FormData !== undefined) {
        var totalFiles = document.getElementById("coverImage").files.length;
        var covImg = document.getElementById("coverImage").files[0];

        // Create FormData object
        var newForm = new FormData();

        newForm.append("title", $("#title").val());
        newForm.append("coverImage", covImg);
        newForm.append("description", encodeURI($("#description").val()));
        newForm.append("whyThis", encodeURI($("#whyThis").val()));
        newForm.append("detail", encodeURI($("#detail").val()));
        newForm.append("ideaType", encodeURI(ideaType));
        newForm.append("contentId", encodeURI(contentId));
        newForm.append("status", encodeURI(recordType));
        var totalFiles = document.getElementById("uploadBtn").files.length;
        console.log(totalFiles);
        if (totalFiles > 0) {
            for (var i = 0; i < totalFiles; i++) {
                files[i] = document.getElementById("uploadBtn").files[i];
                newForm.append("attachment", files[i]);         
                //console.log(files["name"]);
            }
            //newForm.append("attachment", files);
            //newForm.append("contentType", "@ContentTypeEnum.IDEA.ToString()");
            //newForm.append("contentId", newIdeaId);
        }

        $.ajax({
            type: 'POST',
            url: '/@activeLanguage/Idea/CreateTheIdea',
            data: newForm,
            contentType: false, // Not to set any content header
            processData: false, // Not to process data
            success: function(response) {
                if (Number.isInteger(parseInt(response))) {
                    complete();
                } else {
                    openVSnackBar("@Resources.errAnError", "error");
                }
            },
            error: function(error) {
                openVSnackBar("@Resources.errAnError", "error");
            }
        });
    } else {
        alert("FormData is not supported.");
    }
}