我正在使用MVC3。我有一个我用fluidNhibernate创建的模型对象。它包含一些值类型,还有一些通过流体创建的其他对象的引用类型。延迟加载已启用。为了使引用类型在我的视图中显示为下拉框,我的代码如下:
@Html.DropDownListFor(m => m.TheObject.objId, new SelectList(Model.TheObjects, "ObjId", "ItemToDislpay"))
在将模型传递给视图之前,控制器会将List<TheObject>
分配给Model.TheObjects
。
我的控制器中的编辑操作:
public ViewResult Edit(int id)
{
myModelType myModel = //get my model object by id here.
myModel.TheObjects = //assign List<SomeObject> here
myModel.TheObjects2 = //assign List<SomeObject2> here
return View(myModel);
}
[HttpPost]
public ActionResult Edit(MyModelType myModel)
{
if(ModelState.IsValid)
{
....
}
else
{
//We end up here even though the validation should have succeeded
// myModel.TheObjects is null, but I don't know why
return View(myModel);
}
}
属性示例:
[Required(ErrorMessage = "Please enter Username")]
public virtual string UserName { get; set; }
一切正常,直到我将验证属性添加到模型属性。我将属性分配给哪个参数无关紧要。只要我至少有一个验证属性ModelState.IsValid
返回false,并且我在非post操作中指定的所有列表在myModel中都为null。我尝试禁用客户端验证,但这没有帮助。可能导致这种情况的原因是什么?
我认为列表应该被传回,但我猜不是。如果所需的字符串存在,为什么验证失败呢?
似乎FirstName验证在服务器端失败ModelState.IsValid表示缺少名字,而模型对象显然填写了First Name字段。以下是我的视图处理FirstName的方式:
<div class="editor-field">
@Html.EditorFor(model => model.FirstName)
@Html.ValidationMessageFor(model => model.FirstName)
</div>
以下是我的提交方式:
<input type="submit" value="Save" />
客户端验证正确捕获空的FirstName字段,并停止提交,但如果我填写FirstName,那么服务器端代码会给我上述问题。
答案 0 :(得分:1)
您的问题仍然有点模糊,但这可能会对您的问题有所帮助。
将此属性添加到模型中:
[MetadataType(typeof(MyModelTypeMeta))]
public partial class MyModelType
{
...
}
并添加MyModelTypeMeta类,如下所示,添加一个字段以匹配每个字符串属性,并告诉模型绑定器让空字符串值保持为空而不是将它们更改为null,这通常会导致字符串属性失败绑定(因为你没有在模型中将它们定义为可为空)
public class MyModelTypeMeta
{
[DisplayFormat(ConvertEmptyStringToNull=false)]
public string myProperty;
}
答案 1 :(得分:0)
看看你添加了什么,我打赌问题是空的List&lt; someObject&gt;当它至少应该是一个空列表时为null。 (对于List&lt; someObject2&gt;属性也是如此)
在MyModelType的构造函数中,您应该将它们初始化为空列表,以便绑定器不会将它们视为null。类似的东西:
public MyModelType()
{
myModel.TheObjects = new List<SomeObject>();
myModel.TheObjects2 = new List<SomeObject2>();
...
}
答案 2 :(得分:0)
好的,我发现了问题。感谢Neil N帮助我解决问题。首先,如果验证失败,则需要在回发操作中重新分配列表,因为它们不会从视图中保留,并且在将模型发送回视图时我们将再次需要它们。
现在,问题的核心是这个。我模型中的一个字段是与模型类型相同的属性。具体而言,每个用户都具有管理员属性,该属性也是用户类型。它是由nhibernate延迟加载的引用类型。当我根据用户的需要修饰FirstName属性时,这也适用于用户的管理器。 manager对象只有UserId字段集,因为这是我们绑定到视图中的下拉列表。通过查看ModelState.Values,我发现错误消息说在值索引9下需要名字。关键的故障排除步骤现在是查看ModelState.Keys集合并找到具有相同索引9的项目,该项目具有Manager.FirstName的值。因此,它是具有空FirstName的管理器对象,而不是正在编辑的直接User对象。
我想现在的问题是我应该如何解决这个问题。我应该以不同方式进行绑定吗?我是否在nHibernate方面做了些什么?我应该custom validation吗?我应该以某种方式指定Manager对象,以检查是否为Manager选择了有效的userId?我很想听听一些建议。非常感谢大家的帮助。