10

我有以下 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 对象,但没有一个属性可以设置为表单中输入的值。

我在这里做错了吗?

谢谢

4

10 回答 10

51

这是问题所在:

[HttpPost]
public ActionResult Create(LocationViewModel location)

你看到了吗?这是您的操作参数的名称:location.

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

public Location Location { get; set; }

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

所以只需重命名以避免冲突:

[HttpPost]
public ActionResult Create(LocationViewModel model)
于 2012-05-25T06:25:36.353 回答
35

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

public int CustomerName;

它应该是:

public int CustomerName { get; set; }

已经在 ASP.NET MVC 上工作了 3 年,我以前从未遇到过这种情况。希望它可以节省一些人的挫败感;)

于 2013-05-15T08:15:46.793 回答
5

入党也晚了,但是在asp.net mvc 3年后,我发现禁用的输入没有发布,所以模型绑定器当然无法绑定它们。见这里

“不会提交表单中的禁用元素”。

更好地使用readonly="readonly"而不是禁用。见这里

于 2015-09-05T05:44:11.347 回答
3

重申一下 Tod 所说的,模型绑定器需要 HTML 元素上的“名称”属性来映射属性。我正在手工制作一个快速测试表格,并且只使用“id”属性来识别我的元素。

当我添加“名称”属性时,一切都到位了。

<input type="text" id="Address" name="Address" />
于 2017-06-26T09:52:11.060 回答
2

让我在这里补充一下模型绑定器无法正常工作的另一个原因。

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

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

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

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

我希望这可以节省某人的时间。

祝你好运!

于 2014-07-04T22:47:58.927 回答
1

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

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

于 2019-03-27T22:30:22.730 回答
1

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

于 2018-09-01T22:02:21.537 回答
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 解决了我所有的问题。

于 2016-08-11T10:29:53.137 回答
0

这拯救了我的一天。输入以下内容:

public ActionResult Edit(int masterId, ConclusionView conclusion)

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

于 2013-04-18T09:24:28.803 回答
0

我知道现在评论这个为时已晚。我所做的是在 ViewModel 中添加了无参数构造函数,一切都很棒。

于 2015-05-23T19:19:02.680 回答