ASP.NET MVC Controller design - asp.net-mvc

Let's have an oject structure like this :
Company -> Department -> Person
-> means 1:M relation
Should I have one fat controller which serves all request for this objects or one controller per every object ?
There will be the usual CRUD operations for each object. The details (Department,Person) will be displayed on one page using grids.

If its like an admin type thing, I would just use a single controller or use dynamic data. Otherwise I like to breakdown my controllers based on behavior for example, Room Booking, Time-sheet management etc.

Following DDD - if only Company is aggregate root - then one (but still thin) controller

I don't think there is a direct relationship between your data model and your controllers. I view controllers as groupings of related functionality, from the prespective of the application. What I mean is that I typically create a controller for each big logical chunck of functionality. So if I were creating a contacts MVC web app, I might have:
AccountController (for authentication/authorization)
ContactsController (for the real business case, contacts)
AdminController (for super users to modify the app)
By in my data model I might have tables like, User, Contact, Address, Phone, etc.

I would have a separate controller for each. If one controller (like company) has to pull people information that is fine.
If you really want Render Action. This lets you view call into another controller to load that part of the view.

I usually go with one controller per object per CRUD ... so one controller for Department and one for Person. Why?
You should either have a DTO or Repository for each. If you have a repository:
public class PersonController : Controller
{
private IPersonRepository _personRepository;
public PersonController(IPersonRepository personRepository)
{
_personRepository = personRepository;
}
}
Then use an IoC container (I like StructureMap) for the dependencies.

Related

ASP MVC 4 managing object state in controller

I am new to MVC and am having a conceptual problem with state and object persistence and hope someone can put my thoughts in order.
I have a remote webservice which provides methods to manage orders. An order consists of a header and Lines as you would expect. Lines can have additional requirements.
I have my domain objects created (using xsd2code from the webservice schema), the webservice calls and object serialization all working fine. I've build the DAL/BLL layers and it's all working - tested using a WinForms testbed app front-end.
I have view model objects mapped from the domain objects using Automapper. As the order is returned from a single webservice method complete with lines etc I have an OrderViewModel as follows
public class OrderViewModel
{
public OrderHeaderViewModel OrderHeader { set; get; }
public List<OrderLineViewModel> OrderLines { set; get; }
public List<OrderLineAdditionalViewModel> OrderLineAdditional { set; get; }
public List<OrderJustificationViewModel> OrderJustifications { set; get; }
}
Firstly I'm wondering if I should dispense with the OrderViewModel as if I pass this as a model to a view I'm passing far more data than I need. Views only need OrderHeader or OrderLines etc - not the entire order.
Now my conceptual problem is in the controllers and the views and object persistence.
My Order controller has a Detail Action which performs the load of the order from the webservice and maps the Domain object to the OrderViewModel object.
public ActionResult Details(string orderNumber)
{
OrderViewModel viewModel = new OrderViewModel();
var order = WebServiceAccess.LoadOrderByOrderNumber(orderNumber,"OBOS_WS");
viewModel = AutoMapper.Mapper.Map<BusinessEntities.Order, ViewModels.OrderViewModel>(order);
return View(viewModel);
}
But the Order/Details.cshtml just has the page layout and a call to two partial pages for the header and the lines (I swap the Headerview for a HeaderEdit using Ajax, same for the LinesView)
#{ Html.RenderPartial("DetailsHeaderViewPartial", Model);}
#{ Html.RenderPartial("DetailsLinesViewPartial", Model);}
At the moment I'm passing the model into the main Details container page, then into the RenderPartials, However I don't think that the model should be passed to the main Detail page, as it doesn't need it - the model is only needed in the DetailsHeaderViewPartial, DetailsLinesViewPartial so I'd be better off using #RenderAction here instead and passing the model into the Header/Lines views instead.
However, The Order is retrieved from the webservice in the ActionResult Details() how can I make the retrieved OrderViewModel object available in the ActionResult HeaderDetails() / LineDetails() methods of the controller to pass as the model in return PartialView(...,model) ?
Should I use a User Session to store the Order ViewModel so it can be used across actions in the controller.
Moving on from this stage the user will be able to maintain the order (add/remove lines - edit the header etc). As the webservice call to save the order could take a few seconds to complete I'd rather only call the save method when the user has finished with the order. I therefore would like to persist the in-progress order locally somewhere whilst it's being worked on. User session ?
Many thanks for any advice. Once I've got my head around state management for the ViewModels I'll be able to stop reading a million Blog posts and actually write this thing !
You actually have a few questions here so I will try to address them all the best I can.
1) Dispensing with the view model : I would say no. The view model represents the data that you need in order to populate your view. It seems like you are using the view model as an identical container to the domain model object. So you are asking if you should dispense with it and just pass the domain model to the view while your original concern is that you are passing along more data then you really need as is?
Rather then dispensing with the view model, I would revisit your properties on your view model. Only use properties that you need and create the mapping logic (either with automapper or on your own) for taking the complex domain object and populating the properties on the view model.
summation: build the view model to be only things that the view needs and write mapping logic to populate that view model.
2) This is just a statement of best practice before I breakdown your specific scenario.
You describe your architecture as having a BLL and DAL. If that is the case then you should not be persisting any objects from your controller. The controller should not have any knowledge of the database even existing and the objects used in the controller should have no idea of how to persist themselves. The objects that are going between your controller and the web service should strictly be Data Transfer Objects (DTO's). If you are unfamiliar with what constitutes a DTO then I highly suggest that you do some research and try to build them into your solution. It will help you conceptually see the difference between view model objects, domain objects and data transfer objects.
3) I would not try to store an order object in the session. I would re-analyze how you are breaking up the partial views within the view so that you can call actions with the ordersviewmodel being the parameter in a way that you need. It sounds like you are needlessly breaking up views into partial views.
4) You should not be concerned with state management for the view model object. Your view (which can be comprised of many partial views) is filled based on properties provided by the view model. The user can make changes using the UI you have developed. Since you express the desire to only save once they are finished making all changes to optimize calls to the web service, you just need to repopulate the fields of the view model upon clicking submit. Now you have a "state" for orderviewmodel that represents the users changes. You can send this object to the web service after converting back to a DTO (if you do what I said above) or by mapping it to the domain object.
1 final note. You are using automapper to map your domain to the view model. I am assuming that your view model is too complex and includes things that you don't need because you built your view model to emulate the domain object so that automapper could map by naming convention. Automapper has an api for doing complex (custom) mappings that fall outside of standard same name properties. Don't let automapper constrain you to building your view models a certain way.
Hope this helps

