//----------------------------------------------------------------------- // // Copyright (c) Andrew Arnott. All rights reserved. // //----------------------------------------------------------------------- namespace RelyingPartyLogic { using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.ServiceModel; using System.Text; using System.Web; public class Database : IHttpModule, IDisposable { private const string DataContextKey = "DataContext"; private const string DataContextTransactionKey = "DataContextTransaction"; /// /// Initializes a new instance of the class. /// public Database() { } public static User LoggedInUser { get { return DataContext.AuthenticationTokens.Where(token => token.ClaimedIdentifier == HttpContext.Current.User.Identity.Name).Select(token => token.User).FirstOrDefault(); } } /// /// Gets the transaction-protected database connection for the current request. /// public static DatabaseEntities DataContext { get { DatabaseEntities dataContext = DataContextSimple; if (dataContext == null) { dataContext = new DatabaseEntities(); try { dataContext.Connection.Open(); } catch (EntityException entityEx) { var sqlEx = entityEx.InnerException as SqlException; if (sqlEx != null) { if (sqlEx.Class == 14 && sqlEx.Number == 15350) { // Most likely the database schema hasn't been created yet. HttpContext.Current.Response.Redirect("~/Setup.aspx"); } } throw; } DataContextTransaction = dataContext.Connection.BeginTransaction(); DataContextSimple = dataContext; } return dataContext; } } internal static IDbTransaction DataContextTransaction { get { if (HttpContext.Current != null) { return HttpContext.Current.Items[DataContextTransactionKey] as IDbTransaction; } else if (OperationContext.Current != null) { object data; if (OperationContext.Current.IncomingMessageProperties.TryGetValue(DataContextTransactionKey, out data)) { return data as IDbTransaction; } else { return null; } } else { throw new InvalidOperationException(); } } private set { if (HttpContext.Current != null) { HttpContext.Current.Items[DataContextTransactionKey] = value; } else if (OperationContext.Current != null) { OperationContext.Current.IncomingMessageProperties[DataContextTransactionKey] = value; } else { throw new InvalidOperationException(); } } } private static DatabaseEntities DataContextSimple { get { if (HttpContext.Current != null) { return HttpContext.Current.Items[DataContextKey] as DatabaseEntities; } else if (OperationContext.Current != null) { object data; if (OperationContext.Current.IncomingMessageProperties.TryGetValue(DataContextKey, out data)) { return data as DatabaseEntities; } else { return null; } } else { throw new InvalidOperationException(); } } set { if (HttpContext.Current != null) { HttpContext.Current.Items[DataContextKey] = value; } else if (OperationContext.Current != null) { OperationContext.Current.IncomingMessageProperties[DataContextKey] = value; } else { throw new InvalidOperationException(); } } } public void Dispose() { } void IHttpModule.Init(HttpApplication context) { context.EndRequest += this.Application_EndRequest; context.Error += this.Application_Error; } protected void Application_EndRequest(object sender, EventArgs e) { CommitAndCloseDatabaseIfNecessary(); } protected void Application_Error(object sender, EventArgs e) { if (DataContextTransaction != null) { DataContextTransaction.Rollback(); DataContextTransaction.Dispose(); DataContextTransaction = null; } } private static void CommitAndCloseDatabaseIfNecessary() { var dataContext = DataContextSimple; if (dataContext != null) { dataContext.SaveChanges(); if (DataContextTransaction != null) { DataContextTransaction.Commit(); DataContextTransaction.Dispose(); } dataContext.Dispose(); DataContextSimple = null; } } } }