Having private properties in ASP.NET MVC model objects

I have an ASP.NET MVC project in which I wanted to track which users created an item. I’m already using membership and authorization, so I just have to annotate my controller methods with an [Authorize] tag. I added a “User” property to the model objects I wanted to track, but I didn’t want MVC scaffolding to allow editing of those “hidden” or system properties.

I tried a few things, such as removing the property setters, but that prevented the DbSet from persisting those properties. I could have written a custom mapping, but that really felt like overkill. Setting Editable annotations never worked for me. Finally, I marked the appropriate setters as “internal”, and had more success.

This isn’t enterprise code, but you can see where I’ve used “internal” to protect some settings. Since the data context is in the same namespace but the view isn’t, the properties are safe from end user editing. 

I’ve also set a few methods to set properties for me. For example, I have Approve and Reject methods which change the status. It’s a lightweight workflow, and would be better to handle another way, but this was a quick-and-dirty approval system and it works well enough.

 public class PurchaseRequest
    {
        private string userName;
        private DateTime requestDate;
        private string status = "PENDING";

        public int PurchaseRequestId { get; set; }

        public string UserName { get { return userName; } internal set { userName = value; } }
        public string Title { get; set; }

        public DateTime RequestDate { get { return requestDate; } internal set { requestDate = value; } }
        public virtual ICollection<OrderItem> OrderItems { get; set; }

        public string Status { get { return status; } internal set { status = value; } }

        public void Init(string user)
        {
            userName = user;
            requestDate = DateTime.Now;
            status = "PENDING";
        }

        public bool CanApprove()
        {
            if ("PENDING".Equals(status))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public void Approve()
        {
            if (CanApprove()) status = "APPROVED";
        }

        public void Reject()
        {
            if (CanApprove()) status = "REJECTED";
        }

    }