Can't get selected drop down value to bind to view model property

冷暖自知 提交于 2019-12-11 10:27:27

问题


I'm having trouble binding the selected value of a drop down list to the correct property in my view model. I can't see what I am doing wrong here. I've put the code that should help show what I'm doing below. I've omitted some things such as the population of the 'AllFolders' property of the view model, as it's just a simple List with an object called ImageGalleryFolder.

Every time the form posts back, the ParentFolderId property is null without fail. This is driving me crazy and I've wasted a lot of time trying to work it out.

Can anyone see something I'm doing wrong?

This is the view model

public class ImageGalleryFolderViewModel
{
    [Required]
    public string Title { get; set; }

    public int Id { get; set; }
    public string CoverImageFileName { get; set; }
    public HttpPostedFileBase UploadedFile { get; set; }
    public string ParentFolderId { get; set; }
    public IList<ImageGalleryFolder> AllFolders { get; set; } 
}

Here is the view code

@using Payntbrush.Presentation.Demo.MVC3.Areas.Admin
@model Payntbrush.Presentation.Demo.MVC3.Areas.Admin.Models.ImageGalleryFolderViewModel

@{
    ViewBag.Title = "Create A New Gallery Folder";
}

<h2>@ViewBag.Title</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm((string)ViewBag.Action + "Folder", "Portfolio", FormMethod.Post, new { Id = "CreateFolder", enctype = "multipart/form-data" }))
{
    @Html.ValidationSummary(true)

        if(((string)ViewBag.Action).ToLower() == FormConstants.Edit.ToLower())
        {
            @Html.HiddenFor(m => m.Id)
            @Html.HiddenFor(m => m.CoverImageFileName)
            @Html.HiddenFor(m => m.ParentFolderId)
        }

        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.UploadedFile)
        </div>
        <div class="editor-field">
            <input type="file" name="UploadedFile"/>
            @Html.ValidationMessageFor(model => model.UploadedFile)
        </div>


    {
        // Count > 1 is important here. If there is only 1 folder, then we still don't show the drop down
        // as a child folder can't have itself as it's own parent.
    }
    if(@Model.AllFolders.Count > 1)
         {
             <div class="editor-label">
                 Choose a parent folder (optional)
             </div>
             <div class="editor-field">
                    @Html.DropDownListFor(m => m.ParentFolderId, new SelectList(Model.AllFolders, "Id", "Title"))
             </div>


         }


    <p>
            <input type="submit" value="Save" />
        </p>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

I've ommitted my view, but this is what my form looks like when rendered in the browser. The form looks good from what I can see?

   <form Id="CreateFolder" action="/SlapDaBass/Portfolio/EditFolder/1" enctype="multipart/form-data" method="post">
<input data-val="true" data-val-number="The field Id must be a number." data-val-required="The Id field is required." id="Id" name="Id" type="hidden" value="1" />
<input id="CoverImageFileName" name="CoverImageFileName" type="hidden" value="" />
<input id="ParentFolderId" name="ParentFolderId" type="hidden" value="" />        


<div class="editor-label">

             <label for="Title">Title</label>

            </div>

            <div class="editor-field">

                <input class="text-box single-line" data-val="true" data-val-required="The Title field is required." id="Title" name="Title" type="text" value="Test" />

                <span class="field-validation-valid" data-valmsg-for="Title" data-valmsg-replace="true"></span>

            </div>

            <div class="editor-label">

                <label for="UploadedFile">UploadedFile</label>

            </div>

            <div class="editor-field">

                <input type="file" name="UploadedFile"/>

                <span class="field-validation-valid" data-valmsg-for="UploadedFile" data-valmsg-replace="true"></span>

            </div>

                 <div class="editor-label">

                     Choose a parent folder (optional)

                 </div>

                 <div class="editor-field">

                        <select id="ParentFolderId" name="ParentFolderId">
                           <option value="1">Test</option>
                           <option value="2">Test 2</option>

                         </select>

                 </div>

        <p>

                <input type="submit" value="Save" />

            </p>

    </form>

And this is the controller action:

[HttpPost]
        public ActionResult EditFolder(int id, ImageGalleryFolderViewModel model)
        {
            if (ModelState.IsValid)
            {
                Services.PortfolioService.UpdateFolder(model.MapToDomainModel(), model.UploadedFile);
                return Home;
            }
            return View();
        }

回答1:


change the data type of the ParentFolderId

public class ImageGalleryFolderViewModel
{
    [Required]
    public string Title { get; set; }

    public int Id { get; set; }
    public string CoverImageFileName { get; set; }
    public HttpPostedFileBase UploadedFile { get; set; }
    public int ParentFolderId { get; set; }
    public IList<ImageGalleryFolder> AllFolders { get; set; } 
}

also use the Html helper for the dropdownlist

<%: 
     Html.DropDownListFor(
           model => model.ParentFolderId , 
           new SelectList(
                  new List<Object>{ 
                       new { value = 1 , text = "Test"  },
                       new { value = 2 , text = "Test2" },
                       new { value = 3 , text = "Test3"}
                    },
                  "value",
                  "text"
           )
        )
%>

i hope you are strongly typing your view like

    public ActionResult EditFolder()
    {

        return View(new ImageGalleryFolderViewModel());
    }



回答2:


Please refer below link for the bind drop down list. It will be very helpful to you.

ASP.NET MVC - drop down list selection - partial views and model binding

Here if you do not want to create property in model for the List of items, than you can also store it in a ViewData or ViewBag. Please find sample code below.

<%= Html.DropDownList("Category.CategoryId", new SelectList((
IEnumerable<ProductManagement.Models.Category>)ViewData["CategoryList"],
"CategoryId", "CategoryName"))%>



回答3:


You're creating a Hidden input for ParentFolderId with an empty value. This is probably overriding the value that the DropDownList is trying to post. Remove this line:

@Html.HiddenFor(m => m.ParentFolderId)



回答4:


you have 2 element for ParentFolderId

one of them is hidden field

@Html.HiddenFor(m => m.ParentFolderId)  

second is select element

@Html.DropDownListFor(m => m.ParentFolderId, new SelectList(Model.AllFolders, "Id", "Title")) 

and modelbinder bind the first matched element value to model.

You have to remove hidden field



来源:https://stackoverflow.com/questions/9476372/cant-get-selected-drop-down-value-to-bind-to-view-model-property

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!