Caverman
Caverman

Reputation: 3739

MVC 5 creating new ViewModel not keeping property settings

I'm in the process of refactoring some code for a site and I'm trying to reduce repetitive code.

I setup a ViewModel and then made and override that would populate properties. When I debug I can step through and see that when the new object is created it will populate but as soon as it comes back to the controller there are no properties set. I thought I could populate properties like this any time I create a new object.

namespace VTC.Models.ViewModels
{
    public class VtcCommentViewModel
    {
        DataAccess DAL = new DataAccess();

        public string EmployeeName { get; set; }
        public string EmployeeNumber { get; set; }
        public string ReaderName { get; set; }
        public string Comment { get; set; }
        public string CommentStatus { get; set; }    
        public List<PunchList> PunchList { get; set; }


        public VtcCommentViewModel()
        { }

        public VtcCommentViewModel(Auth_Admin auth)
        {
            ValidETMResult validEtm = DAL.ValidateETM(auth.CurrentUser, auth.CurrentIP);

            VtcCommentViewModel vm = new VtcCommentViewModel();
            vm.EmployeeName = validEtm.emp_name;
            vm.EmployeeNumber = auth.CurrentUser;
            vm.ReaderName = validEtm.rdr_name;
            vm.PunchList = DAL.GetPunchList(auth.CurrentUser);
        }

    }
}

Here is my controller. When I debug through the creation of the new ViewModel I can see it populate the properties but when I look at the View(vm) then the vm is empty.

public ActionResult Comments()
{
    VtcCommentViewModel vm = new VtcCommentViewModel(auth);
    SetPageTitle("Enter Exception Log Comments");

    return View(vm);
}

UPDATE

Not sure if this would be good design or not but I moved the populating of the properties from the ViewModel constructor to a function in the controller.

This is what I have in my controller now and it seems to work.

public ActionResult Comments()
{
    VtcCommentViewModel vm = populateCommentVM(auth);
    SetPageTitle("Enter Exception Log Comments");

    return View(vm);
}

private VtcCommentViewModel populateCommentVM(Auth_Admin auth)
{
    ValidETMResult validEtm = DAL.ValidateETM(auth.CurrentUser, auth.CurrentIP);

    VtcCommentViewModel vm = new VtcCommentViewModel();
    vm.EmployeeName = validEtm.emp_name;
    vm.EmployeeNumber = auth.CurrentUser;
    vm.ReaderName = validEtm.rdr_name;
    vm.Comment = string.Empty;
    vm.PunchList = DAL.GetPunchList(auth.CurrentUser);

    return vm;
}

Upvotes: 0

Views: 80

Answers (3)

maciejgos
maciejgos

Reputation: 103

Maybe worth to consider is to usage of Factory Method Pattern or Builder Pattern. Additional as others already tell VM should not know about DAL Separation of concern.

Upvotes: 0

Jorge Rojas
Jorge Rojas

Reputation: 485

Besides including DAL access in your vm, you have some flaws on the constructor:

        ValidETMResult validEtm = DAL.ValidateETM(auth.CurrentUser, auth.CurrentIP);

        // Wrong! You are creating a new instance which dies when you left the constructor!
        VtcCommentViewModel vm = new VtcCommentViewModel();
        vm.EmployeeName = validEtm.emp_name;
        vm.EmployeeNumber = auth.CurrentUser;
        vm.ReaderName = validEtm.rdr_name;
        vm.PunchList = DAL.GetPunchList(auth.CurrentUser);

Fix:

        ValidETMResult validEtm = DAL.ValidateETM(auth.CurrentUser, auth.CurrentIP);

        // Wrong! You are creating a new instance which dies before you exit the constructor!
        // Nop VtcCommentViewModel vm = new VtcCommentViewModel();
        this.EmployeeName = validEtm.emp_name;
        this.EmployeeNumber = auth.CurrentUser;
        this.ReaderName = validEtm.rdr_name;
        this.PunchList = DAL.GetPunchList(auth.CurrentUser);

Try to get a helper class which loads your data into your viewmodel.

Upvotes: 0

Dawood Awan
Dawood Awan

Reputation: 7348

You creating a new object VtcCommentViewModel inside your constructor, and assigning the properties to that new object

    public VtcCommentViewModel(Auth_Admin auth)
    {
        ValidETMResult validEtm = DAL.ValidateETM(auth.CurrentUser, auth.CurrentIP);

        VtcCommentViewModel vm = new VtcCommentViewModel();
// here you are creating a new object - WRONG!
        vm.EmployeeName = validEtm.emp_name;
        vm.EmployeeNumber = auth.CurrentUser;
        vm.ReaderName = validEtm.rdr_name;
        vm.PunchList = DAL.GetPunchList(auth.CurrentUser);
    }

Should be this

    public VtcCommentViewModel(Auth_Admin auth)
    {
        ValidETMResult validEtm = DAL.ValidateETM(auth.CurrentUser, auth.CurrentIP);

        // assign values to property of the object you are creating - not a new object
        EmployeeName = validEtm.emp_name;
        EmployeeNumber = auth.CurrentUser;
        ReaderName = validEtm.rdr_name;
        PunchList = DAL.GetPunchList(auth.CurrentUser);
    }

Note: Your View Model should not Know about your DAL - seems like some bad architecture

Upvotes: 2

Related Questions