0

I'm trying to allow file uploading on modal popup using bootstrap modal popup. But it always returns null for type = "file"

I've tried following solutions but no luck: File upload in MVC when used in bootstrap modal returns null

it always return null. If I run this directly as separate page then it works fine but only having problem with popup.

I tried to change the content type on ajax but then its giving me this error "required anti-forgery form field __requestverificationtoken is not present"

I've tested what does page post using development tools: enter image description here

here are my codes:

controller: [HttpPost] [ValidateAntiForgeryToken] public async Task Create([Bind(Include = "ID,FileName,Link,SourceType,Comments,SourceDate,DateCreated,DateModified,ProjectID")] ProjectSource projectSource, HttpPostedFileBase uploadFile) { if (ModelState.IsValid) { //upload method 1 var fileSavePath = ""; if (HttpContext.Request.Files.AllKeys.Any()) { // Get the uploaded image from the Files collection var httpPostedFile = HttpContext.Request.Files[0];

                if (httpPostedFile != null)
                {
                    // Validate the uploaded image(optional)

                    // Get the complete file path
                    fileSavePath = (HttpContext.Server.MapPath("~/xyz/") + httpPostedFile.FileName);

                    // Save the uploaded file to "UploadedFiles" folder
                    httpPostedFile.SaveAs(fileSavePath);
                }
            }

              //upload method 2
            if (uploadFile != null && uploadFile.ContentLength > 0)
            {
                try
                {
                    string path = Path.Combine(Server.MapPath("~/xyz/"),
                                               Path.GetFileName(uploadFile.FileName));
                    uploadFile.SaveAs(path);
                    ViewBag.Message = "File uploaded successfully";
                }
                catch (Exception ex)
                {
                    ViewBag.Message = "ERROR:" + ex.Message.ToString();
                }
            }
            else
            {
                ViewBag.Message = "You have not specified a file.";
            }


            db.ProjectSources.Add(projectSource);
            await db.SaveChangesAsync();


            return " File : " + ViewBag.Message + " == " + fileSavePath;

        }


        return " File : " + ViewBag.Message +" === "+sb.ToString();
    }

view:

@model CharterPortal.Models.ProjectSource

@{ Layout = "";

@Scripts.Render("~/Scripts/jquery-2.2.3.min.js")
@Scripts.Render("~/Scripts/moment.min.js")
@Scripts.Render("~/Scripts/bootstrap.min.js")
@Scripts.Render("~/Scripts/bootstrap-datetimepicker.min.js")
@Scripts.Render("~/Scripts/bootstrap.fd.js")

}

× Add new Source
@using (Html.BeginForm("Create", "ProjectSource", FormMethod.Post, new { enctype = "multipart/form-data" , @id="ajaxForm"}))
{

    @Html.AntiForgeryToken()

    <div class="modal-body">
        <div class="form-horizontal">
            @*@Html.ValidationSummary(true, "", new { @class = "text-danger" })*@

            <div class="form-group">
                @Html.Label("Source file", htmlAttributes: new { @class = "control-label col-md-3" })
                <div class="col-md-6">
                    @Html.EditorFor(model => model.FileName, new { htmlAttributes = new { @class = "form-control" } })

                    @*<input type="file" name="uploadFile" />*@
                    @Html.TextBox("uploadFile",null, new { @class = "form-control", type = "file" })

                    @*<a href="../ProjectSource/FileUpload" id="open_btn" class="btn btn-orange" target="_blank">Add file</a>*@
                    @Html.ValidationMessageFor(model => model.FileName, "", new { @class = "text-danger" })

                </div>
            </div>
            @*<div class="form-group">
                    <div class="col-md-10" id="files" style="padding-left:40px;">

                    </div>
                </div>*@
            <div class="form-group">
                @Html.LabelFor(model => model.Link, htmlAttributes: new { @class = "control-label col-md-3" })
                <div class="col-md-6">
                    @Html.EditorFor(model => model.Link, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Link, "", new { @class = "text-danger" })
                </div>
            </div>
            <div class="form-group">
                @Html.LabelFor(model => model.SourceType, htmlAttributes: new { @class = "control-label col-md-3" })
                <div class="col-md-6">
                    @Html.EditorFor(model => model.SourceType, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.SourceType, "", new { @class = "text-danger" })
                </div>
            </div>
            <div class="form-group">
                @Html.LabelFor(model => model.Comments, htmlAttributes: new { @class = "control-label col-md-3" })
                <div class="col-md-6" style="color:black;">
                    @Html.TextAreaFor(model => model.Comments, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(model => model.Comments, "", new { @class = "text-danger" })
                </div>
            </div>
            <div class="form-group">
                @Html.LabelFor(model => model.SourceDate, htmlAttributes: new { @class = "control-label col-md-3" })
                <div class="col-md-6" style="color:black;">
                    @Html.EditorFor(model => model.SourceDate, new { htmlAttributes = new { @class = "form-control datepicker datefield" } })
                    @Html.ValidationMessageFor(model => model.SourceDate, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>
    </div>
        <div class="modal-footer">
            <button class="btn btn-med btn-orange" data-dismiss="modal">Cancel</button>
            <input class="btn btn-med btn-orange" type="submit" name="submit" value="Add" />
        </div>
}

ajax: $('form', dialog).submit(function (event) { event.preventDefault();

        $.ajax({
            url: this.action,
            type: this.method,
            async: true,
            data: $(this).serialize(),
            contentType:this.enctype,
            success: function (result) {

                if (result) {
                alert(result)
                    //Refresh

                } else {
                   alert(result)
                }
            }
        });

        return false;
    });

I hope to get good working solution for this: thanks in advance for your time.

Thanks

Community
  • 1
  • 1
Akshay14
  • 31
  • 1
  • 4
  • Possible duplicate of [how to append whole set of model to formdata and obtain it in MVC](http://stackoverflow.com/questions/29293637/how-to-append-whole-set-of-model-to-formdata-and-obtain-it-in-mvc) –  May 10 '16 at 07:09
  • You nee to use `FormData` if you want to upload a file using ajax. –  May 10 '16 at 07:09
  • @StephenMuecke thanks a lot.... I was trying to use formdata but wasn't working because didn't put contentType = false and processData = false. But it's working now... thanks alot... – Akshay14 May 10 '16 at 07:14

1 Answers1

-1

Ive been using this block of code to solve this problem and ModelState.IsValid in partials for about a year. cheers.

$(function () {
window.addEventListener("submit", function (e) {
  var form = e.target;
  if (form.getAttribute("enctype") === "multipart/form-data") {
    if (form.dataset.ajax) {
      e.preventDefault();
      e.stopImmediatePropagation();
      var xhr = new XMLHttpRequest();
      xhr.open(form.method, form.action);
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
          if (form.dataset.ajaxUpdate) {
            var updateTarget = document.querySelector(form.dataset.ajaxUpdate);
            if (updateTarget) {
              updateTarget.innerHTML = xhr.responseText;
            }
          }
        }
      };
      xhr.send(new FormData(form));
    }
  }
}, true);

$('#modal').on('shown.bs.modal', function () {
  $.validator.unobtrusive.parse($(this));
});

$('#modal').on('hidden.bs.modal', function () {
  $('#spinner').remove();
});

$.ajaxSetup({ cache: false });

});
  • The bulk of this code is exactly the same as [this](http://stackoverflow.com/a/20913169/660921) and [this](http://stackoverflow.com/a/27545941/660921). – Martin Tournoij Aug 29 '16 at 23:48