Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
por Tom FitzMacken
Esta série de tutoriais demonstra aspetos básicos da utilização de binding de modelos num projeto ASP.NET Web Forms. A ligação de modelos torna a interação de dados mais simples do que lidar com objetos fonte de dados (como ObjectDataSource ou SqlDataSource). Esta série começa com material introdutório e avança para conceitos mais avançados em tutoriais posteriores.
Este tutorial mostra como usar a ligação de modelos com uma camada de lógica de negócio. Irá definir o membro OnCallingDataMethods para especificar que um objeto distinto da página atual é usado para chamar os métodos de dados.
Este tutorial baseia-se no projeto criado nas primeiras partes da série.
Podes descarregar o projeto completo em C# ou VB. O código descarregável funciona com Visual Studio 2012 ou Visual Studio 2013. Utiliza o modelo Visual Studio 2012, que é ligeiramente diferente do modelo Visual Studio 2013 mostrado neste tutorial.
O que vais construir
A ligação de modelos permite-lhe colocar o seu código de interação de dados quer no ficheiro code-behind de uma página web, quer numa classe separada de lógica de negócio. Os tutoriais anteriores mostraram como usar os ficheiros code-behind para código de interação de dados. Esta abordagem funciona para sites pequenos, mas pode levar à repetição do código e maior dificuldade ao manter um site grande. Também pode ser muito difícil testar programáticamente código que reside atrás de ficheiros porque não existe uma camada de abstração.
Para centralizar o código de interação de dados, pode criar uma camada de lógica de negócio que contenha toda a lógica para interagir com dados. Depois chamas a camada de lógica de negócio a partir das tuas páginas web. Este tutorial mostra como mover todo o código que escreveste nos tutoriais anteriores para uma camada de lógica de negócio e depois usar esse código das páginas.
Neste tutorial, você:
- Mover o código dos ficheiros code-behind para uma camada de lógica de negócio
- Altere os seus controlos ligados a dados para chamar os métodos na camada de lógica de negócios
Criar camada de lógica de negócio
Agora, vais criar a classe que é chamada a partir das páginas web. Os métodos desta aula são semelhantes aos métodos que usaste nos tutoriais anteriores e incluem os atributos de provedor de valor.
Primeiro, adiciona uma nova pasta chamada BLL.
Na pasta BLL, crie uma nova classe chamada SchoolBL.cs. Conterá todas as operações de dados que originalmente residiam em ficheiros code-behind. Os métodos são quase os mesmos que os do ficheiro code-behind, mas incluirão algumas alterações.
A alteração mais importante a notar é que já não está a executar o código a partir de uma instância da classe Page . A classe Page contém o método TryUpdateModel e a propriedade ModelState . Quando este código é movido para uma camada de lógica de negócio, já não existe uma instância da classe Page para chamar estes membros. Para contornar este problema, deve adicionar um parâmetro ModelMethodContext a qualquer método que aceda ao TryUpdateModel ou ao ModelState. Utiliza este parâmetro ModelMethodContext para chamar TryUpdateModel ou recuperar ModelState. Não precisa de alterar nada na página web para ter em conta este novo parâmetro.
Substitua o código em SchoolBL.cs pelo seguinte código.
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);
}
}
}
Revise páginas existentes para recuperar dados da camada de lógica de negócio
Finalmente, vais converter as páginas Students.aspx, AddStudent.aspx e Courses.aspx de usar consultas no ficheiro code-behind para usar a camada de lógica de negócio.
Nos ficheiros de code-behind para Alunos, AdicionarAluno e Cursos, elimine ou comente os seguintes métodos de consulta:
- grelhaEstudantes_ObterDados
- studentsGrid_AtualizarItem
- studentsGrid_EliminarItem
- addStudentForm_InserirItem
- coursesGrid_GetData
Agora não deves ter código no ficheiro code-behind que se relacione com operações de dados.
O manipulador de eventos OnCallingDataMethods permite-lhe especificar um objeto a usar para os métodos de dados. Em Students.aspx, adicione um valor para esse gestor de eventos e mude os nomes dos métodos de dados pelos nomes dos métodos na classe de lógica de negócio.
<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">
No ficheiro code-behind para Students.aspx, defina o gestor de eventos para o evento CallingDataMethods. Neste gestor de eventos, especifica a classe de lógica de negócio para operações de dados.
protected void studentsGrid_CallingDataMethods(object sender, CallingDataMethodsEventArgs e)
{
e.DataMethodsObject = new ContosoUniversityModelBinding.BLL.SchoolBL();
}
Em AddStudent.aspx, faça alterações semelhantes.
<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();
}
Em Courses.aspx, faça alterações semelhantes.
<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();
}
Executa a aplicação e repara que todas as páginas funcionam como antes. A lógica de validação também funciona corretamente.
Conclusion
Neste tutorial, reestruturaste a tua aplicação para usar uma camada de acesso a dados e uma camada de lógica de negócio. Especificou que os controlos de dados utilizam um objeto que não é a página atual para operações de dados.