I am developing a Web-App using ASP.NET MVC and I've been trying to avoid using the ViewBag, therefore I created few viewmodels to populate my drop-downs and in general to pass the data I need in my views. At the same time I would like to keep the data binding clean and avoid properties that will not be bound to (without using include/exclude attributes) and I've been told that obviously returnmodels are great for that purpose.
So is creating two independent models for one view a bad idea? One with all the data that needs to be displayed and another one only with the fields from my form or is this an excess of form over substance and should I reconsider changing my design?
Edit: A quick example because I'm not too good at explaining
class ViewModelA{ // passed to the view and then bound to when form is submitted
List<KeyValuePair<int, string>> DropDownValues; // will be always empty while databinding
int SelectedValue; // will be always 0 when passed to the view
...
}
Should I replace ViewModelA with
class ViewModelB{ // contains data passed to the view
List<KeyValuePair<int, string>> DropDownValues;
...
}
class ReturnModel{ // contains data returned from the view
int SelectedValue;
...
}
Obviously here I could just bind directly to my model but let's assume it's more complex and the data has to be processed before saved.
I think I know what you are asking. You are saying you have a viewmodel with, lets say, these properties: Age, Name, CountryOfResidence (for dropdown), and a few more properties. But when you create a new person, you only post Age, Name, IdOfCountry to controller.
So your question is what is the point of posting the whole viewmodel, when it is not needed. Fair question.
There are many ways you can do this. Here is one way:
Create a base class with common properties (for posting)
Create a derived class with more properties for the view.
Some people will refer to 1 as Data Transfer Object (DTO). These DTO's will be shared for communication between presentation layer, service layer, business layer, data access layer etc.
Related
I am struggling to implement MVVM pattern in my current project.
"ClassA" continuously gets required data from a remote device and stores this data inside it's fields. It is a model, I guess. ClassA updates required information via Update method.
"ClassB" continuously gets the data from "ClassA" and stores it in corresponding properties. Looks like it is a view model.
View is a simple MainWindow.xaml with a DataGrid inside.
I have the following questions:
1) How do I update ViewModel?
Should ClassB have an Update method, which accepts an instance of ClassA and updates corresponding fields?
2) Where do I store an instance of ClassA?
Should ClassA be a field of ClassB? If it should, then how do I update Model?
I thought of something like the following:
public void UpdateB()
{
ClassA.UpdateA();
this.FieldOne = ClassA.FieldOne;
this.FieldTwo = ClassA.FieldTwo;
}
4) Does model have it's update method at all or model just stores the data?
3) What do I do inside MainWindow.cs, aside from windows initialization? Do I update view model (ClassB) there?
I find it best to have a object representing an item in each layer of abstraction. This includes the form of the data as it exists on the disk. Remember that in MVVM, the only real goal is to promote loose coupling between the interface(User Interface) and the implementation(ViewModel functionality).
For example, if I have objects stored in XML files, I will have an object in my data access layer that exists only for the proper management of the XML data. Let's call it ObjectXml. This object only contains data in the form that is native to the data on the disk. In this case, all data has a string representation, as in the XML files.
In the model layer, you will have the data representation of the XML file in the expected data types. Let's call this Object. The property getters and setters may access and set the string representation of the data by performing conversions in both directions. This way, the data is ready to be persisted to the data source(xml file, database etc.).
In ObjectViewModel, properties may access those in Object. The viewmodel contains all the members for representing and modifying the model.
Note that ObjectXml is really only beneficial when you are only allowed to store string information, or when a suitable schema does not exist for your data types.
At the end, you have a hierarchy of containment such as the one below:
public class ObjectXml
{
[XmlArray("People"), XmlArrayItem("Person")]
public List<PersonXml> People { get; set; }
//PersonXml is an xml data model similar to this one
[XmlElement("Item")]
public string Items { get; set; }
}
Here is the model for the Xml object:
public class Object
{
private ObjectXml _xmlContext;
public Object(ObjectXml xmlContext)
{
this._xmlContext = xmlContext;
}
public List<Person> People
{
get
{
//Person requires a constructor that takes a PersonXml object in order for this to work properly
return this._xmlContext.People.Select(x => new Person(x)).ToList();
}
set
{
this._xmlContext.People = value.Select(x => new PersonXml(x)).ToList();
}
}
public double Item
{
get { return double.Parse(this._xmlContext.Item); }
set { this._xmlContext.Item = value.ToString(); }
}
}
Obviously, it's not wise to name your class Object as it's a reserved word in C#. Hopefully I've given you some ideas of how to access and update data in a robust and extensible manner.
In short, you don't need an update method at all. Also, short of constants and property backing fields, there are very few reasons to need direct field access in C# MVVM.
See below. Do not listen to people that say the ViewModel and Model need to be decoupled. The main purpose of the model is an intermediary layer that prepares data to be saved or loaded into the program and to store data in a way that is agnostic to both the data and the program functionality(ViewModel)
You do not need an update method. Use properties that access the data model and persist to the data storage(xml, database etc.) if needed.
You do not need an update method.
You should not have to do anything inside of ViewModel.cs. Only code that modifies the view should be in the codebehind. The only ViewModel you should ever access in a view is one that follows the form of MainWindowViewModel, which is more like an ApplicationViewModel that carries instances of other required viewmodels.
Finally, don't get stuck using an overcomplicated MVVM "framework" as most of the functionality is not useful or necessary.
Like stated in Yuris comment, you should not use any update method, but rather implement the INotifyPropertyChanged interface. Like the name says this notifies all subscribers when the value of a certain Property changed.
This is a nice article which contains code to a minimalistic MVVM implementation. If you have trouble implementing the pattern from scratch, try to start with this example and replace the existing classes with your own one-by-one.
As to the update mechanic inside your MainWindow.cs - you don't need any, if you specify the DataBinding in your xaml code like it is done in the example linked above.
I hope this helps you getting started!
Just to make it clear, my question is how do you CREATE multiple objects using a single view. My ViewModel works fine, I can display multiple objects no problem.
Its been a while between .NET coding (last time I was coding in 2.0). I have created an MVC 4 project and successfully created a ViewModel (displaying data on a single view from multiple objects).
However, I cheated. I populated the database directly. I now face the question in reverse, what is the best practice for creating multiple objects from a single view?
In my example, I have a User, who has a userId. The userId is a foreign key in UserDetails.
Just trying to get back into the swing of it and wondering what you guys do?
There are 6 ways to pass multiple object in MVC
ViewModel
Partial View
ViewBag
ViewData
TempData
Tuple
Each one have there own pros and cons.you have to decide base on your issue in hand.
For more information you can refer code project article on it: How to Choose the Best Way to Pass Multiple Models in ASP.NET MVC
Let me give advantage and disadvantage of View Model
ViewModel :
Advantages
ViewModel allows us to render multiple model types in a View as a
single model.
Great intellisense support and compile time error checking on View
page.
ViewModel is good for security purpose also as Views have only what
they exactly need. Core domain models are not exposed to user.
If there is any change in core domain model, you do not need to
change anywhere in View code, just you need to modify corresponding
ViewModel.
Disadvantages
ViewModels add another layer between Models and Views so it increases
the complexity a little bit. So for small and demo applications, we
can use tuple or other ways to keep the things simple for demo.
Option 1:
The best approach is to use strongly typed views with Model or ViewModel.
For Example, you have two classes User and Education, you want to display all education details of user in a view, you can create a custom view model and pass it to view, where you view is strongly typed view model:
public class User
{
public int UserId {get;set;}
public string UserName {get;set}
-------
------
}
public class Education
{
public int UserId {get;set;}
public int DegreeId {get;set;}
public long Marks {get;set;}
---------------
--------------
}
Now create a view Model like this:
public class EducationViewModel
{
public User user {get;set;}
public List<Education> educationList {get;set;}
}
now pass the ViewModel to View and do this in View:
#model AppNameSpace.ViewModels.EducationViewModel
Tip: Create a folder named ViewModels and put all the viewmodel classes in it.
Option2:
Option 2 is to user ViewBag and pass multiple object from control to your view, ViewBag is accessible when you set some value in it in controller, you can access in the view of that action, after that it is automatically washed out, and its null if you access again it.
you can use ViewBag like this:
ViewBag.Message = "Using ViewBag";
and read value like this in View:
string Message = ViewBag.Message as string;
Option 3:
Option 3 is to store data in TempData, its once read only, means you set value in it, and when you read it, its automatically removed, TempData internally uses Session Variables.You can use TempData like this:
TempData["Key"] = "value";
now you read it in view:
string val = TempData["Key"] as string;
after reading it, it will be automatically removed, but you can keep it if you need it further like this:
TempData.Keep("Key");
I've always heard that you should separate GUI/Data/Logic components, like the MVC pattern.
So, I am wondering: In a GUI application, where do you actually store the data?
Here is an example (using C# terminology):
Suppose you have a GUI that takes user input, does some analysis, and displays results in a table. The user can have several analyses in one window, so there is a ListView at the bottom that allows the user to select which analysis is currently displayed (the selected item gets displayed).
In order to display this, the analysis data must be stored somewhere. I have always done one of two things:
Put all the data into a single object and store it in the ListViewItem's "Tag" property
Extend "ListViewItem" and just add whatever properties I need.
But, this means I am storing the data inside of the ListViewItem.
Is there a more appropriate place to keep track of the data?
I could add it as private members to the main form, but that seems like the same thing.
The only other thing I can think of is to make some global class that I can reference whenver I need to.
Thanks.
As I understand, you have some ListViewItems. Each ListViewItem is associated with your business logic object and after select one of ListViewItem you want make some operations over this buisness object. In similar situations I usually make Data Object like
struct MyDataObject
{
string Id;//very often data object need to have Identifcator, but not always
//some fields
}
and add to data object constructors for typical user input.
After that I make business logic layer contains available algorithms for this data objects. For simple projects, this is a static class like
static class MyDataObjectOperationService{
void MakeSomething(MyDataObject myDataObject);
object GetSomething(MyDataObject myDataObject);
...
}
For big projects that is usually interface. Also I usually make a data layer interface for getting this data object. For example
interface IMyDataObjectRepository{
IList<MyDataObject> GetAll();
MyDataObject GetById(string id);
//CRUD operations if it need
}
After that I put into ListViewItems ids of Data Objects and on ListViewItemClick getting selecting id, after that getting DataObject by Id using data layer classes and make some operations using business logic layer classes. If I need to save DataObject changes or create new DataObject I using data layer classes.
I am wondering is it good practice to try to make a view that takes in a generic view model?
I am wondering this because someone mentioned that he was anticipating to have to do lots of duplicate code unless he started to make a generic view and generic view model.
So basically the views would be like just a set of controls. One view might have 2 controls(say a text-box and radio button) another view might have 50 controls on it.
They will all have the same look and feel(it just grows by number of controls) . Basically he was thinking having a view model takes in the object(domain object) looks at it and see's 50 fields and renders the right control types.
I guess a edit template could be used to figure out the controls however I am just not sold on a generic view model.
I like generics and they can do very powerful things and in some situations they are good but I am just not overall to crazy about them and try to not use.
I find most of the time it may reduce duplicate code but sometimes it makes the code alot more complicated. Of course this could just because I am still a relatively new to programming and it could be still above my skill level.
The next problem I have with it is I think that view models should be as flat as possible and only expose data that is actually going to be used so people don't start using properties that should never been in the view in the first place.
The next problem I have with it that it could just keep going if you have some complex object that has objects in it that has objects in it. It could go for a long long time.
Personally I avoid using generics in view models. I agree with most of the reasons you mentioned against them and particularly this one:
The next problem I have with it is I
think that view models should be as
flat as possible and only expose data
that is actually going to be used so
people don't start using properties
that should never been in the view in
the first place
The idea behind view models is that they need to be specifically tied to the requirements of a given view, not making them general (/generic) as your domain models are. I prefer duplicating code in view models compared to having some generic monster reused all over the views and partials.
And even in cases where you need to generate dynamic forms and controls you don't need to use generic view models.
So, unless you have some hyper specific scenario (can't think of any at the moment), it's probably a good thing to avoid generics in view models.
This being said, don't rule them out completely, if you feel that there is a situation in which generic view models could be useful don't hesitate to present it here, by explaining the scenario and showing all the code so that we can discuss it.
I don't see anything wrong with generic ViewModels. It is a good way to remove duplication and keep compile-time checks, as opposed to ViewBag.
Example:
Imagine you have a set of Model classes for Product, Category, etc.
Each class (ProductModel, CategoryModel) has an associated display and editor template, which generates appropriate view.
Now you want to construct a set of pages for view and edit.
I usually create a Layout (Master page in web forms) to render the common content (header, footer, menu, etc.)
Then I would create individual, strongly-typed views that accept as model ProductViewModel, CategoryViewModel, etc.
Now we need to define those view model classes. Each view model class should take an instance of ProductModel, CategoryModel, etc (which will be passed to the template). But the layout often requires some additional data (ie. selected menu, logged-in user name, etc). My solution is to create a generic ViewModel that encapsulates this duplicate data for the Layout:
public class EntityViewModel<T>
where T : EntityModel
{
public T Entity { get; set; }
public string UserName { get; set; }
public string SelectedMenu { get; set; }
}
Then you can easily create a ProductViewModel : EntityViewModel<ProductModel>, which contains everything the Layout need to render the page, and you can add there any additional, product-specific data.
As far as ViewModels go, I typically have all of my ViewModels inherit from a BaseViewModel that exposes methods that aid in implementing MVVM. If you'd like to see an example, just comment below.
I really do not like puting business logic inside viewmodel. I think that besides regular properties and error handling inside constructor nothing should be in view model. It makes much cleaner code, and you can more freely make additions to view model.
If you have to much duplicated code you can isolate it to separate viewmodel and then nest it where you need it.
This way you also have only what you need on your view.
This question is a follow-up of this older one, and it's more of a confirmation than an open question.
My ViewModel instance has a private instance of the Model, _modelInst.
The ViewModel has exclusive access to the Model's data during editing (so the Model doesn't need to implement INotifyPropertyChanged).
Now there are three ways I came up with how to edit the Model data from the View:
Getting/setting directly on the Model instance
e.g. for simple value fields
return _modelInst.fieldname;
_modelInst.fieldname = value;
This one's easy to implement...
Creating a ViewModel instance and operating on the parent's data structure
e.g. for more complex object types like structs:
Creating a new ViewModel for that type.
The ViewModel knows the parent and its fieldname.
displaying that in a ContentControl+DataTemplate
getting / setting:
via methods of the parent with the fieldname as parameter,
overwriting the whole original object even if only one field is changed
This means creating a new interface (with update routines working on _modelInst), implemented by the parent, for each of these structures.
Creating ViewModel instances with no direct knowledge of the parent's data structure
e.g. for (lists of) classes within parent classes
Creating a new ViewModel for each class
Sending update instructions to the parent via
commands
messages
reflection (parent knows which child called the function
by comparing the instance to all stored children)
All of these are a big mess implementing, creating functions for
every field of the model that is editable.
Which means pretty much all fields of the model...
(4.) One could create a generic ViewModel which works via reflection alone, where each
subobject knows its parent and its fieldname (+index, if in a list).
Only the root's logic would then interfere with the model.
But that solution would also require a means to store the path to a field within _modelInst.
Is there any other (more simple) way to achieve this?
Did I misunderstand the principles of MVVM (again)?
Is MVVM suited for manipulation of large hierarchical data structures?
Hopefully these resources will help; they helped me quite a bit as I learned MVVM and how to approach representing object graphs/hierarchies with view models:
Editable Object Adapter
Editable Collection Adapter
MicroModels
This is an excellent question for which I do not feel there is a good answer that comes stock with the MVC pattern.
ViewModels work great when the model they map to has no children.
But when the model has children, as in
Customer
-->Order
-->Country
(imagining Country were a child object of Customer) the design pattern kind of breaks down.
The best thing I've found is to use inheritance and selectively expose
only those children for which you need viewmodel logic. Otherwise, just access
the model's properties of the view that will come in via inheritance.
public class CustomerView : Customer //inherits from Customer (model)
{
public CustomerView(Customer customer)
{
this.FirstName = customer.FirstName
//etc..
//Only if you need it, that is if you have some display-specific
//logic relating to country for a given view, you create
//a CountryView class that inherits from Country and gets populated
//by an instance of it as well
this.CountryView = new CountryView(customer.Country)
}
public CountryView CountryView {get;set;} //sadly you cannot override Country but you may be able to shadow it.
public string DisplayColor
{
if(base.FirstName == "Joe")
{
return "red";
}
return "";
}
}
This gets messy when dealing with grandchildren. If anyone has a better solution, I would love to hear it.
Thanks