简体   繁体   中英

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. 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. If I step through the POST, I get a NullReferenceException on the getter of the ROleId in my SystemUser class. Notice the _Role property; 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 .

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. The post action receives a simple version of the class (foreign key relationships are not populated).

If you need it, inside the controller you need to repopulate that property (eg based on a posted back ID value).

If you show your controller code and the base User class too, I may be able to suggest specific changes to work around this :)

Workaround:

Ensure the getter property tests if the collection is present:

    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; } set { RoleId = value; } is actually a recursive call. 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; }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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