I’ve been working on a ASP.NET MVC project with LinqToSql. The application has 3 layers: UI, Business and Data.
The last few days I was implementing (I’m still are) a Excel file upload. So my Controller receives the file uploaded, does some stuff, pass info to Business and then to Data. But, along with the development of that, some doubts came up.
Here are some of my doubts (I think the bullet is the easiest way to show):
-
The Excel file must be validated. The application must validate if the worksheet values are correct and if they are, insert/update to database. Should I validate the Excel in Controller or in the Business?
-
This Excel may insert data to DB, for example, a
new Product();Is there a problem in creating new instances in UI layer or is it better to do in Business? Is it better to pass an object from UI to Business or is it better to pass all Class properties and create the object in the Business? -
In this Excel action, I have some helper methods, like verify if the worksheet reached its end, verify if the cell has value, generate a DataTable for the uploaded file and some others. Where these helper methods should be placed? At the moment, they are in UI Layer (same as Controller).
-
Forgetting about the Excel thing, imagine a simple Product form page. On POST, Controller will receive a FormCollection. Should this FormCollection be treated on Controller or should it be pass to Business and Business do all of the stuff?
Sorry about some many questions. I’m also trying to refactor my code and the “Fat Controller” issue is right on my door!
Thanks in advance!
You should indeed avoid having fat controllers. But as always easier said than done.
So let me try to answer your questions with an example. As always you would start by designing a view model which will represent the data that the user sends to this action (don’t use any weakly typed
FormCollectionorViewData)then we move on to the controller:
and the last bit is the service layer. It will have 2 dependencies: the first one will take care of parsing the input stream and returning a list of
Products and the second will take care of persisting those products to the database.Just like this:
Then of course you would have two implementations of those dependencies:
and the repository:
Remark: You could enrich the view model with additional properties that will represent some metadata that we could associate to this file upload and which might have some corresponding input fields on the form. Then you could define a business model to pass to the
TryProcessFilemethod instead of a simpleStream. In this case AutoMapper could be used in the controller action to map between theUploadViewModeland this new business model that you would define.