Asked by:
Have I built my model right?

Question
-
User-2004275369 posted
Hey
Now I am amateur developer keen on learning and I working on a project. But I think my model might wrong because its not mapping right in my view model. So I have a Customer and an Address, both are handled by a View Model. Both are populated on the main form. WShen I debug I can the address and customer are passed back to the controller, great! Issue is its complaining that a generic address object is missing. So I am assuming my model is wrong. Id welcome your thoughts.
public class Customer { [Key] [Required] [Display(Name = "Customer Id")] public int Id { get; set; } [Required] [Display(Name = "First Name")] public string FirstName { get; set; } [Required] [Display(Name = "Last Name")] public string LastName { get; set; } public IEnumerable<Car> Cars { get; set; } public IEnumerable<ContactDetail> ContactDetails { get; set; } [Required] public Address Address { get; set; } }
[Key] public int Id { get; set; } [Required] [Display(Name = "Address Line 1")] public string AddressLine1 { get; set; } [Required] [Display(Name = "Address Line 2")] public string AddressLine2 { get; set; } [Display(Name = "Address Line 3")] public string AddressLine3 { get; set; } [Display(Name = "Address Line 4")] public string AddressLine4 { get; set; } [Required] [Display(Name = "Post Code")] public string PostCode { get; set; }
[HttpPost] public IActionResult Manage(Customer_Create_ViewModel customerViewModel) { if (customerViewModel.Address.Id == 0) { _address.CreateNewAddress(customerViewModel.Address); _address.CommitChanges(); } else { _address.UpdateAddress(customerViewModel.Address); _address.CommitChanges(); } customerViewModel.Customer.Address = _address.FindAddress(customerViewModel.Address.Id); if (ModelState.IsValid) { if (customerViewModel.Customer.Id == 0) { _customer.CreateNewCustomer(customerViewModel.Customer); } else { _customer.UpdateCustomer(customerViewModel.Customer); } _customer.CommitChanges(); return RedirectToAction("Manage", "Customer", new { customer = customerViewModel.Customer }); } return View(); }
Monday, August 10, 2020 6:39 PM
All replies
-
User1120430333 posted
IMHO, a viewmodel doesn't need a [Key] attribute on a property. It doesn't seem that what you have is a viewmodel. It seems more like a persistence model used by the persistence framework aka Entity Framework. Are you using the persistence model as a viewmodel?
https://deviq.com/kinds-of-models/
https://www.dotnettricks.com/learn/mvc/understanding-viewmodel-in-aspnet-mvc
https://en.wikipedia.org/wiki/Persistence_framework
A viewmodel is strong typed to a view and is populated from a persistence model, and a viewmodel populates a persistence model for the persistence of data to a database.
Monday, August 10, 2020 7:41 PM -
User-2004275369 posted
This is my View Model
public class Customer_Create_ViewModel { public Customer Customer { get; set; } public Address Address { get; set; } }
Ultimately on this page I will have all aspects of the customer. Customer, Address, Contact Information and Cars
Monday, August 10, 2020 8:12 PM -
User1120430333 posted
This is my View Model
public class Customer_Create_ViewModel { public Customer Customer { get; set; } public Address Address { get; set; } }
Ultimately on this page I will have all aspects of the customer. Customer, Address, Contact Information and Cars
So what is populating the objects to be shown on the view? If EF is directly populating the objects and then they are being shown on the view, then you're not implementing a viewmodel to be used by a view.
The example solution is using VM(s) that are being populated by DM(s) aka Domain Model objects. The controllers are thin controllers and just about everything is happening in the Models folder as the controllers call on the DM objects. Basically on a FYI, the solution is implementing what is being talked about in the links, which is a layered style. The other one to look at is n-tier.
https://github.com/darnold924/PublishingCompany
Things you should consider for future projects a little push in the right direction.
https://www.c-sharpcorner.com/UploadFile/56fb14/understanding-separation-of-concern-and-Asp-Net-mvc/
https://docs.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/architectural-principles
https://en.wikipedia.org/wiki/Separation_of_concerns
https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ee658117(v=pandp.10)
<copied>
An MVC model contains all of your application logic that is not contained in a view or a controller. The model should contain all of your application business logic, validation logic, and database access logic. For example, if you are using the Microsoft Entity Framework to access your database, then you would create your Entity Framework classes (your .edmx file) in the Models folder.
A view should contain only logic related to generating the user interface. A controller should only contain the bare minimum of logic required to return the right view or redirect the user to another action (flow control). Everything else should be contained in the model.
In general, you should strive for fat models and skinny controllers. Your controller methods should contain only a few lines of code. If a controller action gets too fat, then you should consider moving the logic out to a new class in the Models folder.
<end>
Monday, August 10, 2020 8:55 PM -
User-474980206 posted
you should be cafe how you handle keys or read only fields if you send them to the client. as the user via browser tools can change any post back value, you need to be sure they are allowed access to the keys posted. you should encrypt them in the view if you need them to round trip.
on post back you should verify that the user has update access to the posted keys and only update columns values they are allowed to change.
remember the post back view will only contain bound data from form fields. Generally entities have columns that should not round trip. that is why it is better to use a view model which supports only bound data.
Monday, August 10, 2020 10:02 PM