1

The project I am working is 'University Management System' and it's a big one. Right now, I am implementing the student registration section that works fine (A small portion of the project). I've used 'Three-Tier Architecture' and 'ORM - EF' in ASP.NET MVC template. In the project, I need to do some validations for registering students depending upon their year, department etc. So there are sections like DAL, BLL, finally controller and view. I've done the validations in the controller and getting the data from BLL that again retrieves data from DAL (This is the simple condition of 'Three-Tier Architecture'). So my questions are:

1) Is it OK to do the validations in the controller?

2) If not and need to do it in the BLL, will it be just fine and why or I can continue doing it in the controller?

Note: To me, doing the validations in the controller or BLL seems OK and the same. Does it have any effect?

Right now, I've done the following:

DAL:

public List<Student> Add(int studentID, string studentName, string email, DateTime regDate)
{
     List<Student> lst = null;
     Student aStudent = new Student();

     aStudent.StudentID = studentID;
     aStudent.StudentName = studentName;
     aStudent.Email = email;
     aStudent.RegDate = regDate;

     try
     {
        db.Students.Add(aStudent);
        db.SaveChanges();
     }

     catch (Exception ex)
     {
        ex.ToString();
     }

    return lst;
 }

BLL:

public List<Student> Add(int studentID, string studentName, string email, DateTime regDate)
{
   return aStudentGateway.Add(studentID, studentName, email, regDate);
}

Controller:

/**Student Registration - Starts**/
[HttpPost]
public ActionResult AddStudent(Student aStudent)
{
    List<Department> departments = aDepartmentManager.GetAllDepartments();
    List<DepartmentViewModel> departmentsViewModel = aDepartmentManager.GetAllDepartmentViewModel();

    DateTime yearInDateTime = Convert.ToDateTime(Request.Form["RegDate"]);
    string extractYear = yearInDateTime.ToString();
    var year = DateTime.Parse(extractYear).Year;
    int department = Convert.ToInt32(Request.Form["Department"]);

    List<Student> studentList = aStudentManager.GetAllStudents();

    int count = 1;

    var query = (from c in studentList
                 where c.Department == department && c.Year == year
                 select c).ToList();

    foreach (var c in query)
    {
        if (query.Count() > 0)
        {
            int m = Convert.ToInt32(c.StudentID);
            count = m + 1; //Incrementing the numbers by one with the table column
        }
        else
        {
            int m = 1;
            count = m + 1; //Incrementing the numbers by one with the variable assigned one
        }
    }

    Student student = new Student();
    student.StudentName = Request.Form["StudentName"];
    student.Email = Request.Form["Email"];
    student.RegDate = Convert.ToDateTime(Request.Form["RegDate"]);
    student.StudentID = count;

    if (aStudentManager.ExistEmailAny(student.Email))
    {
        ViewBag.ErrorMessage = "Email already exists";
    }
    else
    {
        aStudentManager.Add(aStudent.StudentID, aStudent.StudentName, aStudent.Email, aStudent.RegDate);
        ViewBag.Message = "Registration successful. See below to verify.";

        /**This section used to show student details after registration**/
        var result = (from c in departments
                      join d in departmentsViewModel on c.DepartmentID equals d.DepartmentId
                      where d.DepartmentId == department
                      select c);

        foreach (var items in result)
        {
            if (count.ToString().Length > 1)
            {
                ViewBag.StudentID = items.Code + "-" + year + "-" + "0" + count;
            }
            else
            {
                ViewBag.StudentID = items.Code + "-" + year + "-" + "00" + count;
            }

            StudentViewModel.StudentID = student.StudentID;
            StudentViewModel.StudentName = student.StudentName;
            StudentViewModel.Email = student.Email;
            StudentViewModel.RegDate = student.RegDate;
        }
        /**This section used to show student details after registration**/
    }

    return View();
}
/**Student Registration - Ends**/
Mandeep Thakur
  • 655
  • 1
  • 10
  • 23
