Say I have a domain level "Person" class that contains a lot of properties(FirstName, LastName, Age, Address, Telephone, EmailAddress, etc). For the purposes of a view, I only need to pass the Age property. The smaller, the better as the collection is being passed to the client as a JSON string.
What is the best way of managing this?
1) Do I create an anonymous type collection and pass that to the view?
2) Do I create a new "ViewModelPerson" type that only contains the "Age" property.
3) Do I create a new domain "Person" super type and have my Person and ViewModelPerson derive from it (seems a convoluted way of doing things).
Then, whats the best way of persisting these details onto my server (ie passing the age value into a collection of Domain Person objects?
EDIT:
Apologies, I should have said that I'd be returning a collection of Person objects (each with just an Age property).
1) I do not think that is possible, please elaborate
2) Yes! I would call it PersonAgeViewModel though.
3) Very convoluted indeed unless you know that you will derive from Person a lot and are planning to implement TPH or TBT in the database anyway.
If you're interested in only sending the Age (a single age) then don't specify a Model in the view at all. Add the value of the age to the ViewBag.
Check out Hajan's Blog Entry.
Call me pedantic, but I would lean towards creating a ViewModel with a single age property. I'm not sure the ViewBag approach would work unless you're building the JSON in a view. Typically when we return JSON we just use
return Json(model);
I would definitely recommend against a common base type between domain and view models.
Related
After working with MVC for a long time, I decided to go with MVVM. I understood the basics of the pattern and got through multiple articles that explain that MVVM is waaay better then MVC any day. And I am okay with that.
I decided to make my own app in order to set my mind correctly for logic behind MVVM. So I created basic app that does follow MVVM principles and after a while I found the problem that you see in the title.
So, basically, this is the problem. Let's say that I have one object, call it Person. Person have name and surname. But when I want to show details about that person, I will have address, phone numer etc. Because one person can have many phone numbers I will have something from API that link to the user ID.
So we came to my question. If I have some basic information about some model, and want to have detail information about that same model, where do I keep ID (or link) for that detail information? Do I have to keep it inside view controller, which would be just wrong? Or do I keep it inside view model, even if I don't use it really on user interface?
The ID also belongs to the model class. ie If you have an object Person then simply create a data class Person, which will obviously include all the members say ID, Name, Address, Number and so on. You can identify each person using the same ID as well.
The View Model need not always know about the ID. If you have a list of Person objects in view model, then you could easily map each item using the ID. Additionally if you want to have currently selected item or something, you could map it to viewmodel property of that object type ie Person. So you need not keep a PersonID field in ViewModel unless it is absolutely required for some rare cases.
Sorry, but I did not understand this : So basically in prepareForSegue method I could say something like give me from current VM object at particular index and create VM for new view that I will actually send ?
As far as simple applications are concerned, the above approach is more than enough. But in some rare cases, you may need to keep the current selected item's ID in the view model. So if you're using a list and keeping a property for selected item, it may not be the type of that list ie Person. Instead it could be the ID alone.
Hope you got the point.
We have identified a Location entity in a database as a value object in our domain (DDD). Locations are used by other domain objects, but don't really "stand alone" -- they always belong to another entity.
Now we are trying to edit a list of these values in a simple MVC web application. So the view would show a list of locations in a view model LocationViewModel.
However, the value object is by definition immutable, yet does hold a reference to another entity (Business).
Domain:
public class Location : ValueObject<Location>
{
readonly locationId;
public int LocationId {get{return _locationId;}}
public Business Business {get;set;}
}
My problem is understanding how you can simply edit a bunch of value objects in a UI and change, e.g. what Business the location belongs to.
A value object is not supposed to have an "identity", but it does need an ID so the repository can update the database.
I also don't think you can make Location an entity just because you want to edit it in the UI. Or is Location, in this scenario indeed an Entity?
What am I not understanding?
Thank you!
It's a classic problem. In one context it's an entity and in another a value object. I found the example of a telephone number helpful to understanding this sort of problem.
In a CRM for example, a telephone number is a value object. The same one can be associated with multiple contacts. It varies by value (key concept here). So in this context it's a value object. In this example, I could store telephone numbers in the database and the 'ID' would be the telephone number itself. If the value object was made up of multiple parts then they would form a composite key.
If however we looked at a telephone number at a telephone company. That would most likely be an Entity. It could have all manor of information attached to it. All that info would vary by ID (which in this case would be the number).
In your case, Location sounds like a value object. If you need to save it in a database as a thing rather than just as part of an entity then use it's parts as a composite key. You will need to handle what happens when you 'change' one as it's not a change but the creation of new value object. One approach is to remove the old and insert the new. Or just keep all versions. It depends on your domain.
Hope that's helpful.
You don't change a value object. You create a new one with different values. If the value object has few properties that you want often to change, some helper methods are usefull. myObject.WithX(4711) will create a new instance with all properties the same as myObject but the X Property changed to 4711 for example.
To "edit" a value object in an UI you use a viewmodel. The Viewmodel is not a value object (and no entity by the way) and is not part of your domain. It's purely in the Presentation Layer. It is editable and mutable. It could have a constructor, taking your (immutable) value object to copy its values from and it could have a ToXXX Method to create a new (immutable) value object with its current (and changed) values.
If you want to store your value objects in a separate table (instead of roll out the fields in the table that stores the owning entity) this is purely data access layer related and not part of your domain model. This could be done by mapping. In the value object the database id is immutable and has no meaning in the domain model.
I have been reading a lot about the importance of keeping layers separately and the concepts are mind blowing :) . However,I looked into many places to find a practical example on how to separate these three types of models and had no luck. How do I connect them together in a practical situation? Here are few questions I have
My understanding is that persistence models contain the POCOs that we use to create entities , domain models contain the business logic and view models are used to expose relevant data. Am I correct?
If I am correct , how do I actually connect these different layers in a single solution. I mean at the end of the day , they are classes and how do I connect domain class(model) with a relevant persistence (model) and the view model?
Can someone please point me to a great tutorial that teaches how to build n-tire asp.net applications?
If not, and if possible can someone tell me how to build and connect three types of models for the following scenario.
A Customer has a Name , DOB , Address and a collection of Orders
An Order has a Customer, Date , Price and a Description
How do I create separate persistence, domain and view models(eg: A view model to display all information about customer except DOB and all orders related to the customer )
More importantly how do I connect them?
Thanks heaps!
Cheers!
you create viewmodels to match the view, not every property from the model (Entity) you might want to show in the Create/Edit view, or you want to show it but combined or in a different way, that's why you need viewmodels, usually you would have a property in the viewmodel for each editor/input in the view
for example in the Entity you can have one DateTime property but in the ViewModel 2 properties one for Date and one for Time,
or in the Entity you will have property of type Country but in the ViewModel of type int (the value of the id)
and when you have this separation you need to map Entities to ViewModels and the other way around
for demo app you can look here: http://prodinner.codeplex.com/
I have this problem of confusing when to include the entire object as a property of another object, or just its ID. It seems that if I include the entire object, the calls to load the containing object will unnecessarily also load the included object when I probably only need references. What is propert approach?
Generally always refer to another object.
Many ORM technologies have the idea of "proxies" and "lazy loading", meaning, unless you reference the object, it won't load it.
I prefer to include the object itself, since one object actually has a relationship with another actual object -- the object ID is just an implementation detail. To deal with the problem of unnecessary calls, look into "lazy loading".
Only include the other object if you need the details.
in MVC use a ViewModel ideally and not your entities. Your ViewModel contains only what it needs, so for example OrderEditViewModel would contain a customerid unless you want to display the custom name, in that case you would include the fields from customer. Some people recomend you flatten out your objects to a view model, so you dont have OrderEditViewModel.Customer.CustomerId but instead ORderEditViewModel.CustomerId. Automapper can help you do this (As well as valueinjecter - note the spelling)
If you must include an ID ensure when you save back to the database your update include a clause to say 'where id=#customerId and (logic here to ensure your user actually has access to that customerid and root object)
I have mvcsecurity.codeplex.com to help encrypt record ids on a web page to prevent against tampering as well (it helps but you should still have something in your query to prevent field tampering so an attacker cant add someone else's customer id for example_)
I go more into parameter tampering in MVC here if anyone is interested:
http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=hack-proofing-dotnet-app
My suggestion would be to always think about the design and not about performance. Performance can be tweaked but design can't. So, if the two objects have that kind of a relationship where Aggregation/Composition is required, you should do that.
But, if your containing object only has to deal with the ID (for e.g. passing it to a different object which processes the ID to do something) then you can keep the ID field only. No need to expose the whole object (but make sure that your containing object does not need to know anything about the other object.).
Lets say I have a view that accepts a Person object.
Has three properties, FirstName, LastName, Age
Now lets say I add another textbox field that's not part of the object.
I don't need the value of the textbox, its just populated with data that's for the user.
When you edit the fields and post the Person to the controller, lets assume there is a validation problem so you return the Person object back with Errors
The problem is now the additional textbox has lost it's value since its not part of the model.
So I made a ViewModel with a string property for that field and a Person property to keep all the values. Seems like there would be a better way to keep the value in the "special" textbox?
You should be able to get that extra field from the posted fields. How do you set it first time, through the ViewBag? You should be able to set it again.
But what exactly is wrong with using a ViewModel? Sooner or later you will have 2 or 3 extra fields, or a Person and an Appointment.
I think that's totally the right way to do it. The viewmodel is the model for the view not the model for your non-UI processing, it contains a Person and extra viewable information. It fits exactly with the concept. Your Person is presumably a (non-view) model and therefore when you have a valid post back, you get the Person to save it's data (or whatever) and the extra viewable information is irrelevant at that point, because you are no longer in a 'View/UI' part of your app.
Make the view strongly typed to your viewmodel and access the Person within it
#model myViewModel
#Model.Person.FirstName
#Model.OtherViewOnlyValue
Go with the viewmodel, so much cleaner than ViewBags/Session/ViewData etc.
There are many times that you might think that you do not need to include a UI mapping to a ViewModel but most of the time you will end up adding the mapping into the ViewModel. I believe that ViewModel should represent everything on your UI screen. Since HTTP is stateless the post form values will play an important role in populating the user interface controls.