Basic programming with MVC

Wanna get views on a very basic structure as follows:
"Person lives inside town ABCTown. ( ABCTown consists of "Person" visually). And "Person" has information about town ABCTown", ie. he has knowledge about his town.
That's all .
A very basic approach would be making two classes Class_Person and Class_ABCTown . And exchanging references of each other.
public class Class_ABCTown
{
var person:Person ;
.....
.....
public function get personInfo()
{
return person.info() ;
}
}
public class Person
{
var abcTown:ABCTown ;
....
....
public function get townInfo()
{
return abcTown.info() ;
}
}
Now as a programmer, i want to extend the project more towords MVC design pattern. So what do you think, what classes can i add here, and how can i arrange them, to get a MVC design.
( For example Class_ABCTownView can be created to store the reference of PersonView, because visually, person is present inside the town )
Share your views.
Thanks
"Person lives inside town ABCTown. ( ABCTown consists of "Person" visually). And "Person" has information about town ABCTown", ie. he has knowledge about his town.
Based off of this I'd create a Person Class, a Town Class and have them consists of a One-Many relationships (one town can have many people). This is all that is needed for the model.
The Controller is sort of like a pointer that directs all user input to the correct action (so if you click the details button the controller will direct the application to go to the view page and display the model).
The view page essentially is used to display information and forms.
If you want an action to happen such as a person moving to a town, you can put in an Edit action for example in the Person Controller to edit information about a person such as which town they live in. This will cause the application to go to an edit view where users can make changes.
This is a well-known tutorial that teaches you what MVC is and how to use it: http://www.asp.net/mvc/tutorials/mvc-music-store
I think you are misunderstanding the MVC pattern. The code above represents the M part of MVC - the data Model. The V (View) would be the classes, JSPs, etc that present the information to the user, and the C (Controller) is the code that handles user interaction, retrieves the data model from persistence, updates the model, binds the model data to the View, etc.

What's the role of the Model in MVC?

