2012-05-24 111 views
7

我有以下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); 
     } 

的问题是,我有一个定位对象,但没有任何属性都设置为在表单中输入的值。

难道我做错了什么吗?

感谢

+0

我可能会关闭,但我认为您在构造函数中初始化'Location'会抛出它。你可以尝试删除该行(并在模型本身之外实例化属性)? –

+0

我在Create ActionResult(不是帖子)中实例化它,现在当我发布时,Location是null。 – Mike

+0

是的,这就是我希望你会尝试的。哦,猜猜这不是问题。 –

回答

37

这里的问题:

[HttpPost] 
public ActionResult Create(LocationViewModel location) 

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

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

public Location Location { get; set; } 

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

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

[HttpPost] 
public ActionResult Create(LocationViewModel model) 
+0

我不能停止笑,它是如何让我感觉转瞬即逝 –

+0

发生在我身上,很棒的回答! – Jesse

+1

我有一个模型属性的类用于车辆的品牌/型号。当然,我传递的参数是'model'。 * facepalm * – DataHerder

0

这救了我的一天。 IAD如下:

public ActionResult Edit(int masterId, ConclusionView conclusion) 

ConclusionView有一个名为Conclusion,所以我几乎失去了我的脑海财产。

30

只是为了促进另一种可能的原因是:我花了几个找我的代码中的错误和粘结剂在我的情况不工作的原因小时使用公共领域而不是公共属性的模型:

public int CustomerName; 

,它应该是:

public int CustomerName { get; set; } 

一直在ASP.NET MVC 3年了,我从来没有碰到这个来了。希望它可以节省一些人的一些挫折;)

+0

希望授予 - 今天把我从吹垫子救了出来。我有所有的领域,没有任何财产。所有的HTML链接都没有细节。感谢您为@Grzegorz添加这个额外的答案。 – edhubbell

+0

上帝,我花了很多时间试图弄清楚这一点!谢谢! – LukeP

+0

这个答案也有助于提醒我,属性需要** public **。 –

2

让我在这里添加另一个原因,为什么模型联编程序无法正常工作。

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

问题出在我的控制器的Create操作。我已经使用了默认的Visual Studio的脚手架和已经创建的方法签名是:

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

,请注意Bind属性时,棚架创建使用原来的名字ContactPhone的字段和,因为这是一个字符串,它没有重构。由于未包含新字段Phone,它的值被模型联编程序忽略。

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

祝你好运!

0

我知道现在评论这件事为时已晚。我所做的是在ViewModel中添加了少参数的构造函数,并且所有工作都很棒。

4

也来不及加入派对,但经过3年的asp.net mvc,我发现禁用的输入不会发布,所以模型绑定器无法绑定它们当然。请参阅here

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

更好地使用readonly="readonly"超过禁用。见here

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 fixed我所有的问题。

0

为了重申Tod的说法,模型联编程序需要HTML元素上的'name'属性来映射属性。 我正在手工做一个快速测试表单,只使用'id'属性来标识我的元素。

当我添加'名称'属性时,所有东西都到位了。

<input type="text" id="Address" name="Address" />