ASP.NET MVC 3 - ViewModel Best Practice - asp.net-mvc

I've a Razor view with lots of graph and other text fields which gets data from controller. I'm thinking of passing a ViewModel from controller to the view which then will parse the relevant content and display it.
Could anyone suggest if above approach is the best practice to solve such, in MVC?
The ViewModel class may look like below:
public class ViewModelDemo
{
public MyChart chart {get;set;}
public string LeftContent {get;set}
public string bottomContent {get;set;}
public ChartLeged legent {get;set}
......
}
public class MyChart
{
public List<int> xAxis {get;set}
public List<int> yAxis {get;set;}
......
}
Reason I'm trying to return ViewModel is that there are may parts of the page which have different data.

Absolutely. A ViewModel is a perfectly acceptable solution to this problem. See Section 12.1.5 of Palermo's excellent MVC in Action book (conveniently in the free sample)
The other option is to create a separate view model type for our views
from the domain model. We’ll create a specialized class, just for
that one view. We can shape that type however we like, and allow the
view to shape our view model however we want. The advantage of a
separated view model is that our views won’t influence the domain
model in any way. For less complex applications, this separation is
not necessary and overcomplicates the design. As complexity of the
views increases, the design of the views has more and more impact on
our domain model, unless the view model and domain model are
separated.
http://www.manning.com/palermo/Samplechapter12.pdf

I think you solution is corret.
Another approach could be to split up the big razor view into smaller partial views, each with a simpler view model. This is usefull for readability, separation of responsability, ecc.

Related

ASPNET MVC - What goes into the model?

I have noticed a pattern that in some MVC applications I inherited from a previous developer. When defining the models all the information containing the items for selects and check-boxes are passed in the model.
public class MyModel
{
int MyEntityField1 {get;set;}
string MyEntityField2 {get;set;}
public selectList SelectItens1 {get;set;}
public selectList SelectItens2 {get;set;}
}
...
MyModelInstance.SelectItens1 = new selectlist(...
MyModelInstance.SelectItens2 = new selectlist(...
return view (MyModelInstance);
the information on SelectItens1 and SelectItens2 is one way. What is the advantage of doing as above instead of using the ViewBag to pass Select Items to the view ?
public class MyModel
{
int MyEntityField1 {get;set;}
string MyEntityField2 {get;set;}
}
...
Viewbag.SelectItems1 = new SelectList ( ...
Viewbag.SelectItems2 = new SelectList ( ...
return view (MyModelInstance);
I think it just makes the model fat for no gain whatsoever.
Please advise.
Both approaches are fine, its just a developer preference
First Approach:
There is no harm in having the SelectListItem within your model, Moreover it gives you a clear picture of what the fields must be in your UI, So looking at the model you can confirm that the UI needs to render a dropdown list control for the 2 properties in your example.
Second Approach: If this model is used only in one or minimal pages then Viewbag should be okay. Again this might mean that the developer must have knowledge on what control the UI must render.
So the approaches are purely developers choice and I don't see any major performance improvements of one over the other.
I personally use the first approach as it more clean and keeps the controller code less.
Generally I would agree that models should be kept to the minimum.
However with Microsoft ASPNET MVC pattern you want to keep your controller clean and Microsoft they recommended approach is to fatten your Model and not your controller!
"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."
https://www.asp.net/mvc/overview/older-versions-1/overview/understanding-models-views-and-controllers-cs

exposure of DAL in razor views

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.

ASP.NET MVC View Model Base?

I am working on my model hierarchy and have a few questions.
1) I have a base model for each view type (Add, Edit and View). I put thing in these that are specific to each view type.
2) I then have a model base which the bases above inherit from. This allows me to include things that pertain to ALL views.
3) In my ModelBase, i have a couple of other view models like FeedbackViewModel, ShoppingCartViewModel, etc that I can consume on any view.
4) I have my MasterPage inheriting ModelBase.
Example
Public MustInherit Class ModelBase
Public Property ErrorMessage As String
Public Property InformationMessage As String
Public Property WarningMessage As String
Public Property FeedbackModel As New FeedbackViewModel
End Class
Public MustInherit Class ViewModelBase
Inherits ModelBase
'View Model Specific Stuff
End Class
'Allows contact us form to be submitted.
Public Class ContactUsViewModel
Inherits ViewModelBase
Public Property Name As String
Public Property EmailAddress As String
Public Property Phone As String
Public Property Comments As String
End Class
That is the basic structure of my models, but a few questions:
1) What do I do with a view that requires no model, but I need to pass the FeedabckViewModel, SHoppingCartViewModel, etc.? I was thinking of a GenricViewModel?
2) Do you see any flaws in this design?
Thank You!
Some points:
Why use ErrorMessage, InformationalMessage, WarningMessage, etc. ModelState should be more than enough, and it ties in better with the validation helpers as opposed to you writing the manual stiching in the View.
I think a "base" model to handle different view types is a bit overkill. I think a enum specifying the mode would be better, then you can make decisions accordingly.
Overall, there is nothing really wrong with your design. It's a matter of opinion - for which mine is i usually create a ViewModel per View. Keeps it simple. I use areas extensively so it doesn't get messy. I generally try and create the ViewModels to make the View simple - that's the ultimate goal, not to re-use code across View's, but to keep the View simple. Such as augmenting the model with nested models to make use of partials/templates, as opposed to having a bunch of strings.
1) What do I do with a view that requires no model, but I need to pass the FeedabckViewModel, SHoppingCartViewModel, etc.?
Doesn't that kind of contradict itself? :) If you just need "parts" of a couple of ViewModels, either create another ViewModel, or if it's just a couple of fields, just stick it in the ViewData.