I've read a few articles about MVC but there's one thing that isn't clear to me. What is the role of the model in practical term.
Does the model represent the business object?
Or is it just a class that help send information from the controller to the view?
Take for example two business class (data populated from the database)
Class Image
Property FileName As String
Property CreatedBy As User
End Class
Class User
Property UserName as String
End Class
Will "Image" be the model or should I create a new class?
In the model, should I create a UserName property that will fetch it's data from the User object?
Class ImageModel
Property FileName As String
Property CreatedBy As User
ReadOnly Property UserName As String
Get
Return User.UserName
End Get
End Property
End Class
There are many views on this, but in my experience, there are 2 major views of the Model:
ViewModel
This is a POCO that simply contains all the data necessary to display the View. The data is usually populated by the Controller.
Fat Model, Skinny Controller
The Model does the majority of the business-work. It contains and populates all the data that is needed by the View, and is used by the Controller to save data, etc.
The beauty of MVC
The beauty of MVC is that it's OPEN! You can choose any type of model you want ... you can put all your data into ViewState, into a Model, into a ViewModel that contains a bunch of Models, whatever. It's really up to you. The Model, View, and Controller are blank canvases that can be used however you like.
What I use
My team has done a lot of MVC work, and we have tried many of these different methods. We finally decided that our favorite was the Fat Model, Skinny Controller paradigm.
I believe that this pattern is the best at "keeping it simple" and "don't repeat yourself", and it definitely maintains the "separation of concerns".
Here's how our code is organized:
Controllers
Handles everything that pertains to HTTP requests - redirects, authentication, web safety, encoding, etc.
Gives all "input" to a Model, and gives the Model to the view. Does NOT access Business or Data layers.
Views
Handles all HTML and JSON generation
Only accesses data from the strongly-typed Model
Models
Responsible for making all updates, calling Business and Data layers, loading all data
Handles all validation and errors, and returns these to the Controller
Contains properties of all data that is required for the View, and populates itself
Even though this sounds like a generic principle of MVC, it quickly becomes obvious that MVC does not require these principles, which is why many projects use other principles.
Example
Here's an example Model. The Controller creates it, it populates itself, and the Controller passes it to the View.
public class UsersModel
{
protected UserBusiness userBusiness = new UserBusiness();
public UsersModel(string editUserName)
{
// Load all users:
this.Users = userBusiness.GetAllUsers();
// Load the user to be edited:
this.EditUser = (editUserName == null) ? null : userBusiness.GetUser(editUserName);
}
public List<User> Users { get; private set;}
public User EditUser { get; private set; }
}
All the "user business logic" in this case is in a different project (our "Business Layer"), because we have a large system. But smaller projects don't require this ... the Model can contain business logic, and even data-access code.
There are many models. It both can be business data (or domain) objects (Controller -> Datasource, and vice-versa), business rules (act on domain objects) or view models (Controller to View, and vice-versa).
You don't explicitly have to define the username again in ImageModel.

asp.mvc model design

I am pretty new to MVC and I am looking for a way to design my models.
I have the MVC web site project and another class library that takes care of data access and constructing the business objects.
If I have in that assembly a class named Project that is a business object and I need to display all projects in a view ... should I make another model class Project? In this case the classes will be identical.
Do I gain something from doing a new model class?
I don't like having in views references to objects from another dll ... but i don't like duplicating the code neither.
Did you encounter the same problem?
I usually use a combination of existing and custom classes for models, depending on how closely the views map to the actual classes in the datastore. For pure crud pages, using the data class as the model is perfect. In real world use though you usually end up needing a few other bits of data. I find the easiest way to combine them is something like
// the class from the data store
public class MyDataObject {
public string Property1 {get;set;}
public string Property2 {get;set;}
}
// model class in the MVC Models folder
public class MyDataObjectModel {
public MyDataObject MyDataObject {get;set;}
// list of values to populate a dropdown for Property2
public List<string> Property2Values {get;set;}
// related value fetched from a different data store
public string Property3 {get;set;}
}
I also have quite a few model classes that are just a set of form fields - basically corresponding to action parameters from a particular form rather than anything that actually ends up in the database.
If it is exactly the same project then obviously don't need to duplicate the Project class, just use it as is in the view. But in real life often views have specific requirements and it it a good practice to define view model classes in your MVC application. The controller will then map between the model class and the view model to be passed to the view.
You will likely find differing opinions on this. I will give you mine:
I tend to, by default, reuse the object. If the needs of the view change and it no longer needs most/all of the data in the business object, then I'll create a separate view. I would never change the business object to suit the view itself.
If you need most/all of the information in the business object, and need additional data, then I would create a view that holds a reference to the business object and also has properties for the additional data points you need.
One benefit of reusing the business object is that, depending on the data access technology you are using, you can get reuse out of validation. For isntance, ASP.NET MVC 3 coupled with Entity Framework is nice as they both use the attributes in the System.ComponentModel namespace for validation.
That depends on what you mean by model. In the architecture I typically use, I have my Domain model, which is a collection of classes in a separate class library. I use DataAnnotations and built in validation to automatically validate my model when saving.
Then there is the View model, which I place in my MVC project. View models only have the information relevant to the view. I use data annotations here as well since MVC will automatically use them for my validation.
The reason for splitting the model this way is that you don't always use every piece of your domain model in a view. That means you either have to rebuild the data on the backend or you have to stash it in hidden fields. Neither is something I like,.

