Using the HttpContext
This article is relevant to entity models that utilize the deprecated Visual Studio integration of Telerik Data Access. The current documentation of the Data Access framework is available here.
The ContextFactory approach demonstrated below requires that the ASP.NET projects, which consume it to be configured with Trust Level equal to Full.
In this topic you will learn how to manage the OpenAccessContext by using the HttpContext.
Suppose, you have an ASP.NET Web Application and Telerik Data Access Domain Model.
Basically, you need to create a class that is responsible for getting and setting the OpenAccessContext from/to the HttpContext. This will be the ContextFactory class
- If you want to create the ContextFactory in a separate assembly (e.g. Telerik Data Access Class Library), make sure you have a reference to the System.Web.dll assembly in your project.
-
Add a new class named ContextFactory.
using System.Web; namespace BestPracticeContextFactory { public class ContextFactory { private static readonly string contextKey = typeof( EntitiesModel ).FullName; public static EntitiesModel GetContextPerRequest() { HttpContext httpContext = HttpContext.Current; if ( httpContext == null ) { return new EntitiesModel(); } else { EntitiesModel context = httpContext.Items[contextKey] as EntitiesModel; if ( context == null ) { context = new EntitiesModel(); httpContext.Items[contextKey] = context; } return context; } } public static void Dispose() { HttpContext httpContext = HttpContext.Current; if ( httpContext != null ) { EntitiesModel context = httpContext.Items[contextKey] as EntitiesModel; if ( context != null ) { context.Dispose(); httpContext.Items[contextKey] = null; } } } } }
Public Class ContextFactory Private Shared ReadOnly contextKey As String = GetType(EntitiesModel).FullName Public Shared Function GetContextPerRequest() As EntitiesModel Dim _httpContext As HttpContext = HttpContext.Current If _httpContext Is Nothing Then Return New EntitiesModel() Else Dim context As EntitiesModel = TryCast(_httpContext.Items(contextKey), EntitiesModel) If context Is Nothing Then context = New EntitiesModel() _httpContext.Items(contextKey) = context End If Return context End If End Function Public Shared Sub Dispose() Dim _httpContext As HttpContext = HttpContext.Current If _httpContext IsNot Nothing Then Dim context As EntitiesModel = TryCast(_httpContext.Items(contextKey), EntitiesModel) If context IsNot Nothing Then context.Dispose() _httpContext.Items(contextKey) = Nothing End If End If End Sub End Class
Accessing the OpenAccessContext from the Pages
For every page that will use the OpenAccessContext, you should declare a field that exposes the context. You need to override the OnInit method and there you will initialize (retrieve) the context.
using System;
using System.Collections.Generic;
using System.Linq;
namespace BestPracticeContextFactory
{
public partial class _Default : System.Web.UI.Page
{
private EntitiesModel context;
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
this.context = ContextFactory.GetContextPerRequest();
}
protected override void OnUnload(EventArgs e)
{
ContextFactory.Dispose();
base.OnUnload(e);
}
protected void Page_Load(object sender, EventArgs e)
{
// Load your data here.
List<Category> categories = this.context.Categories.ToList();
}
}
}
Public Class _Default
Inherits System.Web.UI.Page
Private _context As EntitiesModel
Protected Overrides Sub OnInit(e As EventArgs)
MyBase.OnInit(e)
Me._context = ContextFactory.GetContextPerRequest()
End Sub
Protected Overrides Sub OnUnload(e As EventArgs)
ContextFactory.Dispose()
MyBase.OnUnload(e)
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' Load your data here.
Dim categories As List(Of Category) = Me._context.Categories.ToList()
End Sub
End Class
Declaring the Context in a BasePage
Although you can retrieve the OpenAccessContext directly in the concrete pages (like the example above), a better approach is to define the context in a base class that inherits System.Web.UI.Page. Then the other pages should derive from the base page and use the context. For example:
using System;
namespace BestPracticeContextFactory
{
public class BaseUIPage : System.Web.UI.Page
{
protected EntitiesModel DbContext
{
get;
private set;
}
protected override void OnInit( EventArgs e )
{
base.OnInit( e );
this.DbContext = ContextFactory.GetContextPerRequest();
}
public override void Dispose()
{
ContextFactory.Dispose();
base.Dispose();
}
}
}
Public Class BaseUIPage
Inherits System.Web.UI.Page
Private _DbContext As EntitiesModel
Protected Property DbContext() As EntitiesModel
Get
Return _DbContext
End Get
Private Set(ByVal value As EntitiesModel)
_DbContext = value
End Set
End Property
Protected Overrides Sub OnInit(ByVal e As EventArgs)
MyBase.OnInit(e)
Me.DbContext = ContextFactory.GetContextPerRequest()
End Sub
Public Overrides Sub Dispose()
ContextFactory.Dispose()
MyBase.Dispose()
End Sub
End Class
Then, for the concrete pages you will have:
using System;
using System.Collections.Generic;
using System.Linq;
namespace BestPracticeContextFactory
{
public partial class _Default : BaseUIPage
{
protected void Page_Load( object sender, EventArgs e )
{
// Load your data here.
List<Category> categories = this.DbContext.Categories.ToList();
}
}
}
Public Class _Default
Inherits BaseUIPage
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' Load your data here.
Dim categories As List(Of Category) = Me.DbContext.Categories.ToList()
End Sub
End Class