ASP.NET MVC Best Practices - c#

I come from the WPF side of the world and I am used to using the MVVM pattern quite a bit. I am attempting to learn MVC and am having a little bit of difficulty trying to understand where my boundries are in MVC. Here is my scenario:
I have 3 objects, Parent, Child and GrandChild. These are custom objects, not using the built in model stuff from MVC. I have a good handle on validation stuff. I have a good handle on how to get and populate my objects. But, I am struggling to find best practices on what to do with Controllers. What should my controller be responsible for? For example, should I have one controller that understands how to CRUD Parent, Child, and GrandChild? Or should those be separated? If they should be separated, how should I do that if, when I am looking at Parent, I want to see a list of Children.

Controller is used only for controlling the flow of the request-response. So, in your example, controller should never know how to CRUD them. CRUD logic should be wrapped in a Repository class of the model.
Take a look at the Official Nerd Dinner example and I personally love this part the most.

The Nerd Dinner app is a clean cut example. I agree with pushing CRUD to a repository, and in general, using the controller only for control flow.
However, in my experience with ASP.NET MVC (right or wrong), the controller ends up doing a lot of rearranging of the data before handing off to the view, and vice versa when accepting an object model as data from a form post. But again, it is just making a translation between what the View needs and what the Model needs.

Related

Are all MVC models lightweight?

