Naming for Conventions for Actions and Views (Revisited) - asp.net-mvc

I'm brand new to MVC and, as a learning exercise, I'm trying to re-write an old application as an ASP.NET MVC application. I'm a little unclear about some conventions which the question Action Naming Conventions only partially covers.
Lets say I have two controllers: JobController and ClientController. Both of the controllers are going to have identical actions: List, Details, New, Update, and Delete.
Should the views for these actions be named identically to the action? In this case the List action for JobController should have a view named "List.aspx" as opposed to something like "JobList.aspx".
The reason this question came to my mind was that I was unsure if its appropriate to have multiple views with the same name (such as "List.aspx"). This will get more and more relavent as I continue adding controllers as pretty much every business object in my system will require a "List.aspx" of some sort.

They won't really have the same name. If it were important to give all our files different names why would we want folders? You actually have a Job/List.aspx and a Client/List.aspx.

Related

Do Actions in RCAV = Model in MVC? (Rails)

I'm trying to better understand the Rails workflow, specifically RCAV in relation to MVC. I know that MVC is the typical structure of a Rails app and that RCAV is the standard order of building various components of the app, however, I'm a little confused about the correlation between the two.
For example, I'm assuming the routes in RCAV are what link the models with views and controller in MVC. Is this correct?
I'm also guessing that the controller and view in RCAV are the same as the controller and view in MVC and simply represent the order in which you build them. Is this correct as well?
What I'm really stuck on is the Action part of RCAV - does this represent the Model component of MVC?
Sorry if my question doesn't make sense, just trying to get a better hang of the standard Rails workflow and the order in which various components of an app are typically built. I wish it were a little more distilled i.e. "first build Model, then Views, then Controller" but this whole separate RCAV thing is confusing me a little.
To your title question, no.
To elaborate, it's kind of confusing to map out RCAV (the sequence) against MVC (the framework), but I'll see if I can clarify. It's worth noting that the concepts themselves are not as complex as they seem, it's just confusing to explain.
RCAV
(Route-Controller-Action-View)
Routes are defined in config/routes.rb. You may think of them as the coupling between an HTTP Request and a Method (a specific type of method called an Action). On the one side it defines a path (ex. "/login") and one of the HTTP verbs (ex. "GET"), and says that whenever that type of request is made to that location, to perform the appropriate action. On the other side, an action is given in the form of the name of its controller (ex. "sessions"), and the name of the method itself (ex. "new").
Controllers receive the request according to the routes (so following the above example, if a user navigated to www.example.com/login, they would wind up in the sessions controller, which would be housed in app/controllers/sessions_controller.rb). The Controller may perform a number of functions prior to (and following) the action, in the form of callbacks. Callbacks are arguably a more advanced concept than what you need to understand right now, they are an important step (and the reason I explain RCAV as "Route >> Controller >> Action >> View", not as "Route >> Controller-Action >> View").
Actions are public methods in the Controller. Again, by our above example, you'll be hitting a method named "new" in the sessions_controller when a user navigates to www.example.com/login. Actions may perform any variety of functions, and there is often interaction with the model here (for instance, you may have a session model in app/models/sessions.rb with a method named "logout", and perhaps the first thing you do when you hit the login page is ensure the user is currently logged out by calling Session.logout. This is a poor design, but a decent example). Your action must "return" in one way or another. Assuming your action is meant to be consumed by a user directly through their browser (as opposed to as, say, a JSON or XML service), you will either render a view now, or redirect_to another action.
Views are, dare I say, the "end result" of the action. If nothing is specified, the above example will end by rendering "app/views/sessions/new.html.erb" for the user (Rails defaults to rendering the view whose path matches the controller and action, but as referenced above you could name something different). In this file you will also potentially make reference to the model associated with sessions (but this time inside of ERB tags, to be compiled into HTML).
MVC
(Model-View-Controller)
Models are classes tied, generally, to tables in a database. They contain validations for their fields, class methods, and instance methods. Say your database keeps track of sessions. Then you could potentially grab a list of sessions by calling Session.all anywhere in your application. You'd probably use an action in the Sessions controller to save this list to an instance variable (maybe #sessions), which could in turn be accessed in its appropriate view (<% #sessions.each do |s| %> ... <% end %>).
Views are essentially the web pages. They can bring along their own styles and scripts, and exist in the form of HTML files with embedded ruby. They are the end point of request made to your site (unless you're hitting a service which returns something like JSON or XML instead).
Controllers contain all the actions a user may access, often prepare variables via methods from the models, and generally drop the user into a view.
In Summation
A user accesses a route. The route drops them into a specific action within a controller. The controller (in the form of callbacks) and the action (on its own) prepare data from the model (via instance variables) to be consumed by the view. The view is then rendered into the users browser.
This is a simplification, but in the most standard cases, this is how the MVC framework (and rails, specifically) functions.

Handling Singular Resource in REST

i have a case where i am actually using some resources that are singular in nature. This is about buildings, so in a city i have a single sawmill and a single town_center.
Now, i am creating everything in a RESTful manner using resources(with :except or :only) where needed. In this case though, i am having a town_center_controller and a sawmill_controller that just have a different show action(they have no other actions).
One can say that a buildings_controller sounds better, but in that case, i would have a single show action to display totally different views(like the one for the sawmill and the town_center). They have many differences and i don't really see how i could stack them in a single controller. However, when i destroy or create a building, i do use the buildings_controller.
I would like to ask you, how would you go about it ? How would you design your controllers ? Would you do what i do and create building based controllers(one controller per each building), or something else ?
I would create a general controller that has the generic functions to support all building cases, like destroy/create/edit, then I would create new controller that inherits from that base controller. This way I will keep my generic functions DRY, and my specific (overridden) functions separate.

Is an abstract CRUD controller a good idea?

We're developing quite a big application using ASP.NET MVC and at the beginning we saw that could be useful to have an abstract base controller with common CRUD actions (new, save, delete...) plus a default list action. In our case we have 20+ entities that are managed through this kind of controllers.
That works and avoids duplicating some code and makes the application more homogeneous but when you see a Controller is difficult to see exactly which actions does it implement and it may implement some actions that should not exist. And for example, imagine you want to edit passing the name and not the id, you have to create a new EditByName(name) and even doing that, you still have the Edit(id) action available because it's in the base.
To me the whole thing smells a little bit to me but I've not found any example showing an alternative because the MVC applications I see have a pretty narrow domain. Any advise? Any example? (I does not necessarily be in ASP.NET MVC, the problem I think is quite generic to any MVC framework).
In some respects I think this is a good idea, but in others I think that it's an abuse of inheritance. I do have a common base controller, but it exists because I've refactored common code from my controllers into it rather than being designed a priori. If your entities are enough alike that the code that you're sharing in the base controller outweighs the cruft that you're forced to drag around, then perhaps it's worth it. If, on the other hand, the code that's being shared is rather minimal and simply invokes a private abstract method that does the work (so that you're implementing it in the real controller anyway), I don't know what it buys you. It's not like you're instantiating your controllers directly anyway (except in your tests) so having a common interface beyond that required by the framework isn't all that important.
My vote would be to refactor into the base class those things that are truly common or are cross-cutting concerns and not try to force an "is-a" relationship that may not really exist.
I created a version of what you're suggesting (though admittedly relatively non OOP) and it's worked very well for me.
I've created a MasterController that sets up a db instance and a few other variables. Once I started looking at the similarities in my CRUD actions, I realized this could be abstracted and moved into a method within the master. Two methods, actually.
protected ActionResult DisplayValidateAndEditModel<TModel>(TModel model, string modelPrefix,
string editViewName, string successActionName, object routeValues, string successMessage,
string[] includeProperties, bool acceptFiles
) where TModel : class
and
protected ActionResult DisplayValidateAndEditModel<TModel>(TModel model, string modelPrefix,
string editViewName, string successActionName, string successMessage,
string[] includeProperties
) where TModel : class
The Edit covers Create/Read/Update and Delete is Delete. Listing is a single line in a controller -- i just get a group of models and add to viewdata.
Both methods check if it's a post. If not, they return the view. If so:
edit calls TryUpdateModel and also does some xVal validation. If all is ok, it redirects to the successAction with any routeValues. If not, it shows the view again. includeProperties can be passed so that my controller can specify exactly what can get updates. And acceptFiles adds additional functionality where it looks for a file posting and, if there, puts it in the database and creates a link between the file record and the model.
delete updates the model's Cancel_Date and Cancel_User properties (I have a ICancelable interface) and redirects to the success action
This is one of the things Rails packs with ( along with generating the relevant CRUD views for you ) and it's great for whipping up a very quick application but once you get serious about development it is very unusual for the vanilla CRUD stuff to stay in because the things you need for each table start to change and need further customisation.
That isn't to say it doesn't form a useful foundation and a convenient way of setting things up while you're developing and prototyping - much easier than tinkering about in database fields - but certainly the way it works with Rails you don't expect to have any of those pages in your final administration system.
To me the whole thing smells a little..
The same smell here :-)
It is common pratice to have little code in the controller. Its main purpose is to decide what View is rendered with which Model next.
If you wish to have a common place for all the controller code it shows, that you probably have to much logic in the controller.
Try to move the logik into the Model. Use Filters and CustomModelBinder.
Just a though: As you know ASP.NET MVC supports basic scaffolding like Ruby on Rails. What you may consider is to customize the T4 files used to create the Create, Update, Details Views to meet your specific needs.
http://blogs.msdn.com/webdevtools/archive/2009/01/29/t4-templates-a-quick-start-guide-for-asp-net-mvc-developers.aspx

ASP .NET MVC - Number of Controllers

Should there be a separate controller for each table that needs to be manipulated in a system?
As an example, in designing an administration section of a content management system, should there be a separate controller for configuring each look up domain as follows:
/DataTypeA/List --list for A
/DataTypeA/Create -- create new data
.
.
.
/DataTypeB/List --list for B
or should there just be separate actions within an Admin controller as follows
/Admin/DataTypeA -- this lists DataTypeA
/Admin/DatatypeB -- this lists DataTypeB
/Admin/DataTypeA_Create -- Create a new DataTypeA
/Admin/DataTypeB_Create -- Create a new DataTypeB
My approach is to create a new controller for the primary actors (tables) in the system. Ancillary tables end up begin updated by the controller for the primary table that the ancillary data is associated with. For example, I would have a User controller and have an action to update the UserContact information that is associated with a particular user in the User controller rather than create a separate UserContact controller.
I find the bets way is to once you get to the presentation layer (web layer in this case) you should group logically rather then technically. If you have a Product and Category table you may want to make a Catalog controller, or a Store controller. This will help and allow you to reuse a lot of code and keep things organized.
Basically it depends on what you're after and how you want to organize your code. If DataTypeA is distinctly different than DataTypeB (i.e. Animals vs. Automobiles) then you'd probably want to use different controllers. But, if DataTypeA is a subset of (or similar to) DataTypeB, then I'd use one controller with different actions.
ASP.NET MVC is so flexible it is very cool, though admittedly, at the beginning, the flexibility feels like you're drowning. Just start writing code and you'll realize if you're headed down the wrong path. There is a learning curve to MVC. Go with it.
I think it's largely a design choice. I don't think there's a clear-cut answer, although I guess if you were sticking to the letter of the pattern then you would go for the one-controller-per-datatype option.
I started to put together a small prototype blog system to try out ASP.NET MVC a little while ago (still a WIP, sadly), and one design decision I ended up making was to subsume the Comment controller into the Post controller. I only decided this after having tried separate controllers, however. I think this worked because the two concepts are so tightly entwined: you can't have a comment without a blog post.

When should I create a new controller class in ASP.NET MVC?

I'm learning MVC and am having trouble deciding when I should create a new controller versus just adding an action and view associated with an existing controller. On the one hand, Single Responsibility would seem to say a controller should be limited to a few actions. When I try this, though, the number of classes grows exponentially (model, views and controller for each)- to the point I wonder if I'm going overboard.
For example, the default AccountController has Login, ChangePassword, and Register actions. I would tend to instead create a LoginController, PasswordController, and ProfileController, and related model classes. So where there was 1 class, there would be 3-6.
Is there any good rule of thumb on this?
You should dedicate a controller for each model type you're manipulating. The controller acts as a collection of actions that act upon those models. This is generally the rule of thumb, but sometimes a controller's scope transcends a single model.
The AccountController deals with all things authentication related. This is an example of going beyond a single model's scope to encompass authentication in general. What are the key parts of authentication? Retrieving users, changing passwords, etc.
I think you need to be pragmatic about it. I'm working on a project that consists of a StatsController. The number of actions is continuously growing (RandomStat, MostPopular, MostViewed, MostVoted, etc...) the list goes on and on. These actions are simple to satisfy since the StatsController's dependencies don't change. I'm using an IoC to satisfy what my Controllers need and when I start to see my Controllers needing references to new objects, this is a signal that they need to be broken apart.
If your LoginController, PasswordController, and ProfileController all rely on the same objects, why break them apart?
My current AccountController has 12 methods which to me is completely manageable.
I have another controller which currently has 34 methods but those are all tied to a single view and they each have around 8-10 lines of code max (check required parameters, update the model, and redirect as necessary).
They key is to encapsulate your business logic in an entirely separate module. That will allow your action handlers to remain extremely light weight and can make testing your business logic easier.

Resources