MVC architecture large action method on controller - asp.net-mvc

I'm currently developing business logic in a Controller's ActionResult function, and I've noticed it's becoming unwieldy... large... involves a lot of page ups/downs.
Code includes populating lists for dropdownlists assigned to ViewBag properties, but most of the size is taken up EF (linq to entities) and in memory processing of this.
And finally sent to a view model via Auto Mapper.
Where is the best place to move this code? In another class in the Controllers folder? Or in another class in another folder, i.e. a Business layer?

Separate you project to :
WebUI(View, Controller-A MVC Project)
Business Layer(Holds Business Logic - A class Library Project )
Data Access Layer(Holds Entity Model(May be EDMX) - A class Library Project)
A controller of WebUI project call method of business layer.
If business need data from database then, it will call Data Access Layer.

Funnily enough I answered a very similar question yesterday. In a nutshell, limit your controller to just the minimum logic to link your models with your views. Business logic, data access etc. is better placed in a separate repository.

Bappi Datta is right. Let me just explain it from my point of view.
My best practice with the libs AutoMapper, EF is:
Web - includes logic of rendering, some validation, bootstrap configuration. Calls Business layer methods and classes.
Web.Models - web models with validation attributes
BusinessLogic - business layer. Includes mappings EF Entities <---> Web.Models. Uses Data classes.
Data - Here I always put EF Models and context. Also implementation of Repository pattern could be placed there.

You need to have Repository Layer (which you mentioned you already have) and then you need to have a Service Layer which will hold all your necessary business logic probably using patterns like Command Factory and Facades. Then in order for you to have a flexible and easily pluggable architecture, you need to use Dependency Injection between all layers.
Read about MVC architecture in my perspective
There can be different If's and But's in the theoretical discussion of overall MVC architecture itself. But generally your controller actions needs to be thin, you business logic needs to be in a different layer other than repository.

Related

MVC project setup at the enterprise level. What's expected?

By reading at several articles posted here, I get mismatched information about how to properly configure a project.
I am looking for advise about how the pros do it at the enterprise level.
I see different schools of though about this, some people design in a truly N-Tier fashion, others prefer to use EF Code First directly in the MVC application and have FAT models and sort of have one big MVC app with logical separation of concerns, etc.
So for a mid-size project this is my set up and I want to ask for your opinions about it.
MVC application
Models -- Here my models have just what the view needs, validation logic, etc. These models are designed to pass data between the controller and views only.
Controllers -- Call the service layer where business logic lives and gets domain models back if needed. Converts domain models into view models and vice-versa.
Service layer
This is were the business (domain) logic lives.
The service layer is also in charge of communicating with the data layer to perform CRUD operations.
The service layer returns domain models to the controller in the MVC application and also expects domain models when invoked.
Data Repository layer
The data layer is a thin wrapper around EF and performs CRUD operations.
usually I will have a Code First approach where entity models are created for me by EF.
I convert the EF code first models to domain models and return these to the service layer.
The data layer also expect domain models from the service layer that in turn I convert to EF code first models and persist to the DB.
Domain Model layer
These are the domain models that are used and shared thorough the applications layers.
What's best design?
What's expected at the enterprise level?
There's nothing particularly wrong with the approach you've laid out. However, I do see it as overly complex. Your repository layer, in particular, is a totally unnecessary level of abstraction. You could simply just roll the EF stuff into your service layer and call it a day. Having to convert the entity into a domain model and then to a view model, is frankly, a pain. Just map your entity to your view model and back.
The only thing you should really bear in mind is that ASP.NET MVC very loosely follows the MVC pattern. There's no such thing as a true MVC Model, and trying to force something like an entity class into that mold is a huge mistake. Your Model is the combination and interaction of your entity class, view models that represent that class, and the querying logic you tuck away in your service layer.
I would like you to suggest have these layers in your project ----
Entites Layer--
it should contains only all your poco classes in a model folder.Nothing else
Data Layer----
It should contain Db interactions logic.
Also your Dbcontext class should reside in this.
You may use Repository Pattern and unit of work pattern for better seperation of concern.Use dependency injection to resolve dependencies using Unity Container(there are many other container also available).Please have a look on these design pattern and container.there are many articles available on net for this.Simply go through them thoroughly.
Service Layer ----
It should contain only service methods to call into your controller as your controller should not directly talk to data Layer.Its a much better approach and prevent your business logic from being exposed to external attacks.
MVC Layer or UI layer ---
It should contain only the controllers whose work is to call services and business logics inside them.
and View folder where we have all the views to be shown to the end users.
Its a pretty big question.I hope may be u get some idea from this.

