Using the HttpContext
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 a class library with a Telerik Data Access fluent model.
To create such a solution and to configure it, you can use the workflow suggested in the Creating a New Web Application article.
Suppose, you have an ASP.NET Web Application and Telerik Data Access 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.
- In the SofiaCarRental.Model project, add a reference to the System.Web.dll assembly.
-
Add a new class named ContextFactory.
using System.Web; namespace SofiaCarRental.Model { public class ContextFactory { private static readonly string contextKey = typeof( FluentModel ).FullName; public static FluentModel GetContextPerRequest() { HttpContext httpContext = HttpContext.Current; if ( httpContext == null ) { return new FluentModel(); } else { FluentModel context = httpContext.Items[contextKey] as FluentModel; if ( context == null ) { context = new FluentModel(); httpContext.Items[contextKey] = context; } return context; } } public static void Dispose() { HttpContext httpContext = HttpContext.Current; if ( httpContext != null ) { FluentModel context = httpContext.Items[contextKey] as FluentModel; if ( context != null ) { context.Dispose(); httpContext.Items[contextKey] = null; } } } } }
Imports System.Web Public Class ContextFactory Private Shared ReadOnly contextKey As String = GetType(FluentModel).FullName Public Shared Function GetContextPerRequest() As FluentModel Dim _httpContext As HttpContext = HttpContext.Current If _httpContext Is Nothing Then Return New FluentModel() Else Dim context As FluentModel = TryCast(_httpContext.Items(contextKey), FluentModel) If context Is Nothing Then context = New FluentModel() _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 FluentModel = TryCast(_httpContext.Items(contextKey), FluentModel) 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. The disposal of the context happens in the OnUnload method, which has to be overridden as well.
using System;
using System.Collections.Generic;
using System.Linq;
namespace BestPracticeContextFactory
{
public partial class _Default : System.Web.UI.Page
{
private FluentModel 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 FluentModel
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 FluentModel 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 FluentModel
Protected Property DbContext() As FluentModel
Get
Return _DbContext
End Get
Private Set(ByVal value As FluentModel)
_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