Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом руководстве показаны основные аспекты использования привязки модели с проектом веб-форм ASP.NET. Привязка модели позволяет напрямую взаимодействовать с данными, чем с объектами источника данных (например, ObjectDataSource или SqlDataSource). Эта серия начинается с вводного материала и переходит к более сложным концепциям в последующих руководствах.
В этом руководстве показано, как использовать привязку модели с уровнем бизнес-логики. Вы зададите элемент OnCallingDataMethods, чтобы указать, что объект, отличный от текущей страницы, используется для вызова методов данных.
Это руководство основывается на проекте, созданном в предыдущих частях серии.
Полный проект можно скачать в C# или VB. Скачиваемый код работает с Visual Studio 2012 или Visual Studio 2013. Он использует шаблон Visual Studio 2012, который немного отличается от шаблона Visual Studio 2013, показанного в этом руководстве.
Что вы будете создавать
Привязка модели позволяет поместить код взаимодействия с данными в файл программной части веб-страницы или в отдельный бизнес-класс логики. В предыдущих руководствах показано, как использовать файлы программной части для кода взаимодействия с данными. Этот подход подходит для небольших сайтов, но может привести к повторению кода и большей сложности при обслуживании большого сайта. Также может быть очень сложно программно протестировать код, который находится в файлах за файлами кода, так как нет уровня абстракции.
Чтобы централизировать код взаимодействия с данными, можно создать уровень бизнес-логики, содержащий всю логику для взаимодействия с данными. Затем вы вызываете уровень бизнес-логики из ваших веб-страниц. В этом руководстве показано, как переместить весь код, написанный в предыдущих руководствах, в слой бизнес-логики, а затем использовать этот код на страницах.
В этом руководстве вы выполните следующие действия.
- Переместить код из файлов связующего кода в слой бизнес-логики
- Изменение элементов управления привязкой к данным для вызова методов на уровне бизнес-логики
Создание уровня бизнес-логики
Теперь вы создадите класс, который вызывается на веб-страницах. Методы в этом классе похожи на методы, используемые в предыдущих руководствах, и включают атрибуты поставщика значений.
Сначала добавьте новую папку с именем BLL.
В папке BLL создайте класс с именем SchoolBL.cs. Он будет содержать все операции с данными, которые первоначально находились в файлах программной части. Методы почти те же, что и методы в файле программной части, но будут включать некоторые изменения.
Самое важное изменение заключается в том, что вы больше не выполняете код из экземпляра класса Page . Класс Page содержит метод TryUpdateModel и свойство ModelState . Когда этот код перемещается на уровень бизнес-логики, у вас больше нет экземпляра класса Page для вызова этих элементов. Чтобы обойти эту проблему, необходимо добавить параметр ModelMethodContext в любой метод, который обращается к TryUpdateModel или ModelState. Этот параметр ModelMethodContext используется для вызова TryUpdateModel или получения ModelState. Вам не нужно ничего изменить на веб-странице, чтобы учесть этот новый параметр.
Замените код в SchoolBL.cs следующим кодом.
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);
}
}
}
Изменение существующих страниц для получения данных из уровня бизнес-логики
Наконец, вы преобразуете страницы Students.aspx, AddStudent.aspx и Courses.aspx, чтобы вместо использования запросов в файле кода программной части использовать уровень бизнес-логики.
В файлах кода для учащихся, AddStudent и Courses удалите или закомментируйте следующие методы запроса:
- studentsGrid_GetData
- studentsGrid_UpdateItem
- studentsGrid_УдалитьЭлемент
- формаДобавленияСтудента_ВставитьЭлемент
- coursesGrid_GetData
Теперь в файле программной части не должно быть кода, относящегося к операциям с данными.
Обработчик событий OnCallingDataMethods позволяет указать объект, используемый для методов данных. В Students.aspx добавьте значение для этого обработчика событий и измените имена методов данных на имена методов в классе бизнес-логики.
<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">
В файле кода программной части для Students.aspx определите обработчик событий для события CallingDataMethods. В этом обработчике событий указывается класс бизнес-логики для операций с данными.
protected void studentsGrid_CallingDataMethods(object sender, CallingDataMethodsEventArgs e)
{
e.DataMethodsObject = new ContosoUniversityModelBinding.BLL.SchoolBL();
}
В AddStudent.aspx внесите аналогичные изменения.
<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();
}
В Courses.aspx внесите аналогичные изменения.
<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();
}
Запустите приложение и обратите внимание, что все страницы работают так, как они ранее. Логика проверки также работает правильно.
Conclusion
В этом руководстве вы перестроили приложение для использования уровня доступа к данным и уровня бизнес-логики. Вы указали, что элементы управления данными используют объект, который не является текущей страницей для операций с данными.