Adición de la capa de lógica empresarial a un proyecto que usa el enlace de modelos y los formularios web
Por Tom FitzMacken
En esta serie de tutoriales, se muestran aspectos básicos del uso del enlace de modelos con un proyecto de ASP.NET Web Forms. El enlace de modelos hace que la interacción de datos sea más sencilla que tratar con objetos de origen de datos (como ObjectDataSource o SqlDataSource). Esta serie comienza con material introductorio y pasa a conceptos más avanzados en tutoriales posteriores.
En este tutorial se muestra cómo usar el enlace de modelos con una capa de lógica empresarial. Establecerá el miembro OnCallingDataMethods para especificar que se usa un objeto distinto de la página actual para llamar a los métodos de datos.
Este tutorial se basa en el proyecto creado en las partes anteriores de la serie.
Puede descargar el proyecto completo en C# o VB. El código descargable funciona con Visual Studio 2012 o Visual Studio 2013. Usa la plantilla de Visual Studio 2012, que es ligeramente diferente de la plantilla de Visual Studio 2013 que se muestra en este tutorial.
Qué va a crear
El enlace de modelos permite colocar el código de interacción de datos en el archivo de código subyacente de una página web o en una clase lógica empresarial independiente. Los tutoriales anteriores han mostrado cómo usar los archivos de código subyacente para el código de interacción de datos. Este enfoque funciona para sitios pequeños, pero puede provocar repetición de código y mayor dificultad al mantener un sitio grande. También puede ser muy difícil probar el código mediante programación que reside en archivos de código subyacente porque no hay ninguna capa de abstracción.
Para centralizar el código de interacción de datos, puede crear una capa de lógica empresarial que contenga toda la lógica para interactuar con los datos. A continuación, llame a la capa de lógica empresarial desde las páginas web. En este tutorial se muestra cómo mover todo el código que ha escrito en los tutoriales anteriores a una capa de lógica empresarial y, a continuación, usar ese código de las páginas.
En este tutorial, hará lo siguiente:
- Mover el código de los archivos de código subyacente a una capa empresarial
- Cambio de los controles enlazados a datos para llamar a los métodos en el nivel de lógica empresarial
Creación de una capa de lógica empresarial
Ahora, creará la clase a la que se llama desde las páginas web. Los métodos de esta clase tienen un aspecto similar a los métodos que usó en los tutoriales anteriores e incluyen los atributos del proveedor de valores.
En primer lugar, agregue una nueva carpeta denominada BLL.
En la carpeta BLL, cree una nueva clase denominada SchoolBL.cs. Contendrá todas las operaciones de datos que residen originalmente en archivos de código subyacente. Los métodos son casi los mismos que los del archivo de código subyacente, pero incluirán algunos cambios.
El cambio más importante que se debe tener en cuenta es que ya no está ejecutando el código desde una instancia de clase Page. La clase Page contiene el método TryUpdateModel y la propiedad ModelState. Cuando este código se mueve a una capa de lógica empresarial, ya no tiene una instancia de la clase Page para llamar a estos miembros. Para solucionar este problema, debe agregar un parámetro ModelMethodContext a cualquier método que tenga acceso a TryUpdateModel o ModelState. Use este parámetro ModelMethodContext para llamar a TryUpdateModel o recuperar ModelState. No es necesario cambiar nada en la página web para tener en cuenta este nuevo parámetro.
Reemplace el código de SchoolBL.cs por el siguiente.
using System;
using System.Linq;
using ContosoUniversityModelBinding.Models;
using System.Web.ModelBinding;
using System.Web.UI.WebControls;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
namespace ContosoUniversityModelBinding.BLL
{
public class SchoolBL : IDisposable
{
SchoolContext db = new SchoolContext();
public IQueryable<Student> GetStudents([Control] AcademicYear? displayYear)
{
var query = db.Students.Include(s => s.Enrollments.Select(e => e.Course));
if (displayYear != null)
{
query = query.Where(s => s.Year == displayYear);
}
return query;
}
public void InsertStudent(ModelMethodContext context)
{
var item = new Student();
context.TryUpdateModel(item);
if (context.ModelState.IsValid)
{
db.Students.Add(item);
db.SaveChanges();
}
}
public void DeleteStudent(int studentID, ModelMethodContext context)
{
var item = new Student { StudentID = studentID };
db.Entry(item).State = EntityState.Deleted;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
context.ModelState.AddModelError("",
String.Format("Item with id {0} no longer exists in the database.", studentID));
}
}
public void UpdateStudent(int studentID, ModelMethodContext context)
{
Student item = null;
item = db.Students.Find(studentID);
if (item == null)
{
context.ModelState.AddModelError("", String.Format("Item with id {0} was not found", studentID));
return;
}
context.TryUpdateModel(item);
if (context.ModelState.IsValid)
{
db.SaveChanges();
}
}
public IQueryable<Enrollment> GetCourses([QueryString] int? studentID)
{
var query = db.Enrollments.Include(e => e.Course)
.Where(e => e.StudentID == studentID);
return query;
}
private bool disposedValue = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposedValue)
{
if (disposing)
{
db.Dispose();
}
}
this.disposedValue = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}
Revisión de las páginas existentes para recuperar datos de la capa de lógica empresarial
Por último, convertirá las páginas Students.aspx, AddStudent.aspx y Courses.aspx de usar consultas en el archivo de código subyacente al uso del nivel de lógica empresarial.
En los archivos de código subyacente de Students, AddStudent y Courses, elimine o comente los siguientes métodos de consulta:
- studentsGrid_GetData
- studentsGrid_UpdateItem
- studentsGrid_DeleteItem
- addStudentForm_InsertItem
- coursesGrid_GetData
Ahora no debería tener ningún código en el archivo de código subyacente que pertenezca a las operaciones de datos.
El controlador de eventos OnCallingDataMethods permite especificar un objeto que se usará para los métodos de datos. En Students.aspx, agregue un valor para ese controlador de eventos y cambie los nombres de los métodos de datos a los nombres de los métodos de la clase lógica empresarial.
<asp:GridView runat="server" ID="studentsGrid"
ItemType="ContosoUniversityModelBinding.Models.Student" DataKeyNames="StudentID"
SelectMethod="GetStudents"
UpdateMethod="UpdateStudent" DeleteMethod="DeleteStudent"
AllowSorting="true" AllowPaging="true" PageSize="4"
AutoGenerateEditButton="true" AutoGenerateDeleteButton="true"
AutoGenerateColumns="false"
OnCallingDataMethods="studentsGrid_CallingDataMethods">
En el archivo de código subyacente para Students.aspx, defina el controlador de eventos para el evento CallingDataMethods. En este controlador de eventos, se especifica la clase lógica empresarial para las operaciones de datos.
protected void studentsGrid_CallingDataMethods(object sender, CallingDataMethodsEventArgs e)
{
e.DataMethodsObject = new ContosoUniversityModelBinding.BLL.SchoolBL();
}
En AddStudent.aspx, realice cambios similares.
<asp:FormView runat="server" ID="addStudentForm"
ItemType="ContosoUniversityModelBinding.Models.Student"
InsertMethod="InsertStudent" DefaultMode="Insert"
OnCallingDataMethods="addStudentForm_CallingDataMethods"
RenderOuterTable="false" OnItemInserted="addStudentForm_ItemInserted">
protected void addStudentForm_CallingDataMethods(object sender, CallingDataMethodsEventArgs e)
{
e.DataMethodsObject = new ContosoUniversityModelBinding.BLL.SchoolBL();
}
En Courses.aspx, realice cambios similares.
<asp:GridView runat="server" ID="coursesGrid"
ItemType="ContosoUniversityModelBinding.Models.Enrollment"
SelectMethod="GetCourses" AutoGenerateColumns="false"
OnCallingDataMethods="coursesGrid_CallingDataMethods">
protected void coursesGrid_CallingDataMethods(object sender, CallingDataMethodsEventArgs e)
{
e.DataMethodsObject = new ContosoUniversityModelBinding.BLL.SchoolBL();
}
Ejecute la aplicación y observe que todas las páginas funcionan como antes. La lógica de validación también funciona correctamente.
Conclusión
En este tutorial, reestructurará la aplicación para usar una capa de acceso a datos y una capa de lógica empresarial. Especificó que los controles de datos usan un objeto que no es la página actual para las operaciones de datos.