locked
Correctly using a view model RRS feed

  • Question

  • User1352447851 posted

    I am trying to use a view model so I am not exposing the model which is modifying the database. In the below code, UserObject is the model with private values that updates the database. UserView is a reduced model which I want to use to display a list on my razor page.

    public class UserViewModel
    {

    public UserViewModel()
    {

    }

    public UserViewModel(UserObject userobject)
    {
        DisplayName = userobject.DisplayName;

    }

    [Required]
    public string DisplayName { get; set;}
    }

    My PageModel:

    private readonly MyContext _context;

    public MyModel(MyContext context)
    {
    _context = context;

    }

    public IList<UserObject> UserObject { get;set; }

    public IList<UserViewModel> UserViewModel { get; set; }

    public async Task OnGetAsync()
    {
        UserObject = await _context.UserObject.Where(x => x.Name == "Bob").ToListAsync(); //needs changing to return IList<UserViewModel>

    Can anyone confirm that this is the correct use of a ViewModel?

    What syntax is best for convert my UserObjects into UserViewModels in the async list? I can only think to do a long for loop. 

    Wednesday, February 20, 2019 1:25 PM

Answers

All replies

  • User475983607 posted

    Can anyone confirm that this is the correct use of a ViewModel?

    ASP.NET Core Razor pages have a built in model.  It's called the PageModel.  I recommend using the PageModel first rather than building a ViewModel.  There can be times when a ViewModel is needed.

    Razor pages solve a particular MVC design redundancy.  In MVC you always end up with a GET and POST action with the same name and at least one ViewModel.  Often there are two ViewModels; one populates the UI, the other is submitted to a POST action.  Razor Page combines these several code bits into one Razor Page.

    The following site is very informative and I recommend that bookmark it; https://www.learnrazorpages.com/

    The PageModel is described at the following link; https://www.learnrazorpages.com/razor-pages/pagemodel

    Wednesday, February 20, 2019 2:39 PM
  • User1352447851 posted

    I'm sorry, I don't really understand your answer.

    I have a page model (as above), a data model, and I want to add a view model to populate the UI.

    I needed to do this perviously on another page as I was submitting a form and as I was originally only using a data model (UserObject). Model.IsValid failed because the client didn't fully populate it all its properties. I created a view model just to handle the form and used my data model to submit to the database:

    if (!ModelState.IsValid)
    {
    return Page();
    }

    UserObject userobject = new UserObject(UserFormViewModel, "bob"); //this sets some other values in its constructor

    _context.UserObject.Add(userobject);
    await _context.SaveChangesAsync();

    Where UserObject is my data model and UserFormViewModel is my ViewModel.

    After looking into that I read that a separate View Model should also be created for sending elements to the UI as well, so as not to expose the complete data model.

    Wednesday, February 20, 2019 2:59 PM
  • User475983607 posted

    I think you are looking for a projection query.

    List<UserViewModel> userVm = await _context.UserObject.Where(x => x.Name == "Bob").Select(vm => new UserViewModel() {
    	DisplayName = vm.Field<string>("DisplayName")
    }).ToListAsync(); 

    Or

    UserViewModel userVm = await _context.UserObject.Where(x => x.Name == "Bob").Select(vm => new UserViewModel() {
    	DisplayName = vm.Field<string>("DisplayName")
    }).FirstOrDefaultAsync(); 

    https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/method-based-query-syntax-examples-projection

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, February 20, 2019 3:50 PM
  • User1352447851 posted

    Awesome, Thanks

    Wednesday, February 20, 2019 4:14 PM