Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
577 views
in Technique[技术] by (71.8m points)

asp.net mvc - File upload in MVC when used in bootstrap modal returns null

I'm trying to upload images to my application but it always returns null. I'm unable to find the issue here. Can you help me out? Here's my code.

Model


[Table("Slider")]
public partial class Slider : BaseModel
{
    [Required]
    [StringLength(200)]
    public string FileName { get; set; }

    [StringLength(200)]
    public string Title { get; set; }

    [StringLength(1000)]
    public string Description { get; set; }

    public int? Order { get; set; }
}


[NotMapped]
public class SliderImage : Slider
{
    public HttpPostedFileBase ImageFile { get; set; }
}

View


@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.AntiForgeryToken()
<div class="modal-body">
    <div class="form-horizontal">
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.Id)

        <div class="form-group">
            @Html.LabelFor(model => model.FileName, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.TextBoxFor(model => model.FileName, new { @class = "form-control", @readonly = "readonly" })
                @Html.ValidationMessageFor(model => model.FileName, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.ImageFile, new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.TextBoxFor(m => m.ImageFile, new { @class = "form-control", type = "file" })
               //This is Same as below
               //<input class="form-control" id="ImageFile" name="ImageFile" type="file" value="">
            </div>
        </div>

Controller


    public ActionResult Edit(int id)
    {
        Slider slider = _db.Sliders.Find(id);
        if (slider == null)
        {
            return HttpNotFound();
        }
        Mapper.CreateMap<Slider, SliderImage>();
        SliderImage sliderImage = Mapper.Map<Slider, SliderImage>(slider);
        return PartialView("_Edit", sliderImage);
    }


    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult EditSlider([Bind(Include = "Id,FileName,Title,Description,Order,IsActive,Name,ImageFile")] SliderImage sliderImage)
    {
        if (ModelState.IsValid)
        {
            Mapper.CreateMap<SliderImage, Slider>();
            Slider slider = Mapper.Map<SliderImage, Slider>(sliderImage);
            _db.Entry(slider).State = EntityState.Modified;
            _db.SaveChanges();
            return Json(new { success = true });
        }
        return PartialView("_EditSlider");
    }

What am I doing wrong i this?


Found The Issue

I'm binding the partial view inside the bootstrap modal popup. When I upload from the popup, the upload returning null. Instead if I open the partial View directly in browser, then the file is present in the model. So there is no problem with file upload. The problem is with modal popup or something.

When Using Bootstrap model When Using Bootstrap model

When using partial View Directy When using partial View Directy

Check the difference found when using fiddler between the Bootstrap Modal Submit and Using the partial View Directly in the following image respectively

Comparison of Fiddler requests

When posting from the modal popup, the content type is changed to application/x-www-form-urlencoded where as when using the partial view directly it is multipart/form-data


Found the root Issue.

$('form', dialog).submit(function () {
                    var $form = $(this);
                    var enctype = $form.attr('id');
                    $.ajax({
                        url: this.action,
                        type: this.method,
                        data: $(this).serialize(),
                        success: function (result) {
                            if (result.success) {
                                $('#myModal').modal('hide');
                                //Refresh
                                location.reload();
                            } else {
                                $('#myModalContent').html(result);
                                bindForm();
                            }
                        }
                    });
                    return false;
                });

I'm using AJAX posting to submit the data from my form. When using $(this).serialize() the ajax success is being called but the file is not returning as the content type is different. How can I change this??

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think I have been able to identify your problem, Ajax does not support file serialization, you should use the following method in the script:

$('form', dialog).submit(function () {
        var formData = new FormData($(this)[0]);
        $.ajax({
            url: this.action,
            type: this.method,
            contentType: this.enctype,
            data: formData,
            success: function (result) {
                if (result.success) {
                    $('#myModal').modal('hide');
                    $('#replacetarget').load(result.url); //  Load data from the server and place the returned HTML into the matched element
                } else {
                    $('#myModalContent').html(result);
                    bindForm(dialog);
                }
            }
        });
        return false;
    });

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...