简体   繁体   English

我的Razor模型在Post上为空

[英]My Razor model is null on Post

I have the following Type which I am using to extend another Type that is used throughout our system: 我使用以下类型来扩展在整个系统中使用的另一种类型:

    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)));
        }
    }

I'm essentially using this Type to act as a container for data from our database and passing it from a controller to our view as an @model. 我本质上是在使用此Type充当数据库中数据的容器,并将其作为@model从控制器传递到我们的视图。 The view Gets populated just fine, but after I modify the model using @Html.LabelFor() fields, and go to pass that data to a controller that we use to save the updated data to the database, the model is null. 可以很好地填充“视图”视图,但是在我使用@ Html.LabelFor()字段修改了模型并将数据传递到用于将更新后的数据保存到数据库的控制器后,该模型为空。 If I step through the POST, I get a NullReferenceException on the getter of the ROleId in my SystemUser class. 如果我逐步执行POST,则会在SystemUser类中的ROleId的getter上收到NullReferenceException。 Notice the _Role property; 注意_Role属性; It's known that if a property of a class has the same name as its Type, the model will post empty to the controller, but I've fixed that already. 众所周知,如果类的属性与其类型具有相同的名称,则模型会将空值发布到控制器,但是我已经修复了该问题。

This is the meat of the View: 这是视图的实质:

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

Any help here would be greatly appreciated. 在这里的任何帮助将不胜感激。

While you are populating the model in the controller to create the view, you get an EF model (by the look of your code) including child relationships . 在控制器中填充模型以创建视图时,您将获得一个EF模型(通过代码外观), 其中包括子关系

The view will only post back simply properties that match named input elements on the page . 该视图将仅回发与页面上命名输入元素匹配的属性。

As Relationhip is a server-side collection, that property will be null inside the post action. 由于Relationhip是服务器端集合,因此该属性在post操作中将为null The post action receives a simple version of the class (foreign key relationships are not populated). post操作收到该类的简单版本(未填充外键关系)。

If you need it, inside the controller you need to repopulate that property (eg based on a posted back ID value). 如果需要,则需要在控制器内部重新填充该属性(例如,基于回发的ID值)。

If you show your controller code and the base User class too, I may be able to suggest specific changes to work around this :) 如果您也显示了控制器代码和基本的User类,那么我可能会建议采取一些具体的措施来解决此问题:)

Workaround: 解决方法:

Ensure the getter property tests if the collection is present: 确保getter属性测试是否存在该集合:

    public int? RoleId
    {
        get { return this.Relationhip == null ? null : this.Relationhip.FirstOrDefault().TypeList.FirstOrDefault().Id();}
        set { RoleId = value; }
    }

Additional: 额外:

I am also a little concerned that as there is no field backing the RoleId property so set { RoleId = value; } 我也有点担心,因为没有字段支持RoleId属性,所以set { RoleId = value; } set { RoleId = value; } is actually a recursive call. set { RoleId = value; }实际上是一个递归调用。 You might want to check this. 您可能要检查一下。

As it is a derived property I would have expected it to look like this (no setter): 因为它是一个派生属性,所以我希望它看起来像这样(无设置器):

    public int? RoleId
    {
        get { return this.Relationhip.FirstOrDefault().TypeList.FirstOrDefault().Id();}
    }

or, if it is a act as a cached local value for the database, add a private field to back the property with: 或者,如果它充当数据库的缓存本地值,则添加一个私有字段来支持该属性,方法是:

    private int? roleId;
    public int? RoleId
    {
        get 
        { 
             return (roleId = roleId.GetValueOrDefault(this.Relationhip == null ? null : this.Relationhip.FirstOrDefault().TypeList.FirstOrDefault().Id()));
        }
        set { roleId = value; }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM