I'm trying to learn ASPNET MVC. I've built a DbModel starting from DB structure so, under Models, I have the .edmx file that can be used to access data.
I've read that it could be good to have ViewModels classes to act between the View and the Model (useful also for single fields formatting) but I don't' understand if this is right and in which way it's better to build them. If they reproduce classes in my model I believe it is a little bit redundant, isn't it? If this is the right way, is there a way to generate automatically ViewModel classes?
A ViewModel in MVC is a model of your view. It is a property bag containing, usually of primitive types. It may seem redundant, but you are protecting yourself from future problems by decoupling your code.
As an example, given a Person object in your domain model:
public class Person
{
public string FirstName {get; set;} // John
public string LastName {get; set;} // Doe
public DateTime Birthdate {get; set;} // 01/01/1965
}
In your view, you may want to represent this in a view as a full name, age and birthday. Your ViewModel would be similar to:
public class PersonViewModel
{
public string FullName {get; set;} // John Doe
public int Age {get; set;} // 46
public int Birthday {get; set;} // January 1
}
Somewhere in your pipeline, you need to convert from domain model to the viewmodel. I have used either projection queries from the persistence layer or object-to-object mapping frameworks, such as AutoMapper.
By structuring your data this way, you can keep logic and formatting rules out of your view markup. By using a framework, such as AutoMapper, you can also standardize string formatting of dates and times, and do convention-based mappings.
Also, I generally advise having one ViewModel per View. If you need to share View/ViewModel structures or apply conditional view information, those should be separated into partial views.
If you are just starting out I would avoid trying to incorporate every best practice you can find into your early applications. It becomes very easy to try and do everything everyone says is the best practice and you lose track of just learning the fundamentals.
View Models are obviously a great way of seperating the presentation layer and the domain layer, but they serve other purposes. If you are just starting out and your applications are not terribly complicated, I would recommend keeping it simple and use your domain classes as your view model where your views are simple. This will allow you to focus more on the application.
Also, by doing this you will come across views where the simple domain model will not cut it and you will find yourself needing a ViewModel. Which will allow you to incorporate the more specific information you need for your view page (such as multiple domain objects).
By practicing without using View Models for everything, you can gain an appreciation for their benefits and decide what works best for you and your code.
A "view model" (model for a view rather than domain model) helps you separate the domain model from what is bound to the page. Is it always necessary? No, but it is useful if you have some common data shapes used on multiple views where the view will also have some additional data. Another good use is removing certain data from certain types of views (your customer should not know your margin, but your management should?). IT is not mandatory.
Related
I use Entity Framework 6 , code first approach, together with asp.net mvc 5.
the razor views are all strongly typed, and most of them use viewmodels that contain DAL models. Some views use models directly from the DAL. I am wondering what kind of security risks this. Let me demonstrate:
public class SomeViewModel {
public SomeModel SomeModel {get;set;}
public int OtherProperty {get;set;}
}
in razor view:
#model SomeViewModel
What I expose to the razor view is, amongst others, 2 potentially security-risky things: the db id of the SomeModel instance, and the entity's dynamic proxy id ( or whatever that is), which i guess is related to the lazy loading of the entities.
System.Data.Entity.DynamicProxies.SomeModel_2ED515217...etc
So my plan is to make sure that all razor views utilize viewmodels ONLY. Also, all view models should exclude the above 2 mentioned things, the db id and the dynamic proxy id.
So SomeViewModel would become something like this:
public class SomeViewModel {
public int SomeModelId {get;set;}
public string SomeModelPropA {get;set;}
public string SomeModelPropB {get;set;}
public int OtherProperty {get;set;}
}
To sum up, is it a good idea to be very restrictive regarding what razor views use for model?
I know razor views are server side compiled, but what if a razor developer by accident use some of the 'forbidden' view model properties?
Well, as long as you do not expose this stuff outside of your server this is quite fine... But even if user will see the DB's Id of your record - the security risks arises only when he can do something with it. Until then - it's just a number. You better think on how to protect Edit / Delete operations instead :)
Since we are there - think about one thing - when you strip your view model of all identifiers - how are you going to map things back when trying to update user's changes? Of course, it's not an issue if ViewModel is going to be read-only.
But anyway - I would strongly suggest to remove whole model objects from ViewModel objects - leave only some identifiers. If you have security concerns - maybe just try hashing them before?
And keep in ViewModel only as few fields / properties as required. And strictly defined. Not only for security reasons, but also to lower memory /transfer data usage.
I am working on a new project, and, after seeing some of the difficulties of previous projects that didn't provide enough separation of view from their models (specifically using MVC - the models and views began to bleed into each other a bit), I wanted to use MVVM.
I understand the basic concept, and I'm excited to start using it. However, one thing that escapes me a bit - what data should be contained in the ViewModel?
For example, if I am creating a ViewModel that will encompass two pieces of data so they can be edited in a form, do I capture it like this:
public PersonAddressViewModel {
public Person Person { get; set; }
public Address Address { get; set; }
}
or like this:
public PersonAddressViewModel {
public string FirstName { get; set; }
public string LastName { get; set; }
public string StreetName { get; set; }
// ...etc
}
To me, the first feels more correct for what we're attempting to do. If we were doing more fine grain forms (maybe all we were capturing was FirstName, LastName, and StreetAddress) then it might make more sense to go down to that level. But, I feel like the first is correct since we're capturing ALL Person data in the form and ALL Address data. It seems like it doesn't make sense (and a lot of extra work) to split things apart like that.
Appreciate any insight.
If you are using all the fields of the Person object, then there's nothing wrong with using a complex view model. However, if you are only using a field here or there, then it's much better to build your viewmodel with only those values you are using.
You can do your view models any way you like, but the whole point of having them is that a view model should be customized to the view it's representing.
It can also be a lot easier to use the first method if you're using something like AutoMapper to map to business or domain models, because the objects should have similar definitions.
You're not using MVVM. You're defining ViewModels, classes for only view purposes in order to avoid to break the Model classes. In that case you can define the properties you want for your best profit. In the example I will go for the second solution but it's up to you.
I'm working on a big project with many developer providers. In that case the customer let us to define the ViewModels that we want keeping the Models (Business Entities as they call) for their concern. Because we are different groups no one is worried about another ViewModels so you can even use one class for one view, no matter if another view is different a little bit from the first one. That's one of the advantages of ViewModels instead of pure Model using.
I prefer to define the ViewModels in client-side through JSON objects for the sake of data binding. With this you can truly use MVVM through knockoutjs, angularjs, backbonejs, etc....
If you want to use MVVM check knockoutjs. It's very easy and pleasant to use
Using Model classes directly or wrapping them (as in your 1st example) in your ViewModel class can be a potential security issue if your Model classes have some sensitive properties (i.e. IsAdmin in the User class).
Say your controller actions takes a PersonAddressViewModel input parameter:
public ViewResult someAction(PersonAddressViewModel personAddress)
{
//save it
}
A malicious user can basically set any property in your PersonAddressViewModel composite object even if your UI does not provide such capabilitiy.
This is made possible by the default binding mechanism of the MVC.
To avoid this, either don't wrap sensitive model classes or use the Bind attribute
More on this here: Pro ASP.NET MVC 3 Framework 3rd Edition By Steven Sanderson , Adam Freeman (Chapter 17)
If you're using that view model to render a form, I would vote for the second approach, since you're combining all the view data required for the form.
Im new to ASP.NET MVC, trying to learn the basics.
Im now trying to learn the relationship between the model ,view and controller.
The interaction between these three looks different, why? (Look at the arrows)
Source 1: MSDN
Source 2 (Page 65): Steven Sanderson
I would be glad if you help me sort out my confusion
Thanks
Edit:
What you are saying is that mvc can be implemented differently?
(Still asking about asp.net mvc - Not mvc in general)
I have been looking at the mvcmusicstore
and it looks like this.
Controller:
public ActionResult Details(int id)
{
var album = storeDB.Albums.Find(id);
return View(album);
}
Model:
public class Album
{
public int AlbumId { get; set; }
public int GenreId { get; set; }
public int ArtistId { get; set; }
public string Title { get; set; }
public decimal Price { get; set; }
public string AlbumArtUrl { get; set; }
public Genre Genre { get; set; }
public Artist Artist { get; set; }
}
view:
(Had to add as image, add code the normal way did not work)
This looks like the MSDN version, how would this be rewritten to fit Sandersons diagram?
Maybe this will help me understand!
Edit again:
Hi again
Let me sum this up. Please respond if I'm wrong.
The way Microsoft intended us to use mvc is the one we see in the above MSDN link and in MusicStore.
Then there are other "versions" of mvc such as Sandersons (or whereever it originates from).
So Microsoft give us a basic way of how to use the mvc framework, but it is ok to do it other ways.
A newbie should not get stressed by seeing different versions, sticking to the one seen in MSDN/MusicStore is perfectly fine.
The key difference is the inclusion of the "Presentation Model" in Sanderson's diagram. The ASP.NET MVC implementation often uses the Model as the Presentation Model, even though they can be different (and I would argue that they should be different, but it's a holy war and there's no need to get into that).
In most very simple ASP.NET MVC applications, the model is the data entity. Whether it's an EF entity or a Linq2Sql entity, makes no difference. This is because most applications are simple forms-over-data and the presentation is probably one-to-one with the persistence.
The MVC pattern itself, however, doesn't require this. In a more pure framework-agnostic form, Sanderson's diagram illustrates the fact that the controller is interacting with the model. The model is really the "gateway to the domain core" in this sense. Controllers and views are part of the application, but the model has the underlying business logic and, beneath that, layers of persistence and other infrastructure information (properly separated, of course) which are unknown to the application. The boundary between the controller and the model is the application boundary, the point at which other applications can also connect to the domain core and interact with it.
A presentation model is usually nothing more than a simple value object. It's not an entity of any kind in the sense that it doesn't have to exhibit any business behavior or maintain its lifecycle the way that a persistable business entity would. It's just a flat object with some attributes of data.
It can have some behavior, but that behavior is for the application and not for the domain core. For example, maybe it has some methods or properties that the view can use. The presentation model is part of the application, so it's presentation-layer-aware. Essentially it just holds data that the controller needs to pass to the view (or even receive from the request, depending on the framework).
In ASP.NET MVC you'll very often see the model used also as the presentation model. The same object may be playing two roles in those cases, but the two roles are definitely different.
Edit: Just noticed your updated question...
In that example, Album is playing the role of both domain model and presentation model. (In fact, I would argue that it's not a domain model at all because it's too anemic. Notice that it has no functionality, just bare data.) In a richer domain model, Album would likely have more functionality. For a contrived example, imagine that instead of auto-implemented properties it has properties which enforce business logic when set, and it has methods on it such as AddSong(Song song) and Play() and other such behaviors.
This richer model can still be used as a presentation model, but the functionality might not make sense in the scope of a view. A view is really suited more toward just bare data elements. The controller would interact with the model's functionality. So you might create a presentation model similar to the Album domain model in structure, and it would look just like the one in your example.
Going forward, what if the view needs other data as well? Maybe the view needs to know something about other models which aren't part of the same aggregate as Album. It wouldn't make sense to modify the domain models to accommodate the view. That's backwards. The presentation should wrap around the domain core, not the other way around. So you might add properties to the presentation model which are populated from other things inside the controller.
So you might end up with something like this...
Domain model:
public class Album
{
public int ID { get; private set; } // might need to be immutable
private string _title;
public string Title
{
get { return _title; }
set
{
// don't allow empty titles
if (string.IsNullOrWhiteSpace(value))
throw new ArgumentNullException("Title");
_title = value;
}
}
private Album() { }
public Album(int id, string title)
{
ID = id;
Title = title;
}
public void Play()
{
// some implementation
}
public void SomeOtherMethod()
{
// some implementation
}
}
As the business domain grows and changes, this model could change with it. The main point is that it changes at the behest of the domain core and the business logic, not at the behest of UI implementations.
A particular "page" on a particular website which uses this domain core may need specific information about an album, and maybe some other information as well. You'd tailor a presentation model to fit that:
public class AlbumViewModel
{
public int ID { get; set; }
public string Title { get; set; }
public string Owner { get; set; }
public IEnumerable<Listener> Listeners { get; set; }
public string SomeCompletelyUnrelatedValueNeededByTheView { get; set; }
}
The controller would then construct this presentation model for the view:
public ActionResult Details(int id)
{
// TODO: validate and sanitize any inputs
var album = AlbumRepository.Get(id); // after all, why bind the UI _directly_ to the DB? that's just silly
var someOtherObject = SomeOtherRepository.Get(someOtherValueFromSomewhereElse);
var albumVM = new AlbumViewModel
{
ID = album.ID,
Title = album.Title,
Owner = somethingElse.SomeValue,
Listeners = someOtherObject.GetListeners(album),
SomeCompletelyUnrelatedValueNeededByTheView = "foo"
};
return View(albumVM);
}
This is a much more manual approach overall. It's useful when you have more complex domain models, multiple complex applications interacting with that domain, different technology stacks throughout the domain, etc. For simple forms-over-data applications the standard ASP.NET MVC implementation usually works fine. Most of the tutorials for it reflect this, consolidating multiple responsibilities into fewer objects, using decorators instead of explicit code (assuming the use of the same stack of tools across the board), etc.
The examples you're looking at get you to a working application very quickly with very little code. As with any framework, it works beautifully if you do things the way the framework intends you to do them. If you need to step outside the bounds of the framework, you can still maintain the pattern in a more abstract and framework-agnostic way.
Edit: For your update again...
In a way, yes. ASP.NET MVC is a framework which borrows a lot from the MVC pattern in general. As with all things, there's more than one way to do it. Sticking with simple implementations and quick applications, the functionality provided by the ASP.NET MVC framework and explained in its various tutorials is perfectly acceptable and is a great example of the use of a framework... Using a tool to get a job done.
They stick to the pattern in all the most meaningful ways. At the same time, however, in the true nature of a framework (which is generally outside the scope of a pattern description), they try to give you tools which make very light work of the actual development. If you don't have a pressing need to separate your domain models from your presentation models, you don't have to. One model can play both roles. If you don't have a pressing need to abstract your data access behind, say, a repository pattern, you don't have to. You can throw together some quick Entity Framework functionality directly in your Models and be done with it.
Ultimately it's up to the needs of the project, the preferences of the developer(s), and so on. The patterns are more academic, the frameworks are more pragmatic. Balancing the two is the key.
I guess the distinction is that in asp.net MVC you can have strongly typed views which have 'knowledge' of your model and the entity being passed through to the view. In its purest sense though the View shouldn't (or rather, neednt) have any knowledge of the model. For that reason I say Steven Sandersons example is better.
Fantastic book by he way!
I wouldn't sweat it - Stephen Sanderson's diagram is showing less of the cycle but in more detail.
I'd interpret the MS article arrows as:
Controller populates model (from services, etc)
Controller directs to view
View populates through binding model
The microsoft diagram isn't really that useful or informative or useful though in my opinion. You could equally argue that arrows could go in different directions - or even in both directions like Sanderson's do. E.g. Controller also received models from binding, etc.
The Sanderson arrows are annotated well and are self-explicit, and the book is great.
I'm using ASP.NET 4 and MVC3.
Often, I find that I need a ViewModel to display information for my Model. For example, take the following model
class Profile
{
public int UserID { get; set; }
public string Name { get; set; }
public DateTime DOB { get; set; }
}
There is a requirement to hide the UserID, but to show the UserName, so often time for models that are similar to the one above, I have to come up with a ViewModel with just the UserID changed to UserName:
class ProfileViewModel
{
public string UserName { get; set; }
public string Name { get; set; }
public DateTime DOB { get; set; }
}
Are there any ways?
Until recently I always passed my models to my action methods as I also thought that creating viewModels with the same property names was duplication (its not). This caused me a lot of pain. I have now been re-educated and almost always use viewModels exclusively in my action methods (of course there will always be situations were it is fine to pass the model directly to the action method).
Have a read of this post which is the one that converted me to using viewModels. This will tell you the following:
The difference between models and viewModels
When each should be used.
How to avoid some security issues with the default model binder.
On top of the information in the linked post you should also consider things such as validation. I had a model that implemented the IValidateableObject interface to ensure the entity was in a valid state before being saved to the database.
In my ASP.NET application I wanted to create a multi-step form that allowed the user to enter the information over a number of pages. The problem I had here was that ASP.NET also uses the IValidatableObject interface during the model binding process.
If you are only allowing the user to enter a subset of the information required for the entity, the model binder will only be able to fill in the information that was given. Depending on how complex your validation is, this can result in the ModelState being marked as invalid as the entire entity is not valid.
The way I got around this was to have a viewModel representing each step each with its own validation. This way you are only validating the properties at each step. Once you get to the final step and everything is valid, I create an appropriate entity using the information given by the user. This entity will only have database-level validation checks performed upon it (field lengths etc.)
My suggestion is not to avoid viewModels but to understand why they are used and embrace them.
No, there isn't, once a member is public, it's public. Now, if the UserID property was internal, then you wouldn't have that problem.
However, one of the aims of MVVM here is to encapsulate logic regarding the interaction of the model and the view. Even if you have the view model and model in separate assemblies and make the UserID property internal, you should still have a view model; if changes come down the line where more functionality is required than simply binding to the model, you are prepared.
Direct access to the model is always a no no.
Additionally, if you really wanted, you could always use T4 templates to auto-generate the code for you (you could use Code DOM on the original CS file) to output your view models for you.
I usually have multiple ViewModels per model - the tradeoff you have to make comes down to this:
Are you comfortable coupling business logic (data annotations, display information, etc...) with your (persistence) models?
Are you comfortable doing all of the hide / display business logic purely within the View and not use the Controller + scaffolding to make those decisions for you?
The downside of creating all of those ViewModels of course is sub-class explosion, but the right way to think about it is in terms of the questions I listed IMHO.
In asp.net mvc, I have been thinking it would be more advantageous to specify parametrized constructors on the view classes in contrast to using ViewData to pass data to the view. In this way the view class could be instantiated in the action and returned from there as an implementation of IView for eventual rendering to the client by the framework.
// An example of an action that returned one of two
// views while passing a data objects from the current
// scope.
IView MyAction(discriminator){
if(discriminator){
return new MyView(SomeVal, SomeVal2)
}else{
return new AnotherView(SomeVal1)
}
}
// An Example Definition for IView
public interface IView{
Render(stream OutputStream);
}
// An Example View Code Behind/Partial Class
public partial class AnotherView{
public AnotherView(string GimmeData){
this.GimmeData = GimmeData
}
// This value could be accessed in the markup like:
// <%=this.GimmeData%>
public string GimmeData {get; set;}
}
I pose this question because I have personally found strongly typed views pointless as there is not 1 or 0 but n number of objects I would like to pass to the view from the action. I also find the ViewData collection a little too "untyped" to mesh really well with the .net strongly typed world.
A parametrize constructor or even public properties on the view would allow the implementer of the view to specify a contract of what data is needed to render the view or can be rendered in the view. This approach would effectively encapsulate the view.
Why would this be a bad design? What advantages are provided with the "viewdata collection"/"strongly typed view" "way" of passing data from the action to the view. Does anyone think this would be a good idea?
update
I have had a change of heart. What I realized is that the view is really just about rendering. A very good design approach is to introduce Presentation Models that represent the user interfaces available in your application.
If something can be shown or not there should be a Boolean in your presentation model. If something can display text there should be a string for that in your presentation model. The presentation model is not anemic because you use it to encapsulate the logic of your UI. For example, if a field is empty then perhaps some other field is grayed out. This is presentation logic and it describes the way that your particular UI works.
Once a presentation model has been introduced the generic page classes work fine, you simply pass the view the correct presentation model. Presentation models allow you to clean up the code in your view as well as provide portability. If one decided to implement in winforms they would seriously only need to bind their UI to the presentation model.
Anyway, I just wanted to follow-up because I no longer agree with my original suggestion. I have accepted Travis's answer because this is essentially what he proposed.
The convention is usually to provide a View Model that encapsulates the data you need in your view. You can then pass this strongly typed object down into your view. So, for example, you might have a BlogDisplay object that looks like this:
public object BlogDisplayPage {
public string PageTitle {get; set;}
public BlogEntry Content {get; set;}
public IList<Comment> Comments {get; set;}
public IList<BlogEntry> RelatedEntries {get; set;}
public IList<BlogEntry> PreviousEntries {get; set;}
}
Excuse the contrivedness of the example, but I think you understand what I'm trying to get at. This way, you can have all of the data associated with the View in one object that can be easily tested and maintained. This also has the advantage of having strongly typed Views using generics.
I prefer this over your suggestion of parameterized constructors because its intent is clear, and the creation and aggregation of that data is going to be in one spot that will probably be easier to maintain.