So I was first introduced to the idea of a model when I learned WPF. The MVVM concept of a model seems to be more aligned to general 'business logic' encased in a class/set of classes. When I look at MVC though, the model seems to be lightweight-classes that are "passed" to and from the user via forms. Is this assessment correct, or are there situations where a model is something heavier (does more than just hold and validate data input from the user).
You can use Models (classes) as data container (which i usually do) , look at anemic domain model (http://en.wikipedia.org/wiki/Anemic_domain_model), then you can implement business layer, service, data layer independently.
Or you can implement them within your model, which some folks wants to do that due to encapsulation, and several design priciples.
Look into domain driven design as well. (http://en.wikipedia.org/wiki/Domain-driven_design)
Well in MVC or another similar Design Pattern you have defined 3 separate layers of your application. The model with the logic of your objects, the view for showing and getting information from the user, and then a controller witch does the interaction and exchanges between the 2.
MVC is more used for web apps and MVVM with WPF. The reason is that you with WPF can do the databinding of the objects in your View with the one in the ViewModel.
For example a Twiter app: You can do have a model (tweetItem) with all the properties of a Tweet, a ViewModel that gets and stores the tweets in an collection and view that has a list, for showing them, binded to that collection.
There for MVVM or MVC only impact in your app is on how the code is organized.

Should I inject services into my MVC views?

We're working on some kind of Cloud CMS using ASP.NET MVC technology, and have found some obstacles on the way. There is a number of parameters user could change thru the control panel that we need to end up in Views. For example, Facebook application id to initialize the Facebook JS API. Or additional text to be shown on the page. Or background picture. For now we're not using DI to transfer this parameters, instead we're adding them to the ViewModel, but this ruin the ASP.NET MVC way of working with models (e.g. form validation, bindings etc.)
It looks like that using DI to inject services for providing parameters, texts and pictures could make my views less dependent on controllers specific, and there is even some Microsoft technique to do it http://www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-dependency-injection#Exercise2. However, there are a lot of answers on forums against injecting services into Views using DI.
So the question: what is a right way to inject some services into Views? Or I shouldn't do it at all and something is wrong in the application design?
UPDATE: some real code examples (now we're using Model to inject the services)
Injecting texts from database (they have to be user-editable, as it is CMS):
<div class="steps">#Html.Raw(Model.Texts["Main", "Step2"]</div>
Injecting translations from database (actually, it is localization):
<div class="gonfalon">#Model.Translations["Title_Winners"]</div>
Injecting parameters (from database, could be request-specific; for example, if the site has different domains, facebook application should be per-domain):
Facebook.Initialize(Model.Parameters["FbApplicationId"], Model.Parameters["FbApplicationSecret"]);
The problem of current approach is that this code has taken from contest mechanic. It is definitely out of contest business scope to deal with custom texts, translations or facebook application Id. Also it ruins the Model as model models not actual business domain but deals with a lot of things actually belongs to View (like translations and custom texts)
UPDATE 2: Have modified the snippet from the answer below to be a bit more generic:
public static class WebViewPageExtensions
{
public static I ResolveService<I>(this WebViewPage page)
{
return DependencyResolver.Current.GetService<I>();
}
}
No, you shouldn't inject services into Views, but...
For scenarios such as theming where you want to give the theme developer more power, just one model isn't enough. If your model contains the current post for example, how can a theme designer asks for a list of categories for the sidebar? Or for a widget?
In asp.net mvc you can use extension methods to offer that functionality.THe extension method will use the dependency resolver to get the service. This way, you can have the needed functionality in the view without actually injecting a service.
Note that calling the business layer to update the model is still a violation of Separation of Concerns. THe services made available to the view should contain only read model or general utility functionality.
An example
public static IMyViewServices MyServices(this WebViewPage view)
{
return DependencyResolver.Current.GetService<IMyViewServices>();
}
IMyViewServices lifetime configured in the DI Container should be per http (scope) request
No, end of story. Why? Here is why:
Your view only needs to know what the view model it's going to be working with to present that model. There are couple of reasons for this but the biggest one is the separation of concerns. Keep your view as stupid as possible. You will see that this seperation will give you a clean application structure throughout the way.
There is a number of parameters user could change through the control panel that we need to end up in Views.
I'm not sure what you exactly mean here but this is why there are view models. Your business layer will shape models up, your controller will simply map them to your view models and pass them into the view (presentation layer).
This really depends on how much or little you want your controllers to do and to what degree of separation you want to achieve.
In my world, the "controller" in an MVC app does as little as possible because I have a service layer handling all of the business logic and a data layer above that handling all of the database interaction.
On a GET, the controller will simply call a service method that will build the view model and hands it back to the controller and the controller passes it on to the view. On POST, the view posts data to the controller which sends it off to the service layer for validation, saving to DB, etc. The service is injected into the controller's constructor.
I'd be more than happy to post code examples if you'd like to see them.

Why do most ASP.NET MVC examples access the database directly in the presentation layer?

Most of (nearly all?) the examples I find on how to set up an ASP.NET MVC project are accessing the database context directly in the controller.
Like this for example:
public class MoviesController : Controller
{
private MovieDBContext db = new MovieDBContext();
//
// GET: /Movies/
public ViewResult Index()
{
return View(db.Movies.ToList());
}
I also know that there are a lot of controls (at least for the aspx view engine) that you can bind to a table in the database directly as a data source, so that it automatically displays the data.
To me this feels weird and I would like some kind of separation between the presentation layer and the database. Some kind of business layer and/or data layer that maps data from the database to view models, before using them in the view. Is it just me or are the examples all like this because it's easier to do? Is there some great gain that I'm missing? I guess it's a bit faster, but it just feels like I shouldn't use the same models in my database as in my views. I finally found an example that feels more right, where the database models are separated from the view models. But it's one example of a hundred.
What are your thoughts on this?
I understand your concerns as I have the same. It's really a pity that most of the examples out there are not using view models. Because of this people are struggling a lot when they start implementing a real application that differs from the most trivial examples seen in those articles.
As far as directly accessing the database from the controller, I don't think that this is such a big concern. You really don't need to implement lots of layers of abstraction if you don't need them and if they don't bring any additional value to your application. Jimmy Bogard wrote an excellent blog post on the subject of limiting your abstractions.
Most MVC tutorials teach you how to do it simply because it can be done, and that the explanation of the Controller usually comes before explaining the Model.
Take the Movie App tutorial for example - http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/cs/intro-to-aspnet-mvc-3
The majority of these tutorials first teach you how to display data using on the view, then using the controller to display in the view, then entering the data into the model and directing to the view via. the controller.
It's to keep the examples simple and focussed on the subject at hand.

ASP.NET MVC Model Patterns: What works best?

I've done a couple of projects in ASP.NET MVC and there is a topic that I haven't really seen covered anywhere. I wanted to get some other peoples' opinions on this.
What are some best practices for designing models? I've taken two approaches in the past: Should models represent distinct entities, or should you have domain specific (sub-domain specific? view specific?) models? The difference really being models representing distinct entities are used in more than one view where as the domain specific models are tied to specific views.
Consider the following: I have a User entity in my application. Should I have a single UserModel that I use in the Register view, the Show view, the Index view, etc., or would it be preferred to have a RegisterUserModel, a ShowUserModel, a ListUserModel, etc.?
I've used both patterns before. The up side of the domain specific models is that any validation logic applied via attributes can be different between views. The down side is you violate DRY and your models get pretty hairy -- even if you separate them in to namespaces. Conversely, using the single model-to-entity pattern leads to overly generic validation data (usually with regard to error messages) but you have a nice, tight model layer and converting between models and entities is a lot easier (less code).
What approach does SO prefer? Or is there an approach that I'm not even considering?
I like to create my data models and then create specific view models as I need them.
The Case for ViewModel
The ViewModel Pattern
When I think of domain models, I think about business logic as well. I try to keep the M in MVC to refer to the models that assist in the presentation aspect of the application, and not the entities (domain objects) that represent my real-world objects.
Model and View shuld be a pair. Building huge Model classes and huge Views is not good idea. In my opinion in your view-Model you should represent only needed part of your business logic. For example. When you'r creating Registration form make your Model and View that simple as it can be possible - Create RegisterUserModel.cs and RegisterUserView.aspx. Do not pass there whole User object. Make it light, don't break Single Responibility Principle.

ASP.NET-MVC data/model best practices for a newb

I am quite new to ASP.NET MVC and MVC in general. Moving from the old school "spaghetti" design practices to WebForms was a big change, but this seems bigger (but better) in my mind.
I have some questions regarding data specific tasks.
For the sake of simplicity, say I have a database table called PIN with the column structure of PinId INT, Value VARCHAR(50) and another table called Entry with the columns EntryId INT, PinId INT.
I have an MVC view that takes in a string value as a PIN code.
The goal is to insert a row into the Entry table. To do this, I must lookup the corresponding PinId to the provided Value.
My question would be, where do I perform this lookup of data. I can easily do it in the controller where I am performing the insert of a new Entry object but is that right? Should this lookup be performed in the Model somehow?
In addition, I am following the instructions and practices outlined in WROX's Professional ASP.NET MVC 1.0. I have created a DataRepository class which handle all of my DB heavy lifting, and am utilizing the validation class as described in that book.
Any insights would be welcomed as I am a true newbie to MVC.
Cheers and thanks stackers!
Take a look at ModelBinders. This allows you to define how bind inputs from the data you are sending to your action to your Model objects. Your Action can also just take an argument of the type you want to save, and in your ModelBinder, you can do some lookup against the repository, etc.
There are many good blog posts on this if you do a search, now that you know to look at ModelBinder. Scott Hanselman has a good basic one:
http://www.hanselman.com/blog/IPrincipalUserModelBinderInASPNETMVCForEasierTesting.aspx
Never place search, add, update, delete code within a controller. Actually, there should be next to no code in the controller.
In the MVC world the controller is simply a means of getting a model from the view to your business layer and vice-versa. The aim is to have as little code here as is possible.
If you can use Linq2SQl then this would be a great place to put the entities. You can then use your data repository to do not only the heavy lifting, as you put it, but also all the other little things.
Linq2SQL will create a partial class. So, you could create another partial class which will do the CRUD and search work for you.

Categories

Resources