0

What I am trying to do is to enable a user upload images in an overlay. After selecting an image, a new row is added with name of the picture. Here goes my code:

my overlay HTML:

@model List<GUI.Models.PictureUploadModel>
@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data", @class = "overlay-form" }))
  {
@Html.AntiForgeryToken()

<div class="row">
    <div class="col-md-5">
        <h3>File</h3>
    </div>
    <div class="col-md-5">
        <h3>Name</h3>
    </div>
    <div class="col-md-2 text-center" style="margin-top: 20px;">
        <label for="picture-upload">
            <i class="fa fa-2x fa-upload" aria-hidden="true"></i>
        </label>
        <input id="picture-upload" name="ImageUpload" type="file" accept="image/*"/>
    </div>
</div>
<div id="image-rows">
    @for (int i = 0; i < Model.Count; ++i)
    {
        @Html.Partial("~/Views/EditorTemplates/UploadRow.cshtml", Model[i])
    }
</div>
<div class="text-center margin-top-20">
    <button class="btn btn-outline" type="submit"><span>Save</span></button>
</div>
}

This partial view is an overlay added in Index view and opened with #pictures-btn:

@model GUI.Models.StructureGeneratorModel

<div class="structure-description-container container">
    <div class="col-md-8">
        @Html.TextAreaFor(m=>m.Description, 10, 60, new { @class = "textarea"})
    </div>
    <div class="col-md-4">
        <div class="btn-container">
            <button id="pictures-btn" class="popup-trigger btn btn-active uppercase">Pictures</button>
        </div>
    </div>
</div>     
@Html.Partial("~/Views/EditorTemplates/UploadOverlay.cshtml", Model)

The partial view contains a row with an image name:

UploadRow.cshtml

@model GUI.Models.PictureUploadModel

@Html.HiddenFor(m=>m.ImageData)
<div class="col-md-5">
    <label for="FileName" id="FileName">@Model.FileName</label>
</div>
<div class="col-md-5">
    @Html.TextBoxFor(m => m.Name)
</div>

Now, when a user clicks #picture-upload btn he can add a picture. Then I strike an ajax post UploadImageRow.

 [HttpPost]
    public ActionResult UploadImageRow()
    {
        try
        {
            HttpPostedFileBase image = Request.Files[0];
            var callModel = new PictureUploadModel(image.FileName, image.FileName);
            callModel.ImageData = image;
            return PartialView("~/Views/EditorTemplates/UploadRow.cshtml", callModel);

        }
        catch (Exception e)
        {

        }

        return PartialView("~/Views/EditorTemplates/UploadRow.cshtml", new PictureUploadModel());

    }

The returned partial view I append do div#image-rows using javascript. Till now everything works well. The row is added. However this new row is not binded to my model. What have I missed?

My PictureUploadModel looks like this:

public class PictureUploadModel
{
    //public int ID { get; set; }
    public string Name { get; set; }
    public string FileName { get; set; }
    public HttpPostedFileBase ImageData { get; set; }
}

When I save the overlay (submit the form) the info image row disappears and when I just close it (without submitting the form) the info image row is still in my overlay, but it is still not binded to my model.

kuleczka
  • 81
  • 11
  • 1
    You cannot use a partial in a loop to generate form controls for collection items (you generating duplicate `name` attributes that have no relationship to the model, and you generating invalid html). You need to use an `EditorTemplate`. But it also seems that your dynamically adding new collection items so that would not work either. If that is the case, then refer [this answer](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) –  Dec 01 '16 at 23:40
  • But there are other issues that make no sense with your code - e.g. `ImageData` is typeof `HttpPostedFileBase` so `@Html.HiddenFor(m=>m.ImageData)` would make no sense –  Dec 01 '16 at 23:42

0 Answers0