Use MVC Custom Model Binder? - asp.net-mvc

I have an MVC app I'm writing. There will be the need for multiple instances of the same page to be open, each accessing different records from a database, these record objects will also need to be passed through a flow of pages, before finally being updated.
What's the best, and most correct, way of acheiving this - should/can I create a custom model binder that links to an object via it's unique ID and then create each record-object in the session, updating them as I go through each one's page flow and then finally calling the update method? Or is there a better way of dealing with this?
Cheers
MH

Technically, that would be possible, but I don't think it is advisable. When you look at the signature of IModelBinder, you will have to jump through some hoops related to the ControllerContext if you want to be able to access the rest of your application's context (such as how to dehydrate objects based on IDs).
It's possible, but so clunky that you should consider whether it's the right approach. In my opinion, a ModelBinder's responsibility is to map HTTP request data to strongly typed objects. Nothing more and nothing less - it is strictly a mapper, and trying to make it do more would be breaking the Single Responsibility Principle.
It sounds to me like you need an Application Controller - basically, a class that orchestrates the Views and the state of the underlying Model. You can read more about the Application Controller design pattern in Patterns of Enterprise Application Architecture.
Since a web application is inherently stateless, you will need a place to store the intermediate state of the application. Whether you use sessions or a custom durable store to do that depends on the application's requirements and the general complexity of the intermediate data.

Related

Where should I add a List All Users function when using MVC?

