ASP.NET MVC: Structuring Controllers - c#

So I'm embarking on an ASP.NET MVC project and while the experience has been a good one overall, I'm not quite as pleased with the spaghetti mess that my controllers have become. I've looked around online (CodeCampServer, etc...) and they all seem to suffer the same issue wherein controller methods violate SRP (single responsibility principle) pretty consistently - such as a controller method that simply renders the view if the request is a GET but updates the model if it's a POST. Now I've got controller methods responsible for multiple logical routes throughout the application - say it checks for which button was clicked on the form and acts accordingly. I could redirect each button click to a different form action using JavaScript, but something doesn't feel right there either... The other big issue is the proliferation of magic strings - ViewData["foo"] = blah; Long story short, how do you guys structure your controller logic? One giant model object per view? Lots of little controller methods and JavaScript is the router? My goal is maintainable code - as features get piled on I'm starting to slide down that slippery slope...

ASP.NET Preview 5 (available on CodePlex) has an answer for this: the [AcceptVerbs] attribute. Phil Haack has a blog post discussion how it's used.
As for the view data magic key question, it's an interesting problem. If you think of a view as being a bunch of semi-independent components (especially in light of the new partial view support), then making a strongly-typed model becomes less ideal, as the several pieces of the view should be relatively independent of one another.

How are different people handling this issue? I know that i just spent a couple hours reviewing the jumble inside of the model folder. I'm finding creating folders is helpful in reducing the visual clutter, using matching namespaces helps alot too.
But my controllers are monoliths at the moment. the trouble is that i've been focused on learning to this point in the project (still lots to sort out as well).
I'm getting a good handle on MVC now, so it is time to review the complexity and consider modifying the controllers up into better named and cleaner functions.
Are other people breaking their controllers up into sub controllers? (If there is such a thing)

Related

Understanding application flow with MVVM

I am having a hard time understanding how MVVM is used in case of more complex applications. All the examples I can find are extremely basic Apps.
Let's say I have a "Package Delivery" application. To perform a delivery I have to do 3 steps:
Scan the package
Enter any damages or problems with the package
Let the recipient sign on the device
All this information gets validated on the device and then sent to the backend.
In MVC I would implement this like this:
The DeliveryController handles all of the logic. This includes navigation between pages, fetching of API data and validating all of the data once it is all collected.
The controller acts as the "Connection" between the Views and collects all the information and brings it together.
But how would this be done in MVVM? Where would all the data be brought together? Most implementations of MVVM I can find do something like this:
In this, the data entered in each View would have to be passed to the next ViewModel until the end of the chain is reached. At that point the SignatureViewModel would do the validation and make the API call. That seems very weird and like it would get very confusing, since data would just be "passed through" multiple ViewModels just to have it at the end of the chain.
Another option I see would be that each ViewModel handles it's own data:
Here for instance the DamagesViewModel would validate and send the data it's own View handles. The big issue with this is that data does not get sent as a whole. Also there can not be any validation of the entire data before it is sent.
My last idea would look like this:
This adds a DeliveryViewModel that essentials acts like the DeliveryController does in MVC. It would handle which ViewModel to navigate to next, handle what API calls to make and validate all the data once it is entered.
To me (as someone who has mostly used MVC) this last options seems most sensible. But I also feel like it might miss the point of MVVM.
How is this usually done in MVVM? I would really appreciate any pointers. Links to articles that explain this well are much appreciated.
Also if anyone knows of any publicly available repositories or projects that have this kind of pattern in them, I would love to see them.
Even when using MVVM I still use some form of a controller and consider ViewModels as basically transformation of data to facilitate the view.
So for me there is still a service or controller layer that completely separates the middle and back end tier from the rest of the architecture.
View models come into play depending on the consumer/app - fetches data from the service tier, transforming the data, validating etc for the purpose of a consumer/app/etc.
I have struggled quite a bit with the same thing. Especially since I’ve used MVC quite a lot.
I think the most important thing to consider is that MVVM is not meant to solve exactly the same things as MVC. You can still implement a controller outside of this pattern to complement it. It also changes quite a lot the general design of the application.
One mean to do it that I have used is to implement the controller as a singleton that can be shared between VewModels. This controller can per example be injected into the ViewModels using dependency injection.
Viewmodels could then for exemple subscribe to events coming from the controller to update.
But this is one way to solve this problem among others.
MVVM is a way to organize code. It’s one way to separate your user interface from your logic.
I have found a blog where you can have a look where MVVM architecture is described perfectly.Though here writer demonstrates MVVM for windows form app but at least you can get some idea about architectural design of MVVM.
https://scottlilly.com/c-design-patterns-mvvm-model-view-viewmodel/
Also please have a look into this repo.
https://github.com/MarkWithall/worlds-simplest-csharp-wpf-mvvm-example

What is the correct method of design in a MVC project in regards to the model, view, and controller directories?

I am in the starting stages of moving from NET c# to MVC, and am wondering about something. I see all of these examples and cases where the code is not organized in any manner within the three primary directories (Model, View, Controller). For example, is it bad practice to have my project design such as "root/Controller/Employee/[multiple controllers for employee, and then root/Controller/ProjectPhase/[multiple controllers for project phase objects], or is it assumed that this need should not be necessary according to the already efficient design implementation of the standard MVC project. Maybe I am overlooking/complicating this or prematurely asking this question, and should give it some more time and or reading/research, but was curios on the topic.
Thanks in advance
All controllers should be directly below controller folder. If you want to segment your controllers, you need to use Areas. With Areas you can have multiple trees of models views and controller.

