模型绑定不起作用

时间:2012-05-24 19:16:39

标签: asp.net-mvc asp.net-mvc-3

我有以下POCO课程:

public class Location
    {
        public int LocationId { get; set; }
        public string Name { get; set; }
        public string Street { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string ZipCode { get; set; }
        public string Country { get; set; }
        public float? Latitude { get; set; }
        public float? Longitude { get; set; }
        public string PhoneNumber { get; set; }
        public string EmailAddress { get; set; }
        public string Website { get; set; }
        public virtual ICollection<Program> Programs { get; set; }
        public virtual ICollection<PlayerType> PlayerTypes { get; set; }
    }

public class PlayerType
    {
        public int PlayerTypeId { get; set; }
        public string Name { get; set; }
        public int SortOrder { get; set; }
        public bool IsActive { get; set; }
        public virtual ICollection<Location> Locations { get; set; }
    }

和视图模型类

public class LocationViewModel
    {
        public Location Location { get; set; }
        public IList<PlayerType> SelectPlayerTypes { get; set; } 

        public LocationViewModel()
        {
            Location = new Location();
        }

    }

在我的创建表单中,我已将模型定义为

@model Locator.Models.LocationViewModel

并拥有以下字段:

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

在我的控制器中处理POST我

[HttpPost]
        public ActionResult Create(LocationViewModel location)
        {
            if (ModelState.IsValid) {
                locationRepository.InsertOrUpdate(location.Location);
                locationRepository.Save();
                return RedirectToAction("Index");
            }
            location.SelectPlayerTypes = golferTypeRepository.All.Where(p => p.IsActive).ToList();
            return View(location);
        }

问题是我有一个Location对象,但没有一个属性要设置为在表单中输入的值。

我在这里做错了吗?

由于

10 个答案:

答案 0 :(得分:43)

问题在于:

[HttpPost]
public ActionResult Create(LocationViewModel location)
你看到了吗?它是您的行动参数的名称:location

现在查看您的视图模型,它有一个名为Location的属性:

public Location Location { get; set; }

这会混淆模型绑定器。它不再知道您是否需要绑定LocationViewModel或其属性。

所以简单地重命名以避免冲突:

[HttpPost]
public ActionResult Create(LocationViewModel model)

答案 1 :(得分:32)

只是为了提供另一个可能的原因:我花了几个小时在我的代码中查找错误,并且在我的情况下绑定器不起作用的原因是使用具有公共字段而不是公共属性的模型:

public int CustomerName;

应该是:

public int CustomerName { get; set; }

现在已经在ASP.NET MVC上工作了3年,之前我从未遇到过这个问题。希望它能让人感到沮丧;)

答案 2 :(得分:4)

加入聚会也很晚,但是经过3年的asp.net mvc,我发现禁用的输入没有发布,所以模型绑定器当然不能绑定它们。见here

  

&#34;表格中的残疾元素将不会被提交&#34;。

更好地使用readonly="readonly"而非禁用。请参阅here

答案 3 :(得分:2)

让我在这里补充说明模型活页夹无法正常工作的另一个原因。

我有一个带有属性ContactPhone的模型,在我决定将此属性的名称更改为Phone的某个地方,然后我突然对此属性进行模型绑定时停止工作正在尝试创建一个新实例。

问题出在我控制器中的Create操作上。我使用了默认的Visual Studio脚手架,它创建了方法签名,如下所示:

public ActionResult Create([Bind(Include = "Id,ContactPhone, ...")] Customer customer)
{ ... }

注意Bind属性,脚手架使用原始名称ContactPhone创建了字段,因为这是一个字符串,所以没有重构。由于未包含新字段Phone,因此模型绑定器会忽略它的值。

我希望这能节省一些人的时间。

祝你好运!

答案 4 :(得分:1)

另一个原因: 通常我使用内置的编辑器或显示器,并且从未遇到过这个问题。但是在这种情况下我需要一个半自定义控件。基本上是选项上有大量数据属性的下拉列表。

我在做什么,因为我的选择标签是:

<select name="@Html.IdFor(x => x.SubModel.ID)" id="@Html.IdFor(x => x.SubModel)" class="form-control select-control">

现在所有的东西都张贴回来,未经训练的眼睛看起来一切都应该工作和绑定。然而,IdFor助手使用下划线渲染子模型。模型绑定器不会将下划线解释为类层次结构指示符。什么应该分开他们是一个点。来自NameFor:

<select name="@Html.NameFor(x => x.SubModel.ID)" id="@Html.IdFor(x => x.SubModel)" class="form-control select-control">

NameFor修复了我的所有问题。

答案 5 :(得分:1)

重申Tod所说的,模型活页夹需要一个名字&#39; HTML元素的属性以映射属性。 我手工做了一个快速的测试表,只使用了#id;&#39;属性来标识我的元素。

当我添加&#39;名称时,一切都已到位。属性。

COMM             PID    SWAP  
dockerd          662    2736  kB
skypeforlinux    26865  1320  kB
NetworkManager   303    1112  kB
slim             392    1028  kB
redis-server     350    204   kB

答案 6 :(得分:1)

我的情况有点特殊,但希望它对类似情况的人有所帮助。我的视图模型实现了IValidatableObject,如果成功,此接口的Validate方法将返回null。我必须返回一个空的IEnumerable。因此,绑定实际上正在发生但崩溃。

基本上,当您遇到此问题时,请使用Fiddler查看发布的数据,确保发布的变量与视图模型上的属性(不是字段!)匹配,然后在View Model构造函数上放置一个断点以确保路由引擎点击了正确的POST方法。祝你好运!

答案 7 :(得分:0)

这节省了我的一天。我有以下几点:

public ActionResult Edit(int masterId, ConclusionView conclusion)

ConclusionView有一个名为Conclusion的属性,所以我几乎失去了理智。

答案 8 :(得分:0)

我知道对此发表评论为时已晚。我所做的是在ViewModel中添加了参数较少的构造函数,一切都很棒。

答案 9 :(得分:0)

对于仍然遇到此问题的其他人,如果您在post方法中将参数命名为与其中一个属性相同,则默认的modelbinder也将失败。