Should a model itself do some calculation?

I have been learning ASP.NET MVC for a few months. I have learned about views and controllers and models and stuff. To design a view, we always need a model.
Usually a model is a just a class which we fill with data and pass to a view. I have a question here: Should a model itself do some calculation, or should it just be dumb?
For example, I have a site where I load Books by Users. My model class is as follows:
public class FormViewModel
{
public User MyUser {get; set;}
public Books UserBooks {get; set;}
//Constructor here.
public FormViewModel(User _user, Books _userBooks)
{
this.MyUser=_user;
this.UserBooks=_userBooks;
}
}
This class doesn’t do anything — it’s just a template. Now if I modify the code as follows:
public class FormViewModel
{
public User MyUser {get; set;}
public Books UserBooks {get; set;}
//Constructor here.
public FormViewModel(User _user)
{
this.MyUser=_user;
this.UserBooks=_user.GetBooks();
}
}
which Books are collected depends on which User has been selected. Now it’s much easier to work with.
I just want to know what is a good approach according to MVC patterns and practices.
You want to separate all of your business logic, and data validation into the model. Usually that includes "grouping" datasets and such or filtering data by some criteria.
You want to separate all calls to these methods of the model in the controller, who's responsibility is to retrieve and send data to and from the model. The controller then passes the applicable data set into the view.
The Helpers are logic that is used by the view to do presentation logic (not business logic or validation) such as printing menus and such.
The View is where you will use the Helpers (or not, they are not required to use MVC properly but they do "help" :p) to write HTML, CSS and JS to the browser. You may also separate commonly used view modules into partial views that you can include on more then one view.
You can further seperate things into a ViewModel, but then you are going outside of "strict" MVC. In this case, you would use the ViewModel to help the view interact with the model - basically the ViewModel is a modular controller. In this case, the controller would do much less then what little it does already.
However, this is generally overkill for web applications. Because web apps have a single flow of execution (the request) separating things into a ViewModel becomes unnecessary. However, in GUI code, the ViewModel becomes much more useful (as GUIs have much more then a single flow of execution).
You always want to separate business logic into the Model, period. Remember that you should not couple your controller to your model - so that you can use your model elsewhere in other controllers or even expose it as a web service.
Hope this helps
:)
You can do it a couple of ways, but I'd say the easiest way would be to pass in the reference identifier for the user which you are trying to access through to the controller action (as below) and let it do all the data access calls.
public void GetUserAndDetails(Guid userId) { ... }
Then in this controller action you can look up the user details and the books for this user, set the properties on the view model instance and return it to the view to access.
FormViewModel model = new FormViewModel();
model.MyUser = GetUser(userId);
model.UserBooks = GetUserBooks(userId);
return View(model);
This way the view remains dumb (which it should be) and the model is relatively simple. This also helps with testing purposes.
Hope this helps.
In general, this kind of work should be done in the model. This is for a couple of reasons. First, if getting the user books requires a database connection, you don't want to be doing that from the view - it will just slow it down. The other thing to remember is that there could be multiple views, and you would need to duplicate that code in all of the views (web clients, maybe rich clients, etc).
In the MVC pattern, the views should be the "dumb" pieces. This allows easier use of multiple views and changing views when needed. It's also easier to test code when it doesn't require a view, so you could test the model without bringing up a web client.
Jeff
it is the view that is "dumb". all it does is display the manipulated data.
the controller simply fetches data from the model for the view... again the controller is ONLY a go between.
the model does everything. it stores the data and contains the classes and methods that manipulate it.
When you have a viewmodel that is different from your domain model, you shouldn't map the domain model to the viewmodel inside the viewmodel. It would make the viewmodel class responsible for more than one thing. You can do the mapping in the controller or in a service layer.
Check out this. You are talking about VIEW model, not domain model. There is a huge difference. View model should be dumb, it's just a placeholder for data which allows your views to be more strongly typed. Domain model must be a heart of your app, it must contain ALL business logic.
MVC is a pattern by itself. I really don't have any experience with ASP.NET MVC, but worked several times and used MVC pattern. Sometimes, MVC is realted to other development patterns like heartbeat, memento, state ...
No business logic is allowed for a Model! It's a bad design!
Your logic must be in the Controllers and more exactly: place your logic into the Helpers (the Helpers might consume your BLL and/or DAL) and then use your Helpers in your Controllers.

Resources