我的Razor模型在Post上为null

时间:2015-01-15 15:28:40

标签: c# asp.net-mvc asp.net-mvc-4 razor

我有以下类型,我用它来扩展在整个系统中使用的另一个类型:

    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" />
    }

非常感谢任何帮助。

1 个答案:

答案 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; }
    }