AT-2017
  • 3,114
  • 3
  • 23
  • 39
  • Thank you for asking this question. I was about to ask same question. I have been working on various projects lately and I always find that I don't do anything in BLL except calling the DAL. Then what's the BLL are there for? I too write all the business validations and object manipulations in Controller. I'd love to know the right approach to do this thing. – Krishnandu Sarkar Nov 16 '16 at 05:28
  • @KrishnanduSarkar: Seems like your question is different then OP's question, if you have such question then you can ask a new. – Divyang Desai Nov 17 '16 at 12:44
  • Thanks for the answers. I tried to understand what you both have written. In some tutorials of **Three-Tier Architecture**, I've seen the logical parts like conditions are being done in the controller and actually not sure of it. But despite data validations, it seems to me that according to the project requirement, there are certain conditions that should be met in the controller rather than DAL. Let me make it more clear. In the DAL, we insert data. But in some cases, there may require some conditions to insert those data. So I am guessing these conditions could be checked in the controller. – AT-2017 Nov 18 '16 at 14:28
  • @AT-2016: As per as three tier architecture concern, there would be a common methods to add/update/delete data, which may generics or different for all. – Divyang Desai Nov 20 '16 at 12:14
  • @Div I guess, you are writing about repository pattern where there will be a generic class and the common methods for **CRUD**. But isn't it little bit different in term of **Three-Tier Architecture**? Basically both are different. – AT-2017 Nov 20 '16 at 12:20
  • @AT-2016: You can even use a generic classes in Three tier also, both are doing similar things but the difference is just repository pattern is more loosely coupled approach to data access with DI and Ioc – Divyang Desai Nov 20 '16 at 12:30

2 Answers2

1

1) Is it OK to do the validations in the controller?

No at all, it would be more better to use Data Annotation Validator Attributes, and to do validation in your model class.

Second thing, you're doing some stuff of DAL in your controller, like

List<Department> departments = aDepartmentManager.GetAllDepartments();
List<DepartmentViewModel> departmentsViewModel = aDepartmentManager.GetAllDepartmentViewModel();

var query = (from c in studentList
             where c.Department == department && c.Year == year
             select c).ToList();

These all queries should be in DAL, which is exact use of DAL to interact with the database, and keep your controller clean.

Third thing,

If you pass Student to the controller, then not need to get each attribute using Request.Form.

Hope this make sense!

Divyang Desai
  • 7,483
  • 13
  • 50
  • 76
1

I would provide multiple steps of validation in the different layers, depending on the context and the meaning of the layer.

First, it's a best practice to provide validation both on client and server side.

For the client side you should provide field checks for required fields and other simple validations. If you are using MVC you can use data annotations.

The same validation should be replicated in the controller. Here you should fail fast applying some kind of contract to the parameters that have been passed. One good practice is using Code Contracts that provide preconditions that need to be satisfied to go on in your pipeline of execution.

In the business layer provide the check that needs to be done in the business logic.

Finally in the data access layer provide all the checks that are needed to persist your data. If you are using EF a good practice is implementing the IValidatableObject for your entity classes. Here in Scott Gu's blog you can find a post that explains this technique.

Even though this approach look like it will introduce repetitions, it will provide consistency in your data and separate concerns between your layers.

user449689
  • 3,142
  • 4
  • 19
  • 37
  • So you are saying it's better to validate data in both server and client side. Despite data validation, there are some other conditions to be met for data insertion and to me, it felt like doing this things in the controller rather than DAL directly. – AT-2017 Nov 18 '16 at 14:40
  • Of course it's your choice and it depends on the web application. My answer wanted just letting you know the "best practices" for what concerns validation. I strongly advice anyway to implement validation both in client and server side. For the server side part you will find the solution most suited for your use case. – user449689 Nov 18 '16 at 15:11