0

Could you explain the interaction Models and ViewModels in the ASP.NET MVC?

  1. If I need to display data on the page, but not edit, whether to create a ViewModel to display or use the Model?

  2. I have two methods in the repository. One returns the Model and the other Model gets.In View I need to send the model. Should I convert the resulting Model to a ViewModel that would pass it to the View, and upon receipt of the submission to convert it back into the model to keep it?

For example I have a class model and class ViewModel.

 public class Item
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Price { get; set; }
}

public class EditItemItemViewModel
{
    public string Name { get; set; }
    public int Price { get; set; }
}

On the edit page, I clicked the edit item, and must get to the controller:

    [HttpGet]
    public ActionResult EditItem(int id)
    {
       //some code
        return View();
    }
  1. Where can I get the ID if I passed in the view ViewModel in which there was no ID?

  2. If I somehow got the ID, I need to do the following, which would save the model?

    [HttpPost]
    public ActionResult EditItem(EditItemItemViewModel ViewModel)
    {
    
       var Item = _dataManager.Items.GetItemById("1");
       Item.Name = ViewModel.Name;
       Item.Price = ViewModel.Price;
    
       _dataManager.Items.AddItem(Item);
    
        return View("Sucsess");
    }
    

Could you tell me how to work with Models and ViewModels?

3 Answers3

1

You can get the id a few different ways:

@Html.HiddenFor(m => m.Id)

This will include the property in the actual HTTP request.

Another option is to simply include the id as part of your route (this is what I usually do):

@Html.BeginForm("EditItem", "SomeController", new { Id = Model.Id }, FormMethod.Post) {
    ...
}

In both instances, make sure to validate that the user should be able to update the record that corresponds to that id! There's nothing stopping a user from tampering with the id and sending you a different value.

As for whether or not to display the database model or the view model, that's really up to you. I would always advocate building a view model and keep your database models out of the picture except for in your controller. The convention I use at work is for every database object that I need to send to users I will create a corresponding view model. So if I have a database object called Product I will build another class for the view called ProductModel.

An advantage of following that pattern is something I actually explained to another user earlier in regards to model binding.

Community
  • 1
  • 1
Justin Helgerson
  • 24,900
  • 17
  • 97
  • 124
0

Your posting your viewmodel, so i'm going to assume that you've referenced your model within the page

 @model MyNameSpace.EditItemItemViewModel

Is there a reason the id is not included in your view model? The easiest method would be to include that in the model and pass the instantiated model when creating the view.

[HttpGet]
public ActionResult EditItem(int id)
{
    var myViewModel = new EditItemItemViewModel() { Id = id }; 
    return View(myViewModel);
}

Like Justin said, it is easier to put it in a hidden field somewhere inside the @Html.BeginForm as the id should just be for reference.

[HttpPost]
public ActionResult EditItem(EditItemItemViewModel viewModel)
{
   var Item = _dataManager.Items.GetItemById(viewModel.Id);
   Item.Name = viewModel.Name;
   Item.Price = viewModel.Price;

   // Should this be an Add?
   _dataManager.Items.AddItem(Item);

    return View("Success");
}
Peter Lea
  • 1,731
  • 2
  • 15
  • 24
0

If I need to display data on the page, but not edit, whether to create a ViewModel to display or use the Model?

If it's very simple (like your example) and the properties map 1-1 like they do now. I would just use the Model as a view model, it's easier. Though if you want you could create a view model with the exact same properties and populate that and display it..it's a bit more work, but makes it so your domain models aren't necessarily tied to your views.

If you do that you may want to look into something like AutoMapper which would allow you to do something like

//simply copies the properties from one type to another
var viewModel = Mapper.Map<Item, EditItemItemViewModel>();

I have two methods in the repository. One returns the Model and the other Model gets.In View I need to send the model. Should I convert the resulting Model to a ViewModel that would pass it to the View, and upon receipt of the submission to convert it back into the model to keep it?

If you go the view model route then yes, you will end up doing a lot of converting between model and viewmodel, that's where something like AutoMapper can help out, or you can just create a couple extension methods that convert between the two types.

It looks like Justin Helgerson's answer explaining a way to handle models/viewmodels is pretty good.

Kyle Gobel
  • 5,530
  • 9
  • 45
  • 68