Answered by:
Correctly using a view model

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 returnIList<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
-
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();
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, February 20, 2019 3:50 PM
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();
- 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