我有以下类型,我用它来扩展在整个系统中使用的另一个类型:
public class SystemUser : User
{
public int? RoleId
{
get { return this.Relationhip.FirstOrDefault().TypeList.FirstOrDefault().Id();}
set { RoleId = value; }
}
public Role _Role
{
get { return (Role)RoleId; }
set { RoleId = (int)value; }
}
public SelectListItem[] RolesList { get; set; }
public bool IsA(params Role[] roles)
{
return new List<Role>(roles).Any(v => v.Equals(_Role));
}
public bool IsNotA(params Role[] roles)
{
return !(new List<Role>(roles).Any(v => v.Equals(_Role)));
}
}
我基本上使用此Type作为数据库的数据容器,并将其作为@model从控制器传递给我们的视图。视图获取填充得很好,但在我使用@ Html.LabelFor()字段修改模型后,并将该数据传递给我们用于将更新的数据保存到数据库的控制器,模型为空。如果我单步执行POST,我的SystemUser类中的ROleId的getter上会出现NullReferenceException。注意_Role属性;众所周知,如果类的属性与其类型具有相同的名称,则模型将向控制器发布空白,但我已经修复了它。
这是观点的内容:
@model SystemUser
@using (Html.BeginForm("Usr", "Mr", FormMethod.Post, new {@autocomplete="off"}))
{
//Fields removed for sake of simplifying stackoverflow post
<input class="button green-bg" type="submit" value="Save" />
<input class="button gray-bg" type="button" onclick="location.href='@Url.Action("View", "Mr")'" value="Cancel" />
}
非常感谢任何帮助。
答案 0 :(得分:2)
当您在控制器中填充模型以创建视图时,您将获得EF模型(通过代码的外观)包括子关系。
视图只会回发与页面上命名输入元素匹配的属性。
由于Relationhip
是服务器端集合,因此后置操作中的该属性将为null
。 post动作接收类的简单版本(未填充外键关系)。
如果您需要,您需要在控制器内重新填充该属性(例如,基于发布的后退ID值)。
如果您同时显示控制器代码和基本User
类,我可能会建议进行具体更改以解决此问题:)
解决方法:强>
如果集合存在,请确保getter属性测试:
public int? RoleId
{
get { return this.Relationhip == null ? null : this.Relationhip.FirstOrDefault().TypeList.FirstOrDefault().Id();}
set { RoleId = value; }
}
其他强>
我也有点担心因为没有字段支持RoleId
属性所以set { RoleId = value; }
实际上是一个递归调用。你可能想检查一下。
因为它是派生属性,所以我希望它看起来像这样(没有setter):
public int? RoleId
{
get { return this.Relationhip.FirstOrDefault().TypeList.FirstOrDefault().Id();}
}
或者,如果它是数据库的缓存本地值,则使用以下命令向返回该属性添加一个私有字段:
private int? roleId;
public int? RoleId
{
get
{
return (roleId = roleId.GetValueOrDefault(this.Relationhip == null ? null : this.Relationhip.FirstOrDefault().TypeList.FirstOrDefault().Id()));
}
set { roleId = value; }
}