Service layer and project structure in ASP.NET MVC 5 without repository and UoW patterns

I'd like to create a good app in ASP.NET MVC 5 using EF 6 Code first concept. I want it to be well-designed i.e. having generally speaking: Presentation, Logic and Data layers separated. I want it to be testable :)
Here's my idea and some issues related with creating application
Presentation layer: It's my whole MVC - view models(not models), views, controllers
I believe that's validation should be done somewhere else (in my opinion - it's a part of business logic) but it's quite convenient to use attributes from the DataAnnotations namespace in ViewModelds and check validation in controller.
Logic layer: Services - classes with their interfaces to rule business logic.
I put there functions like: AddNewPerson(PersonViewModel Person), SendMessageToPerson(...).
They will use DB context to make their actions (there's a chance that not all of them will be relying on context). There's a direct connection between service and db - I mean the service class have reference do context.
Where should I do mapping between ViewModel and Model? I've heard that service is a bad place for it - so maybe in controllers. I've heard that service should do the work related with db exclusively.
Is it right? Is my picture of service layer is good?
Data layer: I've read about Repository and UoW patterns a lot. There're some articles which suggest that EF6 implements these two things. I don't want to create extra code if there's no need for such a behavior. The question is: am i right to assume that i don't need them?
Here's my flow:
View<->Controllers(using ViewModels)<->Services(using Models)<->DB.
**I'm gonna use DI in my project.
What do you think about my project structure?
There is no reason to use a Unit of Work pattern with Entity Framework if you have no need to create a generic data access mechanism. You would only do this if you were:
using a data access technology that did not natively support a Unit of work pattern (EF does)
Wanted to be able to swap out data providers sometime in the future.. however, this is not as easy as it might seem as it's very hard NOT to introduce dependencies on specific data technologies even when using an Unit of Work (maybe even BECAUSE you are)... or
You need to have a way of unifying disparate data sources into an atomic transaction.
If none of those are the case, you most likely don't need a custom Unit of Work. A Repository, on the other hand can be useful... but with EF6 many of the benefits of a Repository are also available since EF6 provides mocking interfaces for testing. Regardless, stay away from a generic repository unless it's simply an implementation detail of your concrete repositories. Exposing generic repositories to your other layers is a huge abstraction leak...
I always use a Repository/Service/Façade pattern though to create a separation between my data and business (and UI and business for that matter) layers. It provides a convenient way to mock without having to mock your data access itself and it decouples your logic from the specific that are introduced by the Linq layer used by EF (Linq is relatively generic, but there are things that are specific to EF), a façade/repository/server interface decouples that).
In general, you're on the right path... However, let me point out that using Data Attributes on your view models is a good thing. This centralizes your validation on your model, rather than making you put validation logic all over the place.
You're correct that you need validation in your business logic as well, but your mistake is the assumption that you should only have it on the business logic. You need validation at all layers of your application.. And in particular, your UI validation may have different requirements than your business logic validation.
For instance, you may implement creating a new account as a multi-step wizard in your UI, this would require different validation than your business layer because each step has only a subset of the validation of the total object. Or you might require that your mobile interface has different validation requirements from your web site (one might use a captcha, while the other might use a touch based human validation for instance).
Either way, it's important to keep in mind that validation is important both at the client, server, and various layers...
Ok, let’s clarify a few things...
The notion of ViewModel (or the actual wording of ViewModel) is something introduced by Microsoft Martin Fowler. In fact, a ViewModel is nothing more than a simple class.
In reality, your Views are strongly typed to classes. Period. To avoid confusion, the wording ViewModel came up to help people understand that
“this class, will be used by your View”
hence why we call them ViewModel.
In addition, although many books, articles and examples use the word ViewModel, let's not forget that it's nothing more than just a Model.
In fact, did you ever noticed why there is a Models folder inside an MVC application and not a ViewModels folder?
Also, ever noticed how at the top of a View you have #model directive and not # viewmodel directive?
That's because everything could be a model.
By the way, for clarity, you are more than welcomed to delete (or rename) the Models folder and create a new one called ViewModels if that helps.
Regardless of what you do, you’ll ultimately call #model and not #viewmodel at the top of your pages.
Another similar example would be DTO classes. DTO classes are nothing more than regular classes but they are suffixed with DTO to help people (programmers) differentiate between all the other classes (including View Models).
In a recent project I’ve worked on, that notion wasn’t fully grasped by the team so instead of having their Views strongly typed to Models, they would have their Views strongly typed to DTO classes. In theory and in practice everything was working but they soon found out that they had properties such as IsVisible inside their DTO’s when in fact; these kind of properties should belongs to your ViewModel classes since they are used for UI logic.
So far, I haven’t answered your question but I do have a similar post regarding a quick architecture. You can read the post here
Another thing I’d like to point out is that if and only if your Service Layer plans on servicing other things such as a Winform application, Mobile web site, etc...then your Service Layer should not be receiving ViewModels.
Your Service Layer should not have the notion of what is a ViewModel. It should only accept, receive, send, etc... POCO classes.
This means that from your Controller, inside your ActionResult, once the ModelState is Valid, you need to transform your ViewModel into a POCO which in turn, will be sent to the method inside your Service Layer.
In other words, I’d use/install the Automapper nugget package and create some extension methods that would convert a ViewModel into a POCO and vice-versa (POCO into a ViewModel).
This way, your AddNewPerson() method would receive a Person object for its parameter instead of receiving a PersonViewModel parameter.
Remember, this is only valid if and only if your Service Layer plans on servicing other things...
If that's not the case, then feel free to have your Service Layer receive, send, add, etc...ViewModels instead of POCOs. This is up to you and your team.
Remember, there are many ways to skin a cat.
Hope this helps.

