Viewmodel security in asp.net mvc - asp.net-mvc

Is there a difference in terms of security between these two models to be given to View? Ie. in the second example can a webuser/hacker access the methods in any way?
public class ObjectViewModel
{
public PropertyA {get;set;}
public PropertyB {get;set;}
public PropertyC {get;set;}
}
public class ObjectViewModel2
{
public PropertyA {get; private set;}
public PropertyB {get; private set;}
public PropertyC {get; private set;}
private void SetPropertyA()
{
...GetDataFromRepository();
}
private void SetPropertyB()
{
...GetDataFromRepository();
}
private void SetPropertyC()
{
...GetDataFromRepository();
}
}

First, the model itself is not exposed to the web browser. It's only exposed to the view rendering engine which resides on the server. You can expose access via your actions to certain properties in your model, but these are only via query or form parameters. It won't give access to the underlying methods.
Second, one thing you should know is that the default model binder requires that any properties you wish to set be available via public accessors. If you make a property with a private setter, it won't updated via the model binder.

No, those methods cannot be accessed in any way via a View unless you explicitly tell it.
Unless your controller specifically exposes those methods, only properties are available via Model Binding.

When by-passing the view engine and returning something like a Json(model) or XmlResult(model) you can expose your data. However, since your data is being serialized
your view model methods no longer apply.

Related

Filtering child collection in DbCotext<Entity> for authorizaton

I have an application where we have elaborate authorization process. However in a method that returns IQueryable, we do not have control on which entities in child collection will be returned.
Here is an example:
public class Parent{
public int Id {get; set;}
public string Name {get; set;}
public virtual ICollection<Child> Children {get; set;}
}
public class Child {
.... details of child class
}
public MyContext : DbContext{
public DbSet<Parent> Parents;
public DbSet<Child> Children;
}
Now we have different level permissions on the parent and child items and the user with read permission on parent may not have same permission on all child items in the parent. However I have an OData Web API controller written on top of this model which has a Get method on the Parent class with IQueryable as return type and EnableQuery attribute.
public class ParentController : ODataController{
private readonly MyContext _db = new MyContext();
[EnableQuery]
public IQueryable<Parent> Get{
return _db.Parents;
}
.... other methods
}
I have no control on what query the end user will send and if user asks for children, the DBSet will return all the children irrespective of the access permission.
Is there any way I can filter the Children property of the Parent class?
The end user can only use a $expand query to get all children. Therefore he can only query again associated entities. However sometimes you need to filter more data. Then you have to options:
(The complex one) Create a View or Stored Procedure with tvf. See this answer for more details.
(The easy one) Use a dynamic filter for soft delete flags. You can use this if you just want to filter data that has a flag like IsDeleted. Than you can include this extension and enable it like this:
modelBuilder.Filter("IsDeleted", (ISoftDelete d) => d.IsDeleted, false);
This will only show the datasets that do not have the IsDeleted flag set to true.

Repository and ViewModel in asp.net mvc 3

Here is the situation I am struggling with.
I have an Object Model:
public class MyModel
{
public string Prop1 {get; set;}
public string Prop2 {get; set;}
//etc
}
Then I have Object ModelView
public class MyModelView
{
public MyModel MyModelObject;
public SelectList PropToBeSelected1 {get; set;}
public SelectList PropTobeSelected2 {get; set;}
//etc
}
I have the MyModelRepository class as well that does the delete, update operations for MyModel.
All good and clear so far.
Question:
PropToBeSelected1 and PropTobeSelected2 are drop down lists whose contents come from the database. Should the methods retrieving these contents be put in my MyModelRepository? Or should I create another repository for ViewModel?
Thank you.
First you really don't want domian-ish objects in your viewModel. Your viewModel should be clean with only primitives (like strings, ints... etc). So I'd suggest using a AutoMapper to map your two string props to your viewModel.
With the select list, there are many ways to go about this but I can imagine if they are lists of properties then they are not actual entities, but value objects instead. In this case creating a repository for them is over kill and boarders bad design.
I'd put the 'get' of the property lists in your MyModelRepository. Something like
_myModelRepository.getProperties1For(myModel);
Then AutoMap again on to get your select list.
Edit:
Like #M.Radwan pointed out for complex domain models I'll make viewModels insdie viewModels for easy of mapping.
Domain Model--
public class User : Entity
{
public Address Address { get; set; }
}
public class Address
{
public string Street { get; set; }
public string Zip { get; set; }
}
would map to
public class DetailsViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public AddressViewModel Address { get; set; }
public class AddressViewModel
{
public string Street { get; set; }
public string Zip { get; set; }
}
}
which in our experience has been the only reason to add any complexity to your viewModel. We will put SelectLists in our viewModel though but lately we've been using IEnumerables of inner viewModels and calling custom EditorFor or DisplayFor to turn them into a dropdown / list of checkboxes / radio buttons.
The answer is NO, you should not make any repository for them if you really need them with this view. so they probably are value objects as #jasonhooten said and they should connected to the main aggregate object that used by the repository
Finally I don't decide the ViewModel structure until I finish the view and make it working first and this why I founder and create DevMagicFake, by using DevMagicFake you will delay all decisions of the design regarding the structure of the ViewModel or the repository or how you will use service layer, all this will be delayed after full complete your view and make it working first as BDD (Behavior Driven Development) and TDD (Test Driven Development) so you can take the right decisions of the design and the object model itself
So I just create the action method as the following
public ActionResult List(MyModelView myModelView)
{
FakeRepository<MyModelView> repository = new FakeRepository<MyModelView>();
repository.Add(myModelView);
}
This fake repository will enable me to save and retrieve my whole model even it's a complex model until I finish and complete the whole view and make it working first, and then I start thanking on how the real design and the real repository should looks like, and do on
For more information about DevMagicFake and this approach see this link
DevMagicFake on CodePlex