Defining view models for MVC / MVP

Short question - how do you define your view models?
Here are some of the options:
Pass the actual model into the view.
Create a view model with a reference to the model (like Model.Product)
Create a view model with the properties needed from the model, and set those from the model.
Probably a lot more.
All with their own advantages and disadvantages.
What is your experience - good and bad? And do you use the same model for GET/POST?
Thanks for your input!
Basically - it's all about separating responsibilities.
More you separate them - more verbose, complex but easier to understand it gets.
Model:
public class foo{
string Name{get;set}
Bar Bar {get;set;}
string SomethingThatIsUneccessaryInViews {get;set;}
}
public class bar{
string Name {get;set;}
}
public class fizz{
string Name{get;set;}
}
Presenter (i admit - still haven't got idea of MVP completely):
public someSpecificViewPresenter{
fizz fizz{get;set;}
foo foo{get;set;}
necessaryThingsForWhatever[] necessaryThingsForWhatever{get;set;}
public void someLogicIfNeeded(){...}
}
magic object2object mapping & flattening, viewmodel modelmetadata configuration goes here...
ViewModel (NB=>POCOS with container props only. No logic should go here.):
public class fooViewModel{
string Name {get;set;}
string BarName {get;set;}
}
public class fizzViewModel{
string Name {get;set;}
}
public class someSpecificView{
fooViewModel foo {get;set;}
fizzViewModel fizz {get;set;}
whateverViewModel whatever {get;set;}
}
and here goes "das happy ending"...
<use viewdata="someSpecificView m" />
<p>
Our foo:<br/>
${Html.DisplayFor(x=>x.foo)}
</p>
<p>
Our fizz:<br/>
${Html.DisplayFor(x=>x.fizz)}
</p>
${Html.UberPaging(m.whatever.Paging)}
And yes, i use same model for GET/POST. See this for more why/ifs.
But lately - I'm looking for other solutions. CQRS buzz catch my eye.
In my projects, it's a mix really.
If I want to display a form with details of Customer X, I just pass a DAL Customer object to my view. It's really no use to create a seperate ViewModel for it, map all its properties, and then display them. It's a waste of time imho.
Sometimes though, models are a bit more complex. They're the result of multiple queries, have some added data to them, so in these cases, I create a custom ViewModel, and add the necessary data from my model to it. In your case, it would be option 2, or sometimes 3. I prefer that over passing my model and having to add an additional 10 items in my ViewData.
I grabbed the T4 templates from SubSonic 3. These were modified and I added some new ones. I can run one of them and it generates 3 separate view models for each table. Then I can modify as needed.
Why three?
FormModel - contains on the data necessary for displaying in a form for editing or creation. Foreign keys get converted to SelectLists. DateTime fields get split into date and time components.
PostModel - this is the object returned from the Form Post. DropDownLists are posted as Int or equivalent type. Only the necessary members are in the model.
DisplayModel - used for non-editing display of the data.
I always generated these in a subfolder named Generated. As I hand tweek them I move them to the Models folder. It doesn't completely automate the process, but it generates a lot of code I would otherwise generate by hand.

Should ASP.NET MVC Views be Parameterized

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.

Resources