ASP.NET MVC - Model in Web project

I'm new to ASP.NET MVC and inherited a project that uses the technology.
Such Web project contains three folders: Views, Controllers and Model. As I understand it, the Model contains in fact your domain / business logic and is called by your controllers. The controllers themselves act as delegators between Views and Model.
Now, in a typical layered architecture, there should be no references in any project to the Web/UI project.
I find this quite confusing:
-> The UI contains the Model, which is - in an ideal world - based on "Domain Driven Design"-principles.
-> The layers on top of the UI (Services and DataAccess) cannot have a reference to the UI
How can you write efficient services and dataaccess layers if they do not know your model?
What am I missing here? Is the Web.Model different from "DDD" and should I still have a separate BL project? If that is the case, then what is the Web.Model supposed to contain?
I view the Model as a concept. You can have a completely separate project containing your Domain (your entities, your services etc.) and reference that in your "UI" project. In this scenario this will be your "Model".
This is what I typically do, In my Models folder I keep "ViewModels", which I use for Binding/Validation (for the UI).
For example, If I have an Employee but I don't necessary want to use all its properties (or for that matter different properties), I will create an EmployeeViewModel adjust it the way I want, I'll add validation (if required) and I'll pass it to my View.
This is by no means, "the right way"/"only way", but It worked for me in the past, and I thought I'll share (also, I'm pretty terrible in explanations, so I really hope this post makes sense, in case it doesn't or clarifications are needed - please let me know).
You necessarily do not need to have your model in the same project. You can ofcourse have those in different layers.
This is how i usually setup my projects
1) UI Project - This is an MVC Web application type project where i will have my controllers and it's views and other UI related stuff
2) Business Entities - This will be a class library type project where i will define my domain objects ( Ex : Customer). This mostly looks similar to how my DB schema looks like. These are usually just POCO's which represent my domain modal ( I use this for the CodeFirst Database generation).
3) Data Access - This will be another class library type project which has the data access classes. Usually my repository class/interfaces, my DBContext class and other data access classes will be in this project.
4) Tests - Unit tests for the project
Business Entities project has been added as a reference to the Data Access Project so that i can use those classes in my Data access code.
Business Entities and Data Access Projects are added as references in UI Project. I would call the data access methods from my Controllers/ Service classes.
You may also add a Service/Business logic layer between your controller's and Data access layer as needed.
I have few ViewModel classes also inside my UI project ViewModels folder. I use this for some screens where i have to show data from multiple domain objects. I have a mapping/service class which maps the domain object to view model object. If your project is bifg, you may keep this as a serperate project under the same solution
Views Contain your HTML Layouts
Controllers do the heavy lifting of getting data from the models or the models themselves and passing them to the Views.
Models are used to do actions for your BL or fetch data.
Tip : You can use a EntityFramework ( i'm recommending it because it's easy to get started with ) to fetch your data and it's dead simple to setup thus eliminating your DAL and saving you time from writing everything yourself.
Services : you can have controllers that return XML/JSON (other format?) by converting the data you have got from the DB to XML/JSON and returning that instead of a view.
Take a look at MVC 4 WebApi for more details,Note that you can pretty much the same thing with mvc 3 too
Also refer to asp.net/mvc site for tutorials to get you started, they are really useful.

