How do I design MVC apps with view auditing in mind? - asp.net-mvc

We're going to be building an application using MVC 4. A key requirement is view-level auditing. In other words, we must be able to show who accessed a view/screen (person details, for example), the parameters to create the view and when the view was accessed. This is a new application so we can do almost whatever needs to be done to address this requirement.
The database will be SQL Server 2008. Data access will include EF 4.x, possibly 5.x but not a sure thing.
My question, how do I get started designing this feature? Are there any sample applications out there?

Don't mind auditing at view level. I think it is better to audit actions. You can do this using global action filters (for example here).

EF does not work very well with Views. You might be better of with either a straight ADO.NET persistence layer that you hand code, or Linq2Sql is a little better about using views (you still have to hook them up manually though). nHibernate would probably be the best ORM to use.
EDIT:
#user1469655 - You have a very fundamental misunderstanding of how MVC works. The "view" is not a page. It's a template. The "page" as you might consider it (ie accessing a specific url) is really a combination of two different things, a route and an action. An action can cause a specific template (view) to render, but there is not necessarily a 1:1 correlation between action and view.
An "action" is a method of a controller. This is mapped to a URL by a route. Typically (but not necessarily), this means something like this:
http://www.my.site/controller/action
When a user visits this URL, it causes the action method to be called, and potentially for a view to be rendered. Different actions can render the same view, because this is nothing more than an html template that can be rendered at will by any action method.
So what you want to do depends on what you are actually logging. It makes no sense whatsoever to log access to the view, because that doesn't actually mean anything. What you want to do is log access through the action, or possibly even log it through the route.
The simplest way to do this is to use a global action filter that is called before every action, in that filter you can log the information you need to (user id, date, time, action, referrer, whatever).. and it gets called for every action. It will not, however, get called for ignored routes (such as for content like javascript, images, css, files downloaded directly, etc..). If you need to log those, then you will need to control access to them via an action.
There's a good tutorial on Action Filters here
http://www.asp.net/mvc/tutorials/older-versions/controllers-and-routing/understanding-action-filters-cs

Related

When does it make sense to use Items over controller or model variables

Asp.net mvc provides the ability to have page specific variables in the form of Items. These persist across action actions you might jump through during the processing of your view.
I'm a bit confused right now though because while using them can make things easier, it can also lead to weird dependency scenarios like the one i'm facing right now where in one action I am forced to call another action (in my case unnecessarily) before I can proceed in the former action.
Also asp.net provides the ability to either bind arguments to a model as well as pass them straight into an action when you execute a controller action. This way each action can operate with a set of variables specific to it's needs.
With those alternative methods in mind, it seems like the ideal thing would be to use a model or action specific variables per action instead of using Item values that persists across all actions. Regardless, Items still exist...
Are Item variables just a relic from asp.net (prior to mvc) and should now be avoided in MVC? Otherwise, Can anyone help me understand scenarios where using an item variable might make more sense than just declaring the variables important for the action directly in the model or on the controller action?
Thanks
One possible scenario I thought of where use of item might make some sense is in the case where encapsulate some functionality into a separate action simply to reduce complexity of the originating code. In this case you can't easily define variables that you need back in the previous action. So you can just set them up as item values and they are now accessible in the former action after the subsequent action fully completes.
This should work work as long as there's never a scenario where you choose not to call the secondary function.
This is definitely a special circumstance though as the secondary action should need access to the detail being passed back. Otherwise it'd make sense to just pull the logic out of the secondary action and apply it to the former action.

What's the difference between controllers and actions in ruby on rails?

