【问题标题】:Three-Tier Architecture: Get All Data and Validations三层架构:获取所有数据和验证
【发布时间】:2016-11-16 05:08:44
【问题描述】:

我正在做的项目是'大学管理系统',它是一个很大的项目。现在,我正在实施运行良好的学生注册部分(项目的一小部分)。我在 ASP.NET MVC 模板中使用了 '三层架构''ORM - EF'。在项目中,我需要根据学生的年级、部门等对注册学生进行一些验证。所以有 DAL、BLL、最后是控制器和视图等部分。我已经在控制器中完成了验证,并从 BLL 中获取数据,该数据再次从 DAL 中检索数据(这是 '三层架构' 的简单条件)。所以我的问题是:

1) 可以在控制器中进行验证吗?

2) 如果不需要并且需要在 BLL 中执行,会不会很好,为什么或者我可以 继续在控制器中执行此操作?

注意:对我来说,在控制器或 BLL 中进行验证似乎没问题,而且是一样的。有效果吗?

现在,我做了以下事情:

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);
}

控制器:

/**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**/

【问题讨论】:

  • 感谢您提出这个问题。我正要问同样的问题。我最近一直在从事各种项目,我总是发现我在 BLL 中除了调用 DAL 之外什么都不做。那么 BLL 有什么用呢?我也在 Controller 中编写了所有的业务验证和对象操作。我很想知道做这件事的正确方法。
  • @KrishnanduSarkar:好像你的问题和 OP 的问题不同,如果你有这样的问题,那么你可以问一个新的问题。
  • 感谢您的回答。我试图理解你们俩写的东西。在 三层架构 的一些教程中,我看到了控制器中正在执行条件等逻辑部分,但实际上并不确定。但是尽管进行了数据验证,但在我看来,根据项目要求,控制器而不是 DAL 中应该满足某些条件。让我说得更清楚。在 DAL 中,我们插入数据。但在某些情况下,可能需要一些条件才能插入这些数据。所以我猜这些条件可以在控制器中检查。
  • @AT-2016:根据三层架构的考虑,添加/更新/删除数据会有一个通用的方法,这可能是通用的,也可能是不同的。
  • @Div 我猜,您正在写关于存储库模式的文章,其中将有一个通用类和 CRUD 的常用方法。但是在三层架构方面是不是有点不同?基本上两者是不同的。

标签: asp.net-mvc entity-framework linq validation three-tier


【解决方案1】:

我会在不同的层中提供多个验证步骤,具体取决于层的上下文和含义。

首先,最佳做法是在客户端和服务器端都提供验证。

对于客户端,您应该提供必填字段的字段检查和其他简单的验证。如果你使用的是 MVC you can use data annotations

应该在控制器中复制相同的验证。在这里,您应该无法快速将某种契约应用于已传递的参数。一种好的做法是使用Code Contracts,它提供了在您的执行管道中继续进行所需满足的先决条件。

在业务层提供业务逻辑中需要做的检查。

最后,在数据访问层提供持久化数据所需的所有检查。如果您使用的是 EF,一个好的做法是为您的实体类实现 IValidatableObjectHere 在 Scott Gu 的博客中,您可以找到解释此技术的帖子。

尽管这种方法看起来会引入重复,但它会在您的数据中提供一致性并在您的层之间分离关注点。

【讨论】:

  • 所以你说最好在服务器端和客户端验证数据。尽管进行了数据验证,但数据插入还需要满足其他一些条件,对我来说,感觉就像在控制器中而不是直接在 DAL 中做这些事情。
  • 当然这是您的选择,这取决于 Web 应用程序。我的回答只是想让您知道有关验证的“最佳实践”。无论如何,我强烈建议在客户端和服务器端实现验证。对于服务器端部分,您将找到最适合您的用例的解决方案。
【解决方案2】:

1) 可以在控制器中进行验证吗?

完全不,最好使用Data Annotation Validator Attributes,并在您的模型类中进行验证。

第二件事,你正在控制器中做一些 DAL 的东西,比如

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();

所有这些查询都应该在 DAL 中,这正是使用 DAL 与数据库进行交互,并保持你的控制器干净。

第三件事,

如果将Student传递给控制器​​,则不需要使用Request.Form获取每个属性。

希望这是有道理的!

【讨论】:

  • 我已经使用 BLL 中的这些方法来检查控制器中的某些条件以进行数据插入@Div。
  • 是的,没关系!我关心的是仅提及良好做法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-18
  • 2015-06-17
  • 2011-06-02
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
相关资源
最近更新 更多