ASP.NET MVC - Model can have business logic?

I read a couple of articles which defines domain model (as in MVC) as something that holds business logic. I never considered a model to hold any methods other than the model properties.
I would like to know if actually there is a thought which supports having functions and business logic in the domain models.
Thanks in advance.
Of course business logic should be inside domain models. But, domain models are more than just entity framework entities. Domain models consists of many small classes which reflects business domain.
In my typical MVC application, I usually split some type of business logic into these (but not limited to):
ViewModels which responsible for model for view.
Controllers which is thin and responsible for application flow.
Simple business logic such as required field can exist as attribute within entity framework model or ViewModels.
Complex business logic such as place order, booking ticket are promoted to be its own class such as PlaceOrderOperation or PlaceOrderCommand.
Simple query logic might be inside the Controller or short extension method to DbSet<Entity> type.
Complex Query also promoted to its own class such as GetMostPorpularProductsQuery assuming that the query is complex.
Infrastructure components may be extension to Entity Framework or MVC components such as ActionFilter, CustomRoute, CustomTemplate or its own classes such as EncyptionHelpers etc.
Conclusion
Building domain Model is more than just creating classes prefix with BusinessLogic such as UserBusinessLogic or with Services such as UserServices. It should consists of many small classes which responsible for one thing. Of course, you would require some usage of design patterns, choice of frameworks, infrastructure components such as error handling, localization, caching, etc.
Welcome to the trade-off world. :)
An MVC Model can indeed have business logic. MVC responsibilities been discussed in more depth here and here is a discussion on anemic domain models - this might help clear things up for you?
From MSDN:
Models, which is provided for classes that represent the application
model for your MVC Web application. This folder usually includes code
that defines objects and that defines the logic for interaction with
the data store. Typically, the actual model objects will be in
separate class libraries. However, when you create a new application,
you might put classes here and then move them into separate class
libraries at a later point in the development cycle.
What might be confusing the issue is that many ASP.Net MVC implementations use View Models, which are classes used to transfer presentation tier data between View and Controller.
In a typical large project setup, we usually delete the Models folder, and instead move our EF data layer, Entities, and business / service logic into separate assemblies entirely.
Based on my experience best place to place business logic is layer between controllers and models. Try some popular patterns, like repository or tasks/commands.

How can I extend the Model in ASP.NET MVC and Entity Framework?

In my first ASP.NET MVC applications, the model was a simple O/R mapping between a table and the classes, managed by the Entity Framework.
Now I would like to add some meat to this skeleton, and introduce business methods for the generated classes. What is the recommended approch to this in ASP.NET MVC (with Entity Framework)? My favorite would be solution which also can be used in a service layer, with no ASP.NET MVC references, so that the same domain logic also could be reused in a desktop client.
Technically, I think it should be possible to extend the generated classes in a way which preserves the additional business logic even if the O/R classes need to be refreshed. (This is more a question related to the Entity Framework however.)
Edit: Many thanks for the contributions, and the information about the next version of Entity Framework (4.0). Building two sets of classes, one auto-generated to represent the data in the persistency layer and one for the actual business logic sounds interesting.
Within MVC.Net, the model is the least clearly defined part. In my opinion, it's basically the rest of your application (i.e. anything not related to the View or the Controller). The O/R Mapping part of your application should probably be outside of the "Model" also, as this is more of a data layer. The Model, should really deal in business objects and create views of your data to pass to the View.
There are lots of differing opinions on this, but I think it's best not to think of MVC.Net as traditional MVC Architecture.
If you are using EF v1.0 right now, the Entity Framework is very intrusive into your application, which means that you cannot create POCO very easily. The way you can extend your model is by using the partial class. So when you refresh your model, the partial class you did will still be valid. The Entity Framework team realizes this is a problem , and have improved this in next version (EF V4.0).
NHibernate is much more friendly and allow you easily extend your business logic.
I really think this blog post by Jeremy D. Miller is very good at pointing out the problem.
Abstract your Business Layer out into another project, then pass an instance of it onto your mvc controller using something like structure map. You can then call this Business Layer from your controller to retrieve your business entities (Model) and pass them on to the UI. This will allow you to resuse your Business Layer in your desktop application.
Not only meat but also some clothes and a style could be added to this project to make it seem chic. It depends on the time you have for the project. If you have time, I could suggest you to get a look to TDD and the frameworks that could be used with TDD such as Castle, NUnit, Moq etc.
As you mentioned a service layer is a must for any project but with these kinds of frameworks you could design your architecture more robust.

Resources