首页 > 解决方案 > View model always empty when submitting form from view to controller

问题描述

I am very new to MVC and have seen many similar questions but I can't seem to get this to work. I have an image file and I am trying to select the product that the image applies to from a list of products. I have created a view model that holds a Image object and a SelectList of products. The Image object consists of ID, Filename and ProductID. What I am trying to achieve is selecting the product from a drop down list of products and assigning the ProductID field of the Image to the ID of the selected product.

Public Class ProductImageViewModel
    Public Image As ProductImage
    Public ProductList As SelectList
End Class

In the get method of my controller I am creating an instance of the viewmodel. I assign the Image object from the database and the ProductList object from an already created list of products, then pass it to the view.

    ' GET: ProductImages/Edit/
    Function Edit(ByVal id As Integer?) As ActionResult
        If IsNothing(id) Then
            Return New HttpStatusCodeResult(HttpStatusCode.BadRequest)
        End If
        Dim Model As New ProductImageViewModel
        Model.Image = db.ProductImages.Find(id)
        If IsNothing(Model.Image) Then
            Return HttpNotFound()
        End If
        Model.ProductList = New SelectList(ProductList, "Value", "Text")
        Return View(Model)
    End Function

In the view object it displays the filename and the dropdown list of products. I select a product from the list and click submit, which I was expecting to pass the model back to the Post method of my controller. The code for the view is

@ModelType ProductImageViewModel
    @Code
        ViewData("Title") = "Edit"
        Layout = "~/Views/Shared/_Layout.vbhtml"
    End Code

    <h2>Edit</h2>

    @Using (Html.BeginForm())
        @Html.AntiForgeryToken()

        @<div class="form-horizontal">
            <h4>Product Image</h4>
            <hr />
            @Html.ValidationSummary(True, "", New With {.class = "text-danger"})
            @Html.HiddenFor(Function(Model) Model.Image.ID)

            <div class="form-group">
                @Html.LabelFor(Function(Model) Model.Image.Filename, htmlAttributes:=New With {.class = "control-label col-md-2"})
                <div class="col-md-10">
                    @Html.TextBoxFor(Function(Model) Model.Image.Filename, New With {.htmlAttributes = New With {.class = "form-control"}})
                    @Html.ValidationMessageFor(Function(Model) Model.Image.Filename, "", New With {.class = "text-danger"})
                </div>
            </div>

            <div class="form-group col-md-10">
                @Html.Label("Product", htmlAttributes:=New With {.class = "control-label col-md-2"})
                <div class="col-md-10">     
                    @Html.DropDownListFor(Function(Model) Model.Image.ProductID, Model.ProductList, htmlAttributes:=New With {.class = "control-label col-md-8"})   
                    @Html.ValidationMessageFor(Function(Model) Model.Image.ProductID, "", New With {.class = "text-danger"})
                </div>

            </div>

            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <input type="submit" value="Save" class="btn btn-default" />
                </div>
            </div>
        </div>  
    End Using

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

    @Section Scripts 
        @Scripts.Render("~/bundles/jqueryval")
    End Section

This displays correctly and I can selected the required product. When I click submit and put a breakpoint in the post method of the controller then both the Image object and the ProductList object contain nothing.

' POST: ProductImages/Edit/5
<HttpPost()>
<ValidateAntiForgeryToken()>
Function Edit(ByVal Model As ProductImageViewModel) As ActionResult
    If ModelState.IsValid Then
        db.Entry(Model.Image).State = EntityState.Modified
        db.SaveChanges()
        Return RedirectToAction("Index")
    End If
    Return View()
End Function

I have tried all the suggestions I have seen in other posts but it always seems to pass an empty model back to the controller. Probably a fundamental misunderstanding of how this is supposed to work but I am at a loss as to what I am doing wrong. Any help would be appreciated.

标签: asp.net-mvcvb.net

解决方案


推荐阅读