Can anybody tell me the difference between controllers and actions in ruby on rails?
I fetched this definition from the official rails guide:
A controller's purpose is to receive specific requests for the application. Routing decides
which controller receives which requests. Often, there is more than one route to each
controller, and different routes can be served by different actions. Each action's purpose is
to collect information to provide it to a view.
I am confused.
Please, make it as simple as possible since I am newbie!
Thanks!
Controllers are just Ruby Class files which have a series of instance methods inside
Basic Explanation
Rails controllers are basically files where actions (methods) are kept
Each time you access a Rails app, you're sending a request to the system. The various technologies inside Rails route that request to a certain action, where your code can use the passed data to perform some sort of action (hence the name). The actions are kept inside controllers to give the application structure
So if you access http://yourapp.com/users/new, it tells Rails to load the new method in the users controller. You can have as many actions in the controllers as you want, but you have to tell the Rails routes system they are there, otherwise they won't be accessible
Proper Explanation
Rails Controllers are just Ruby Classes, storing a series of actions
The "actions" (instance methods) work on passed data (params) to create objects that can either be passed to the model, or used inside other methods
Whenever you send a request to Rails (access a URL), it first uses the ActionDispatch middleware to send your request to the correct Class (controller) instance method (action), and then your code does something with that data
Your job as a dev is to connect the right controllers with the right models, presenting the right data the user at the right time
DISCLAIMER: I don't write code in Rails (never did). I write Sinatra modular applications and use the MVC model.
You first need to clarify the MVC model. The MVC is an approach to programming web applications (in RoR) or user interfaces in general. So MVC stands for Model-View-Controller. I will try to explain a bit, but in order to understand this, you need to practice and play with it.
The Model: If you remove the layers of abstraction, it's your database scheme. The way your application interconnects in order to retrieve information.
The View: The way these informations are retrieved elaborated and served. Essentially is what you, or the client, see in the browser.
The Controller: The controller is what interacts with the program to produce a requested view or to alter a model. You request a view when you access a chart with statistical information, and you alter the model when you input DATA on it. In Rails ecosystem, ActionController is a class with a set of predefined methods to help you perform easier and quicker standard Controller actions like update a form, etc.
So the Action Controller allows you to alter data to your models (the db), or request a route to view your data, etc.
Action is not separated from controllers, it's basically what controllers do :-). Everything else is static.
If you feel that these concepts are still hard to grasp, try building a very basic modular application in Sinatra, and you will have a ground level view of how things work.
Explanation by Analogy (simple explanation without getting too technical)
I work in a busy office. I bark out orders (i.e. 'requests') to my staff to get em to do stuff.
e.g.
Sometimes I want a document so I can read it.
“Ngozi, pass me the ABC.ASX EOFY results please?”
Yes sir!
Sometimes I ask my staff to edit an existing document:
“Sunita, can you edit that report on the state of the union address?”
“Sure!” is the response.
I organise my staff based on the type of work they do
But I have a little problem.....I have 10,000s of different types of documents. Sometimes I want to get: (I) sports results and other times I want: (ii) the evening news, while still at other times I want: (iii) a collection of Donald Trump's latest 4 am Tweets.
So I created a new system. I have a staff member directly responsible for each type of thing.
Ngozi handles ASX (Australian Stock Exchange) Financial Results. And when I want Ngozi to do something (i.e. perform some type of action) then I tell him what to do.
Sunita works mainly on politics. Sometimes I”ll ask her to something (e.g. write up a report – this is one type of 'action', or I'll ask her to bring me a certain document – another type of action - and she'll do it. I like to get Sunita to work on politics and Ngozi to work on financial results. It's best to keep their responsibilities separated.).
And Freddie works on anything pertaining to Queen.
Etc. etc.
The meaning of the analogy?
In this case, the controller would be the person – who's responsible for handling certain types of requests. And the “action” would be the particular specific thing that I want done:
e.g.
getting a document or
edit something or even
creating a new document.
Hope that clears things up.

ASP.MVC Permissioning : Is there a way to control partial content ?

I am writing an ASP.MVC application and I know you can use authorisation filters on the cotrollers to control access to the pages but I am wondering what is the best approach to do if you want to control access to protected data within partial views.
From what I have read ASP.MVC doesnt offer this level of granularity.
This seems easily enough by adding the user permissions to the model as an attribute and then using a simple factory to decide if the view should be rendered or a blank view be returned.
So far I have
RenderPartial(PartialFactory.IsAllowedToRender("partialName", Model.Security), Model)
and the Factory either returns the view requested or a blank partial view.
Has anyone tried this before or knows why no one does this (apart from the extra effort)
We have done similarly with extension methods for HtmlHelper.
RenderPartialIfExists and so on. No shame in doing this if its something you are going to need frequently.
Doing it without the extensions as you have works as well, but its not as clean to read. Also, consider adding your security information to HttpContext.Current.Items, that way you don't have to pass it into the models all the time, and anything that needs to take advantage of it, helpers, controllers, etc have easy access to it, and you only have to fetch it at the beginning of a request.

Display/hide menu items depending on logged on user

In my web app, I would like to show an "Admin" menu link only to users who have been added to the database as an administrator.
What would be the best way to do this in ASP.NET MVC 2?
At the moment, I am doing it by checking whether the user exists in the Admin database table for every page. Obviously, there must be a better way to do this.
If it helps, I am using Windows Auth.
You could probably save the admin state in a session variable or something, but it seems more appropriate to create a partial view with the menu (if you haven't already) and just have the check in there. You'll still have a database call for it on each page request, but no duplication of code. And unless you have performance issues right now, one extra call really isn't that big of a deal.
If you do have performance issues, make sure you optimize your own code, have all the correct indices on the db etc. A lot of performance gain (especially in db related problems) can usually be made by re-structuring how things are done, instead of what is done.
UPDATE:
In ASP.NET MVC 2 there is actually an even better way you could do this, combining Html.RenderAction() and AuthorizeAttribute (or possibly write your own inherited attribute that sets a flag instead of returning an error when the user is not authorized). That way you would minimize view logic, and conform better to the MVC principles.

How do I know when to and whether to have a separate controller for a piece of code?

So I am in a situation where I have to decide whether or not to have a separate controller for a particular piece of code. We have a home page that acts like a hub for the rest of the site. The page is accessible to all users (logged in as well as non-logged-in). I was thinking about having home as a separate controller and an action called index. Thinking about this situation, I started wondering if there are any rules or guidelines on this front.
My perception has been that if a code revolves around an entity, separation is needed. (Similar to REST guidelines) If the entity is a noun, it should be a controller. If the entity is a verb, it should probably be an action and should reside in the controller whose name is the same as that of the noun that the verb refers to. Some colleagues suggested that since this is one action, it should reside in the some existing controller and should be named home. I strongly disagreed, however, I could not find a trusted source that would back me up on this.
Would like to know your thoughts.
In this case I have to agree with your co-workers.
REST is a nice approach to take when dealing with resources, as you say. This allows you to create a consistent interface especially with a view to creating a web service.
However REST doesn't actually map too well to a web browser setting. You'll notice for example that even for resources your /edit and /new actions are just GET requests returning an HTML form pointing to the relevant RESTful action. 'edit' and 'new' aren't RESTy at all.
Similarly, the home page is generally a user-friendly amalgamation of various data, not suited to a RESTful interface. So either just stick an extra controller in with one action, or alternatively use an existing controller's 'list' action as the home page
The problem starts with the phrase
If an entity is a verb
If you are attempting to produce a RESTful architecture, an entity cannot be a verb. The only verbs allowed if you are using HTTP are GET, PUT, POST, DELETE, HEAD, OPTIONS. All entities should be mapped to some noun and if you are trying to retrieve that entity you should be using the verb GET. Personally, I would map that to the method Get() on my controller but I don't know if Rails lets you do that.
The quick (and unhelpful) answer is that either way works fine.
I think that everybody comes across this decision at one point, and the decision you make depends on the likely future of the website... which means it's prone to premature optimisation... but that's always the catch,
As you've probably guessed by now, "home" is in some ways a verb as well as a noun, thus why you're having trouble figuring out what to do.
The answer depends on a combination of interpretation of your website structure and how much time is available to you...
if you have very little time to work on this... then stuffing the 'home' action into another controller is often considered the expedient option. It works, it lets you move onto other (probably more productive) tasks.
However, I agree that sometimes it is good to step back and think about what you're doing and whether it could be done "better"...
in this case, though it's harder to define "better" - as it's unlikely that putting the home action in a new controller would be measurably faster... and if it's the only action int he controller... it's debatable whether it's better, architecturally, to just adding it onto an existing controller...
So we start in on what is mostly a philosophical debate... in other words, no answer will be "more correct" than the other- it's more a matter of taste and circumstance. In this case, the debate hinges on making the structure more RESTful.
To be faithful to RESTful architecture, you would indeed move the action into it's own controller... but you'd first have to identify what the entity is. The "home" page is often not readily identifiable as a specific db entity... it's more often a portal-page.
Sometimes you can pick an entity eg online shops will often have a home page that is actually a "products#index" variation, or sometimes the "home" page is a UserAccount#show page... but more often, your home page will not be simple, and will combine information from multiple entities... thus why it is difficult to decide what the "right" architecture will be.
If you cannot identify a specific entity, then there is a valid debate as to whether to move the action into a specific controller.
however, you can always create a new "entity" that is centred around the architecture of the site. This is especially likely if you are going to come up with other non-entity-specific pages for the site (eg T&Cs or an "about our company" page).
The usual fallback being a "PageController" (or similar name) which isn't linked to an Active Record model, but to a more nebulous entity, in this case a "page" which is recognisable to a user of the website (eg the "home page" and the "T&C page" and the "about page"). Each action would be for a specific page...
So, it's up to you as to whether this fits better with your view of the architecture of your system... and whether it's worth the effort... but that's my view on the debate. :)

Resources