I'm aware that in model-view-controller, the Model is the class part.
If I have a User class and instantiate an object, the object must refer to a single user from the database.
So I'll have the CRUD methods on the user, for that specific user.
But if I need a function to run a SELECT * FROM Users, should I create a function within the User class? Or a function in a helper file? Or in the controller? Where should it go, in order to respect the MVC pattern?
I mean, it makes no sense to instantiate a User object just to run a function to display the Users table.
I'm not sure if this will raise "primarily opinion based" flags. I just don't know where those functions should go. If you guys consider the question worth closing, it's ok. But tell me in the comments in which stack community I should ask this.
Back up a bit. Let's go foundational for a moment.
In the MVC pattern
The model is your state (in simple terms), meaning a representation of the data important to the business functionality you are working with
The view is a way of presenting the state to the user (NOTE user here could be another system, as you can use MVC patterns for service endpoints)
The controller ensures the model gets to the view and back out of the view
In a system designed with good separation of state, business functions are not present in the model, the view or the controller. You segregate business functionality into its own class library. Why? You never know when the application will require a mobile (native, not web) implementation or a desktop implementation or maybe even become part of a windows service.
As for getting at data, proper separation of concerns states the data access is separate not only from the model, view and controller, but also from the business functionality. This is why DALs are created.
Before going on, let's go to your questions.
should I create a function within the User class? This is an "active record" pattern, which is largely deprecated today, as it closely couples behavior and state. I am sure there are still some instances where it applies, but I would not use it.
Or a function in a helper file? Better option, as you can separate it out. But I am not fond of "everything in a single project" approach, personally.
Or in the controller? Never, despite Scott Gu's first MVC examples where he put LINQ to SQL (another groan?) in the controller.
Where should it go, in order to respect the MVC pattern?
Here is my suggestion:
Create a DAL project to access the data. One possible pattern that works nicely here is the repository pattern. If you utilize the same data type for your keys in all/most tables, you can create a generic repository and then derive individual versions for specific data. Okay, so this one is really old, but looking over it, it still has the high level concepts (https://gregorybeamer.wordpress.com/2010/08/10/generics-on-the-data-access-layer)
Create a core project for the business logic, if needed. I do this every time, as it allows me to test the ideas on the DAL through unit tests. Yes, I can test directly in the MVC project (and do), but I like a clean separation as you rarely find 0% business rules in a solution.
Have the core pull the data from the DAL project and the MVC project use the core project. Nice flow. Easy to unit test. etc.
If you want this in a single project, then separate out the bits into different folders so you can make individual projects, if needed, in the future.
For the love of all things good and holy, don't use the repository pattern. #GregoryABeamer has a great answer in all respects, except recommending you create repository instances to access your entities. Your ORM (most likely Entity Framework) covers this, and completely replaces the concepts of repositories and unit of work.
Simply, if you need something from your database, hit your ORM directly in your controller. If you prefer, you can still add a level of abstraction to hide the use of the ORM itself, such that you could more easily switch out the data access with another ORM, Web Api, etc. Just don't do a traditional unit of work with tens or hundreds of repository instances. If you're interested, you can read a series of posts I wrote about that on my blog. I use the term "repository" with my approach, but mostly just to contrast with the typical "generic" repository approach you find scattered all over the interwebs.
I'd use some kind of 'Repository' layer. Then, my controller calls the UserRepository GetAll method and sends the data to View layer.

MVC Security Violation - Improperly Controlled Modification of Dynamically-Determined Object Attributes

We are developing an MVC 5 Application and while we ran security scan using Veracode we are getting the below flaw saying
"Improperly Controlled Modification of Dynamically-Determined Object Attributes"
And added this link as reference to fix.
Tried implementing Bind Attribute to my Controllers functions with HTTP Post and the issue is fixed.
So in ASP.NET MVC is it mandatory to use Bind Attribute for all the Post to avoid security violation ?
Or can i ignore this flaw or any other alternative way i can address this as hard coding and maintaining Bind Attributes really gets difficult in real time applications.
Please share your views.
it is not mandatory to use the Bind attribute.
The link which you have posted is basically the dirtiest example they could have came up with. They are directly binding an EF model into the controller, which no real world application would do and I hate Miscrosoft where they show you how easily you can go from DB to Web by applying the dirtiest worst practise patterns without explaining that this is not something you would want to do in real life.
In real life you would create a (View)Model which is tailored to your View. This means the class will ONLY have the properties which you want to accept from the request, therefore you wouldn't really need the Bind attribute in most cases.
EF models are low level classes in your data layer and shouldn't be bound to any controllers IMO.
UPDATE:
Actually on the top of the link they have posted this:
Note It's a common practice to implement the repository pattern in
order to create an abstraction layer between your controller and the
data access layer. To keep these tutorials simple and focused on
teaching how to use the Entity Framework itself, they don't use
repositories. For information about how to implement repositories, see
the ASP.NET Data Access Content Map.
However, this is just talking about the repository pattern, which is a good pattern to abstract your data layer, but the DTO which the repository pattern would return is still too low level for binding to a View.
You should create a model which is tailored to your view and in your controller or service layer you can do the infrastructure mapping between the different layers.

prepopulate MVC Models with IOC - an alternative to caching?

I'm considering strategies for a simple-minded CMS implementation for an ASP.NET MVC site. The simple-minded part is that I've abstracted the values used in various partial views, all of which are user controls that share identical CSS layouts. So I'm populating the custom values in the identical partial views from the database where I can modify them occasionally using CRUDs.
The not so simple part is a reasonably efficient and logical abstraction of a standard UI element as a sql table row. But putting that aside...
I know I'm going to use some super-models to hand to each page the pre-configged models for the partial views. But if they are pre-configged and pre-loaded, where to put them until called?
The part that makes me think I'm a little insane to go this way is the load time for what is essentially static data. But then again, SharePoint!
So (I think) why not load it all in application_start? Why not? I answer! Then I get to use IoC for something that google returns not one link to good information from even one smart person who has ever considered that it might be a sane idea.
So does anyone have a better idea for populating a Model from the database using an IoC container other than putting a repository call in the constructor?
And then, does anyone think that putting these static-data models in an IoC container accessible to the controllers is a dumb idea?
Thanks,
S. Machino
Following several SOLID principles, keep your stuff as single-minded as possible. For semi-static data, first create a Repository that loads this data. This will load the data for every request. It works, but probably doesn't perform so well, but now you have the implementation you need.
The next thing you can do is to Decorate the first Repository with a caching Repository. This CachingRepository will read from the decorated Repository only once, and then keep data in memory.
Thus you respect Separation of Concerns.
If you scope the CachingRepository instance to be a Singleton, it will live until the application is recycled, effectively keeping the cached data in memory.
You may want to consider using the OutputCache attribute in your design. You can decorate your action methods that will return static data with this attribute and the framework will take care of caching.
Of course, you still need to handle when to invalidate the cache.

Where to put auditing or logging?

I'm currently working on an ASP.NET MVC project using NHibernate and I need to keep track of changes on some entities in order to be able to make some reports and queries over the data. For this reason I wanted to have the data in a table, but I'm trying to decide where to "hook" the auditing code.
On the NHibernate layer:
PRO: Powerful event system to track any change
PRO: Nothing can be changed in the application without notice (unless someone uses raw SQL...)
CON: As I have a generic repository... then I have to filter out the useful entities (I don't need to track everything).
CON: I don't have easy access to the controller and the action so I can only track basic operations (update, delete...). I can get the HttpContext at least to get some info.
On an Action Filter at Controller level:
PRO: Full information on the request and web application status. This way I can distinguish an "edit" from a "status change" and be more descriptive in the audit information.
CON: Someone can forget a filter and an important action can be taken without notice which is a big con.
Any clue?
Update: See how to Create an Audit Log using NHibernate Events.
I think doing this at the repository level is a much better fit. Mostly because you may, in the future, decide to add some method of access to your repository which does not go through MVC (e.g., a WCF interface to the data).
So the question becomes, how do you address the cons you've listed about doing it on the NHibernate layer?
Filtering out the useful entities is simple enough. I would probably do this via a custom attribute on the entity type. You can tag the entities you want to track, or the ones you don't; whichever is easier.
Figuring out what the controller really intended is harder. I'm going to dispute that you can "get the HttpContext"; I don't think it is a good idea to do this in a repository, because the separation of concerns. The repository should not be dependent on the web. One method would be to create custom methods on the repository for actions you'd like to track differently; this is especially attractive if there are other aspects of these edits which behave differently, such as different security. Another method is to examine the changes by comparing the old and new versions of the objects and derive the actual nature of the change. A third method is to make no attempt to derive the nature of the change, but just store the before and after versions in the log so that the person who reads the log can figure it out for themselves.
I'd rather put it in the data (NHibernate in your case) layer. Putting it in the controller and asking other people (or yourself, in the future) to implement controllers accordingly conflicts with object-oriented design principles.
I do this with NHibernate. Objects that require auditing implement an IAudtable interface and I use an Interceptor do the auditing on any object that implements IAuditable by intercepting OnFlushDirty, OnDelete, and OnSave.

In MVC, what are the limitations on the Controller?

Should the Controller make direct assignments on the Model objects, or just tell the Model what needs to be done?
The controller has two traditional roles:
handling the input event from the UI (registered handler or callback)
notifying the model of an action--which may or may not result in a change on the model's state
It does not perform data validation, that is on the model, nor does it have any say in how information is presented.
It depends largely on the scope of your application. If it's relatively quick and dirty, then there's no sense in over-engineering, and sure, your controllers can talk to your model objects. On the other hand, if it needs to be more "enterprisey" for whatever reason, a good pattern to use in conjunction with MVC is the so-called "Business Delegate". This is where you can compose coarse-grained methods out of one or more methods on one or more model objects; for instance deleting an object and then returning a refreshed list without that object. This layer gives two advantages. For one, it decouples the controllers from whatever ORM system is being used for model objects. Furthermore, it is the layer that finally must constructively deal with any exceptions that may have occurred instead of re-throwing them.
I don't think a controller should be dealing with model objects.
I tend to think that controller is really part of the UI tier. I prefer to inject a service layer in-between the controller and the rest of the app. The web tier accepts HTTP requests, unmarshals parameters from request objects into objects that the service interface can deal with, and marshals the response to send back. All the work with transactions, units of work, and dealing with model and persistence objects is done by the service.
This approach is more service oriented. It separates the service from the user interface, leaving open the possibility that several clients can reuse the same service. It makes the layer that marshals requests to the service "thin", so it's easy to switch out SOAP services for REST or EJB or CORBA or whatever the next new thing will be.
The Model services don't have to know the existence of the controller, thus, controller can do the stuff what ever the view needs by utilising the model services.

Resources