exposure of DAL in razor views - asp.net-mvc

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.

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

ASP.NET MVC 3 - ViewModel Best Practice

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.

How to use ViewModel in ASPNET MVC3

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.

How to avoid needing a VIewModel for every Model

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.

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.

Resources