首页 > 解决方案 > 我错过了什么?从“保存”操作传递的值始终为 Null - MVC

问题描述

在我看来MoviesForm.cshtml,有一个BeginForm我试图用来将模型传递给控制器​​中调用Save的动作。Movies但是,在调试时,我注意到传递给Save操作的这个模型始终为空,我只是不知道为什么。

这是模型类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;

namespace vidly.Models
{
    public class Movies
    {
        public Movies() 
        {
            DateAdded = DateTime.Now;
        }

        public int Id { get; set; }
        public string Name { get; set; }

        [Display(Name = "Number in Stock")]
        public int Availability { get; set; }

        [Display(Name = "Release Date")]
        public DateTime ReleaseDate { get; set; }

        public DateTime DateAdded { get; set; }

        public Genre Genre { get; set; }

        [Display(Name = "Genre")]
        [Required]
        public int GenreId { get; set; }
    }
}

这是我在控制器中的操作

[HttpPost]
public ActionResult Save(Movies movies)
{
        System.Diagnostics.Debug.WriteLine($"Object: {movies.Name} {movies.Id}");

        if (movies.Id == 0)
        {
            movies.DateAdded = DateTime.Now;
            _context.Movies.Add(movies);
        }
        else 
        {
            var selectedMovie = _context.Movies.Single(c => c.Id == movies.Id);
            selectedMovie.Name = movies.Name;
            selectedMovie.ReleaseDate = movies.ReleaseDate;
            selectedMovie.GenreId = movies.GenreId;
            selectedMovie.Availability = movies.Availability;             
        }

        _context.SaveChanges();

        return RedirectToAction("Index", "Movies");
}

这是视图

@model vidly.ViewModel.MoviesFormViewModel
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>@ViewBag.Save - Movie</h2>

@using (Html.BeginForm("Save", "Movies"))
{
    <div class="form-group">
        @Html.LabelFor(m => m.Movie.Name)
        @Html.TextBoxFor(m => m.Movie.Name, new { @class = "form-control" })
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Movie.ReleaseDate)
        @Html.TextBoxFor(m => m.Movie.ReleaseDate, "{0:d MMM yyyy}", new { @class = "form-control" })
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Movie.GenreId)
        @Html.DropDownListFor(m => m.Movie.GenreId, new SelectList(Model.Genre, "Id", "Name"), "Select a Genre", new { @class = "form-control" })
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Movie.Availability)
        @Html.TextBoxFor(m => m.Movie.Availability, new { @class = "form-control" })
    </div>
    @Html.HiddenFor(m => m.Movie.Id)
    <button type="submit" class="btn btn-primary">Save</button>
}

谢谢!

标签: c#asp.net-mvc-5html.beginform

解决方案


您的 ViewModel 是一个MoviesFormViewModel. 当您使用扩展来构建类似的东西@Html.TextBoxFor(m => m.Movie.Name时,生成的 html(您应该看一下)将期望一个具有Movie对象作为属性的对象。

但是您的控制器直接期望一个Movies对象。因此,框架的 ModeBinder 将忙于构建模型并试图弄清楚如何映射属性,因为它们不是同一个对象。

您可以将控制器操作更改为接受 a MoviesFormViewModel,然后访问其Movie属性,或者您可以手动构建输入以匹配Movies操作所期望的对象。


推荐阅读