MVC3模型与外键绑定

时间:2011-12-28 12:09:08

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

我花了最近2天试图解决这个问题,基本上我有两个模型(Event和EventStyle),但无论我尝试什么,EventStyle都不会绑定。

这些类是 Code-First 数据库的一部分,Event模型有一个EventStyle的外键。

以下是我的淡化模型:

public class Event {
    public string Id { get; set; }
    public string Name { get; set; }     
    public string Description { get; set; }
    public virtual EventStyle Style { get; set; }
}

public class EventStyle {
    public string Id { get; set; }
    public string Image { get; set; }
}   

在我的控制器中我有这个:

[HttpPost]
public ActionResult Create(Event evt) { /* add evt to the database */ }

一个简单的形式:

@using (Html.BeginForm()) {
    @Html.HiddenFor(evt => evt.Id)
    @Html.HiddenFor(evt => evt.Style)
    @Html.TextBoxFor(evt => evt.Name)
    @Html.TextAreaFor(evt => evt.Description)
}

(我实际上有一个自定义的@ Html.EditorFor for evt.Style,它改变了隐藏字段的值)

提交表单后,事件已与IdNameDescription正确绑定。 但是,即使隐藏字段在数据库中包含有效的Style Id,EventStyle属性仍为null。

如果删除隐藏字段,则Style成为默认字段(在Event的构造函数中设置)

我也尝试在EventStyle上使用ModelBinder,但正确的ID永远不会通过bindingContext,这可能是问题的一部分。

但是,正确的ID确实来自Binder controllerContext,或直接使用Controller中的FormCollection。我宁愿让ModelBinding正常工作。

也许ModelBinder对我的数据库没有任何了解?如果是这样,我怎么能让它识别我的数据库?

编辑:嗯刚刚删除了virtual,现在Binder正在从表单中获取正确的ID,但它仍然没有进入事件模型

EDIT2:解决了,使用它从数据库加载EventStyle:

if (evt.Style != null) {
    evt.Style = db.EventStyles.Find(evt.Style.Id);
}

3 个答案:

答案 0 :(得分:0)

隐藏字段只能存储标量值。您的EventStyle类很复杂,包含2个属性。因此,您需要为2个属性中的每个属性提供2个隐藏字段:

@Html.HiddenFor(evt => evt.Style.Id)
@Html.HiddenFor(evt => evt.Style.Image)

答案 1 :(得分:0)

使用Id属性本身:

@Html.HiddenFor(evt => evt.Style.Id)

修改

需要注意的是,@html.[InputType]For()辅助方法用于在标记中的元素上设置适当的名称/ id属性,以便在发布时,默认模型绑定器将知道如何设置属性你的模特。

如果你看一下html标记,你会看到你的样式元素是这样创建的:

<input id="Style_Id" type="hidden" value="" name="Style.Id" />

这是默认模型绑定器可以理解的命名约定,以及它用于在模型上设置属性的用途。

答案 2 :(得分:0)

您缺少Event Model Class中的EventStyle属性,使其成为该模型的外键。

只需将其添加到您的Event模型类中,就可以了。

public int EventStyleId { get;set; }