MVC Controller Organization

I've inherited a project in which I'm the fifth proverbial 'cook in the kitchen'. The project is too mature for extensive changes on my timeline, but I'm thinking I can at least get rid of some of the "where was that code again!?" issues I'm having.
All of the controllers are dumped in the same Controller folder, but there are enough with similiar names to be a bit cumbersome. Additionally some of these controllers are solely for partial views. The admin page for instance has its own controller, but each of the four tabs on its view have their own model/view/controller. What are some recommended approaches I should take to get this under control?
If you're looking to organize your MVC project, I find Areas an invaluable way to keep things from getting out of control.
It might mean changing some of your paths, but I'll leave it to you to determine the value to your particular project.
Have a read of this: http://msdn.microsoft.com/en-us/library/ee671793%28v=vs.100%29.aspx

How to make one ASP.NET MVC site "derive" from another

My question is similar to "ASP.NET 2 projects to share same files", but with an ASP.NET MVC slant.
Basically, we have two sites, one being based mostly on the other (roughly 90% views, controllers, images, in the second are identical to the first). However, in some cases, the views may be different, or a controller in the second site may be different to the first.
Are there any simple ways of achieving this in ASP.NET MVC?
So far, we've looked at using linked files to have two totally seperate projects where the second project shares the files it needs from the first.
One problem with this approach is that most pages in the second project don't literally exist in the virtual directory, it makes debugging a pain - you have to publish in order to generate the files so you can debug.
Does anyone have any better approaches, or ways this approach can be simplified?
This article might help: http://dotnetslackers.com/articles/aspnet/storing-asp-net-mvc-controllers-views-in-separate-assemblies.aspx
Essentially, it involves creating your own WebFormViewEngine which tells MVC where to look for the Views.
If they are 90% the same and you want to keep them in sync as functionality evolves I would consider making them into a single web application and using the host header to differentiate and to change the images/links/text/functionality/etc. between the two sites.
You can do this in your BaseController: look at the host header and create a Brand object that every page and view has access to, just like it might have aUser object. That Brand object can include the name of the site, the canonical Url for the site, the location of the image directory for that brand, boolean values to turn certain features on or off, ...
Now in a Controller you can just ask if (Brand.SupportsPageX) {...} to decide what to show next. And if you make the brand object part of your base view model or put it in the view collection you can have views that use the brand's name, image directory, ... to customize how they look.
Put as much as possible into a shared non-UI library project. I do that on every project that I work on this, increased testability, shared code with Windows Services, and a host of other reasons.
I've found that if you're aggressive with this then quite often over two-thirds of the project would be in the non-UI shared library.
After doing this, you can take things a step further and create a second library with some shared MVC/UI elements.
Depending on your opinion of it, RenderAction may help a bit here. As you know, RenderAction will allow you to group up those controller/view components and pass in variable arguments at runtime.
A project I'm working on currently has a similar requirement and we have started looking at using portable areas. I personally haven't delved very deeply into them at the moment, but it may be worth you taking a look.
I've been working with areas to create multiple websites that I can host with one hosting account. I would think you could use a similar approach. By implementing the common functionality in the base project, it will be available to each area. You can also override any of the base views or controllers by implementing them in the area. It may require some tweaking of the ViewEngine and Routing but I think it could be done.

How to fight against really big controllers . .

I have an winforms application that was built using MVC. The controller is subscribing to all of the events from the view (button clicks, etc) and connects multiple views with the model.
The problem is that the controller is now about 3000 lines of (hard to unit test) code.
What is the best practice to avoid getting controllers to do everything and become so big?
One obvious thing to point out might be that one controller does not have to be implemented as one class. The MVC design pattern simply states that M, V and C are separate components, but not that each must be one, and only one, class.
Sub controller
Controller can be split in various sub-controller without broking the MVC pattern.
At 3k lines, it's for sure that the cohesion is broken somewhere. Try to group together same behavior and create new controller. This way, you will have a "main" controller that will invoke "sub" controller.
Method without sub:
For my own experience, I do not have 1 controller for the whole WinForm application. How I created it is that I have mutiple module that are loaded from the menu. When those module are loaded (Form->View) it comes with its own Controller. This way, I only have 1 controller for each module. Those controller aren't over 500 lines of code usually.
Depends on the situation, but assuming you are not at a point where a new controller should be created there are several approaches.
Much depends on your setup. One common approach is to have a service layer or service agent which would do work for the controllers that is not specific. The use of interfaced helpers or even static ones should remove some of the repetition. 300 lines does not sound to bad at all assuming it is broken into testable methods.
I would be interested too to hear of other opinions other than the oft repeated mantra of creating more controllers. We use MVP and have experimented with sub controllers but this does rely on careful usage and is probably a bad idea.
It is common to have one controller per module in MVP, which would relate to a logical part of your application. There should be a few clear ones within your domain and a few that are maybe a bit more difficult to distinguish.

Categories