What is the proper way of using DTOs in this case?

I have the following domain class:
public class Product
{
public virtual Guid Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Product> RelatedProducts { get; set; }
}
I have the following DTO class:
public class ProductDTO
{
public ProductDTO(Product product)
{
Id = product.Id;
Name = product.Name;
}
public Guid Id { get; private set; }
public string Name { get; private set; }
}
I have the following method in my service:
public ProductDTO GetBySlug(string slug)
{
Product product = productRepository.GetBySlug(slug);
return (product != null) ? new ProductDTO(product) : null;
}
I have the following action in my controller:
public ActionResult Details(string slug)
{
ProductDTO viewModel = productService.GetBySlug(slug);
return View("Details", viewModel);
}
After reading around a bit is my understanding that using a DTO as a viewmodel is ok as the current scenario is simple and straight forward. My confusion occurs when the data that I want to return gets a bit more complex. Let's assume that I also want to return the list of related products to the view as well. Where would I add this list?
I read that a DTO is a flattened version of your domain entity that is used to transfer data. Does that mean that a generic list containing the related products should not be allowed inside the DTO? The answer I received so far suggests so. How do I then get the related products to the controller?
One option is:
Instead of returning the ProductDTO in the service I would create a new class that holds ProductDTO and the List of type ProductDTO for the related products and return it from the service. In the controller I would then either pass the new class to the view or create a separate ProductViewModel that holds ProductDTO and the List of type ProductDTO for the related products, populate it and pass that to the view.
Is this a good or a bad idea? Why?
Thanks
I wouldn't place the list inside the DTO at all, because it does not naturally belong there. And I am also not sure what you mean with 'wrapper class'. All you need is a list of products, and it is perfectly OK to have another method on the service which returns this list.
Consequently, you would have something like this in your service:
public IList<ProductDTO> GetRelatedProducts(ProductDTO productDTO)
{
...
The most important idea behind a viewmodel (the thing that is called service above) is that it mediates between the UI and the business model. In other words: It orchestrates and aggregates the business model in a way that is relevant to the UI. And if the UI wants a list of related products at some point, then the service has to deliver it. It's really as simple as this, and it is completely irrelevant here whether the business model itself also has this concept.
HTH!
Thomas
P.S.
If your DTOs get larger and your lists longer, you might consider to introduce another (simplified) DTO with only the name and some sort of identifier to reduce the amount of unnecessary data you have to retrieve from the repository.

ASP.NET MVC UpdateModel - fields vs properties?

I refactored some common properties into a base class and immediately my model updates started failing. UpdateModel() and TryUpdateModel() did not seem to update inherited public properties.
I cannot find detailed info on MSDN nor Google as to the rules or semantics of these methods. The docs are terse (http://msdn.microsoft.com/en-us/library/dd470933.aspx), simply stating:
Updates the specified model instance using values from the controller's current value provider.
SOLVED: MVC.NET does indeed handle inherited properties just fine. This turned out to have nothing to do with inheritance. My base class was implemented with public fields, not properties. Switching them to formal properties (adding {get; set; }) was all I needed. This has bitten me before, I keep wanting to use simple, public fields. I would argue that fields and properties are syntactically identical, and could be argued to be semantically equivalent, for the user of the class.
MVC will bind to properties of the inherited class. The model binder calls something like typeof(yourtype).GetProperties() which returns all the inherited members just fine.
Just tested it out with:
public class PersonBase
{
public string Name { get; set; }
}
public class User : PersonBase
{
public string FavoriteFood { get; set; }
}
"My assumption is the methods are reflecting on the top class only,"
How would that work? The "top" class IS the base class too.
this one made me curious too.
i made a edit form for a class Manager who derives from a Person
(after all, managers are persons too :-))
then in this action method
public ActionResult Edit(Manager manager )
{
return View(manager);
}
which wass called from a view with the Manager (derived type) as strong typed Model variable, when hovering the manager variable, it shows me the base class (it actually said: base: Person ) AND the one extra property for the manager
tried the formcollection too, and that also works:
public ActionResult Edit(FormCollection formCollection )
{
Manager manager = new Manager();
UpdateModel(manager );
return View(manager);
}

ASP.NET MVC / DDD architecture help

I am creating a Web application using ASP.NET MVC, and I'm trying to use domain-driven design. I have an architecture question.
I have a WebControl table to store keys and values for lists so they can be editable. I've incorporated this into my business model, but it is resulting in a lot of redundant code and I'm not sure it belongs there. For example, in my Request class I have a property called NeedType. Because this comes from a list, I created a NeedType class to provide the values for the radio buttons. I'm showing just one example here, but the form is going to have probably a dozen or so lists that need to come from the database.
[edit, to clarify question] What's a better way to do this? Are these list objects really part of my domain or do they exist only for the UI? If not part of the domain, then they don't belong in my Core project, so where do they go?
public class Request : DomainObject
{
public virtual int RequestId { get; set; }
public virtual DateTime SubmissionDate { get; set; }
public virtual string NeedType { get; set; }
public virtual string NeedDescription { get; set; }
// etc.
}
public class NeedType : DomainObject
{
public virtual int NeedTypeId { get; set; }
public virtual string NeedTypeCode { get; set; }
public virtual string NeedTypeName { get; set; }
public virtual int DisplayOrder { get; set; }
public virtual bool Active { get; set; }
}
public class RequestController : Controller
{
private readonly IRequestRepository repository;
public RequestController()
{
repository = new RequestRepository(new HybridSessionBuilder());
}
public RequestController(IRequestRepository repository)
{
this.repository = repository;
}
public ViewResult Index(RequestForm form)
{
ViewData.Add("NeedTypes", GetNeedTypes());
if (form == null)
{
form = new RequestForm();
form.BindTo(repository.GetById(125));
}
}
private NeedType[] GetNeedTypes()
{
INeedTypeRepository repo = new NeedTypeRepository(new HybridSessionBuilder());
return repo.GetAll();
}
}
Create a seperate viewmodel with the data you need in your view. The Model in the M of MVC is not the same as the domainmodel. MVC viewmodels are dumb DTO's without behaviour, properties only. A domain model has as much behaviour as possible. A domain model with get;set; properties only is considered an anti-pattern called "anemic domain model". There are 2 places where most people put the viewmodels: in the web layer, close to the views and controllers, or in a application service layer.
Edit:
When you only need to display a list of all needtypes in the database and one request in your view, I would indeed create one viewmodel with the request and the list of needtypes as properties. I don't think a call to multiple repositories in a controller is a smell, unless you have a larger application and you might want a seperate application service layer that returns the whole viewmodel with one method call.
I think it might also be a good idea to follow the advise of Todd Smith about value object.
When the needtypes can be added or edited by users at runtime, needtype should be an entity. When the needtypes are hardcoded and only changed with new releases of the project, needtype should be a value object and the list of needtypes could be populated by something like NeedType.GetAll() and stored in the database by adding a column to the request table instead of a seperate needtype table.
If it comes from a list, then I'm betting this is a foreign key. Don't think about your UI at all when designing your domain model. This is simply a case where NeedType is a foreign key. Replace the string NeedType with a reference to an actual NeedType object. In your database, this would be a reference to an id.
When you're building your list of NeedType choices, you simply need to pull every NeedType. Perhaps keeping it cached would be a good idea if it doesn't change much.
Your NeedType looks like a value object to me. If it's read-only data then it should be treated as a value object in a DDD architecture and are part of your domain.
A lot of people run into the "omg so much redundancy" issue when dealing with DDD since you're no longer using the old Database -> DataTable -> UI approach.

Resources