Dodawanie warstwy logiki biznesowej do projektu korzystającego z powiązań modelu i formularzy internetowych
– autor Tom FitzMacken
W tej serii samouczków przedstawiono podstawowe aspekty używania powiązania modelu z projektem ASP.NET Web Forms. Powiązanie modelu sprawia, że interakcja danych jest bardziej prosta niż obsługa obiektów źródła danych (takich jak ObjectDataSource lub SqlDataSource). Ta seria rozpoczyna się od materiałów wprowadzających i przechodzi do bardziej zaawansowanych pojęć w kolejnych samouczkach.
W tym samouczku pokazano, jak używać powiązania modelu z warstwą logiki biznesowej. Ustawisz element członkowski OnCallingDataMethods, aby określić, że obiekt inny niż bieżąca strona jest używany do wywoływania metod danych.
Ten samouczek opiera się na projekcie utworzonym we wcześniejszych częściach serii.
Pełny projekt można pobrać w języku C# lub VB. Kod do pobrania działa z programem Visual Studio 2012 lub Visual Studio 2013. Używa szablonu programu Visual Studio 2012, który jest nieco inny niż szablon Visual Studio 2013 pokazany w tym samouczku.
Co będziesz kompilować
Powiązanie modelu umożliwia umieszczenie kodu interakcji danych w pliku za pomocą kodu dla strony internetowej lub w oddzielnej klasie logiki biznesowej. W poprzednich samouczkach pokazano, jak używać plików kodu za pomocą kodu interakcji z danymi. Takie podejście działa w przypadku małych witryn, ale może prowadzić do powtórzenia kodu i większej trudności podczas konserwacji dużej lokacji. Programowe testowanie kodu znajdującego się w kodzie za plikami może być również bardzo trudne, ponieważ nie ma warstwy abstrakcji.
Aby scentralizować kod interakcji z danymi, możesz utworzyć warstwę logiki biznesowej, która zawiera całą logikę do interakcji z danymi. Następnie należy wywołać warstwę logiki biznesowej ze stron internetowych. W tym samouczku pokazano, jak przenieść cały kod napisany w poprzednich samouczkach do warstwy logiki biznesowej, a następnie użyć tego kodu ze stron.
W tym samouczku wykonasz następujące elementy:
- Przenoszenie kodu z plików z kodu do warstwy logiki biznesowej
- Zmienianie kontrolek powiązanych z danymi w celu wywołania metod w warstwie logiki biznesowej
Tworzenie warstwy logiki biznesowej
Teraz utworzysz klasę wywoływaną ze stron internetowych. Metody w tej klasie wyglądają podobnie do metod używanych w poprzednich samouczkach i zawierają atrybuty dostawcy wartości.
Najpierw dodaj nowy folder o nazwie BLL.
W folderze BLL utwórz nową klasę o nazwie SchoolBL.cs. Będzie zawierać wszystkie operacje danych, które pierwotnie znajdowały się w plikach za kodem. Metody są prawie takie same jak metody w pliku za kodem, ale będą zawierać pewne zmiany.
Najważniejszą zmianą, którą należy zauważyć, jest to, że kod nie jest już wykonywany z poziomu wystąpienia klasy Page . Klasa Page zawiera metodę TryUpdateModel i właściwość ModelState . Po przeniesieniu tego kodu do warstwy logiki biznesowej nie masz już wystąpienia klasy Page w celu wywołania tych elementów członkowskich. Aby obejść ten problem, należy dodać parametr ModelMethodContext do dowolnej metody, która uzyskuje dostęp do elementu TryUpdateModel lub ModelState. Użyjesz tego parametru ModelMethodContext, aby wywołać metodę TryUpdateModel lub pobrać modelState. Nie musisz zmieniać niczego na stronie internetowej, aby uwzględnić ten nowy parametr.
Zastąp kod w pliku SchoolBL.cs następującym kodem.
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);
}
}
}
Poprawianie istniejących stron w celu pobrania danych z warstwy logiki biznesowej
Na koniec przekonwertujesz strony Students.aspx, AddStudent.aspx i Courses.aspx przy użyciu zapytań w pliku za pomocą kodu w warstwie logiki biznesowej.
W plikach kodu dla uczniów, AddStudent i Kursów usuń lub oznacz jako komentarz następujące metody zapytania:
- studentsGrid_GetData
- studentsGrid_UpdateItem
- studentsGrid_DeleteItem
- addStudentForm_InsertItem
- coursesGrid_GetData
Teraz nie powinien znajdować się kod w pliku za pomocą kodu, który dotyczy operacji danych.
Procedura obsługi zdarzeń OnCallingDataMethods umożliwia określenie obiektu do użycia dla metod danych. W pliku Students.aspx dodaj wartość dla tej procedury obsługi zdarzeń i zmień nazwy metod danych na nazwy metod w klasie logiki biznesowej.
<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">
W pliku code-behind dla students.aspx zdefiniuj procedurę obsługi zdarzeń dla zdarzenia CallingDataMethods. W tej procedurze obsługi zdarzeń należy określić klasę logiki biznesowej dla operacji danych.
protected void studentsGrid_CallingDataMethods(object sender, CallingDataMethodsEventArgs e)
{
e.DataMethodsObject = new ContosoUniversityModelBinding.BLL.SchoolBL();
}
W pliku AddStudent.aspx wprowadź podobne zmiany.
<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();
}
W pliku Courses.aspx wprowadź podobne zmiany.
<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();
}
Uruchom aplikację i zwróć uwagę, że wszystkie strony działają jak wcześniej. Logika walidacji działa również poprawnie.
Podsumowanie
W tym samouczku ponownie ustrukturyzujesz aplikację, aby używać warstwy dostępu do danych i warstwy logiki biznesowej. Określono, że kontrolki danych używają obiektu, który nie jest bieżącą stroną dla operacji danych.