SQL Server and iis create a lot of connections - asp.net

I have an ASP.net mvc application that uses Fluent Nhiberate, SQL Server, and autofac. When my application is published, IIS creates a lot of connections to SQL Server that are not being closed.
My SessionManager class:
public class SessionPerRequestModule : IHttpModule
{
private static readonly string NH_SESSION_ISOK_KEY = "NH_SESSION_ISOK";
private static readonly string NH_SESSION_PREFFIX_KEY = "NH_SESSION";
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.EndRequest += CtxEndRequest;
context.Error += CtxOnError;
}
private void CtxOnError(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
context.Items[NH_SESSION_ISOK_KEY] = false;
}
private void CtxEndRequest(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
foreach (string dbKey in DatabaseKeys.AllKeys)
{
ISession session = GetCurrentSession(dbKey, false);
CloseSession(session);
SetSession(dbKey, null);
}
}
public static bool IsOnError
{
get { return Convert.ToBoolean(HttpContext.Current.Items[NH_SESSION_ISOK_KEY]); }
set { HttpContext.Current.Items[NH_SESSION_ISOK_KEY] = value; }
}
private static ISession OpenSession(string dbKey)
{
try
{
var interceptor = new SetSystemPropertiesInterceptor(
() => DependencyResolver.Current.GetService<IAuthenticationService>()
);
ISession session;
session = NHibernateSessionHelper.GetFactory(dbKey).OpenSession(interceptor);
if (session == null)
throw new InvalidOperationException(string.Format("Call to factory.OpenSession('{0}') returned null.", dbKey));
session.FlushMode = FlushMode.Never;
session.BeginTransaction();
interceptor.SetSession(session);
return session;
}
catch (Exception ex)
{
throw new Exception(string.Format("Error on database with key '{0}'", dbKey), ex);
}
}
private static void CloseSession(ISession session)
{
if (session != null)
{
try
{
if (!IsOnError)
{
if (session.Transaction != null && session.Transaction.IsActive)
session.Transaction.Commit();
else
session.Flush();
}
else
session.Transaction.Rollback();
}
finally
{
session.Dispose();
}
}
}
public static ISession GetCurrentSession(string dbKey)
{
return GetCurrentSession(dbKey, true);
}
public static ISession GetCurrentSession(string dbKey, bool createIfNotFound)
{
string fullKey = FormatFullContextKey(dbKey);
ISession session = HttpContext.Current.Items[fullKey] as ISession;
if (createIfNotFound && session == null)
{
session = OpenSession(dbKey);
SetSession(dbKey, session);
}
return session;
}
private static void SetSession(string dbKey, ISession session)
{
string fullKey = FormatFullContextKey(dbKey);
HttpContext.Current.Items[fullKey] = session;
}
private static string FormatFullContextKey(string dbKey)
{
return string.Concat(NH_SESSION_PREFFIX_KEY, "_", dbKey);
}
}
Part of my NHibernate session helper:
factory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.FormatSql().ShowSql().AdoNetBatchSize(50).ConnectionString(c => c.FromConnectionStringWithKey(databaseKey)))
.Mappings(x =>
x.FluentMappings.AddFromAssemblyOf<ColaboradorMapping>()
.Conventions.AddFromAssemblyOf<CustomTypeConvention>()
).BuildSessionFactory();
factories.Add(databaseKey, factory);
My Autofac injection:
public static IContainer RegisterAllDependencies()
{
var builder = new ContainerBuilder();
builder.Register(x => new VejoSeriesDb(SessionPerRequestModule.GetCurrentSession(DatabaseKeys.VejoSeriesDb))).As<IVejoSeriesDb>();
builder.Register(x => new StarkDb(SessionPerRequestModule.GetCurrentSession(DatabaseKeys.MySQLStarkDb))).As<IStarkDb>();
//session mongo
builder.Register(x => new StarkMongoDb()).As<IStarkMongoDb>();
builder.RegisterAssemblyTypes(typeof(IUsuarioSerieN).Assembly)
.AsImplementedInterfaces();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterFilterProvider();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
return container;
}
Where I´m forgetting to close the connections?

Related

Why is my blazor app leaving so many ports open

I created a .net 6 app using server side Blazor and SignalR. The app was basically a single page with 10 different components. Each component was a client that looked something like this:
#code {
private HubConnection? hubConnection;
private ExampleViewModel data { get; set; } = new ExampleViewModel();
protected override async Task OnInitializedAsync()
{
hubConnection = new HubConnectionBuilder()
.WithUrl(NavigationManager.ToAbsoluteUri("/mainhub"))
.Build();
hubConnection.On<ExampleViewModel>("example", (Data) =>
{
data = Data;
StateHasChanged();
});
await hubConnection.StartAsync();
}
public async ValueTask DisposeAsync()
{
if (hubConnection is not null)
{
await hubConnection.DisposeAsync();
}
}
}
Each component has a "broadcaster" that runs on a timer and makes a call to the database using Mediator and Dapper. Example:
public class ExampleBroadcaster : IDataBroadcaster
{
private readonly IMediator _mediator;
private readonly ILogger<ExampleBroadcaster> _logger;
private readonly IHubContext<MainHub> _mainHub;
private readonly IMemoryCache _cache;
private const string Something = "example";
private Timer _timer;
public ExampleBroadcaster(IHubContext<MainHub> mainHub,
IMediator mediator, ILogger<ExampleBroadcaster> logger,
IMemoryCache cache)
{
_mainHub = mainHub;
_mediator = mediator;
_logger = logger;
_cache = cache;
}
public void Start()
{
_timer = new Timer(BroadcastData, null, 0, 30000);
}
private async void BroadcastData(object? state)
{
ExampleViewModel viewModel;
try
{
if (_cache.TryGetValue(Something, out ExampleViewModel data))
{
viewModel = data;
}
else
{
viewModel = _mediator.Send(new GetExampleData()).Result;
_cache.Set(Something, viewModel, TimeSpan.FromMinutes(10));
}
await _mainHub.Clients.All.SendAsync("example", viewModel);
}
catch (Exception ex)
{
_logger.LogError(ex, ex.Message);
}
}
}
The mediator handler simply uses Dapper to get data from the database:
public class GetExampleData : IRequest<ExampleViewModel>
{
}
public class GetExampleDataHandler : IRequestHandler<GetExampleData, ExampleViewModel>
{
private readonly IDbConnectionFactory _connectionFactory;
private string _storedProcedure = "some sproc name";
public GetExampleDataHandler(IDbConnectionFactory connectionFactory)
{
_connectionFactory = connectionFactory;
}
public async Task<ExampleViewModel> Handle(GetExampleData request, CancellationToken cancellationToken)
{
using (var connection = _connectionFactory.GetReadOnlyConnection())
{
return await connection.QueryFirstAsync<ExampleViewModel>(_storedProcedure, CommandType.StoredProcedure);
}
}
}
This is the main razor page that houses all the individual components:
#code {
private HubConnection? hubConnection;
protected override async Task OnInitializedAsync()
{
try
{
hubConnection = new HubConnectionBuilder()
.WithUrl(NavigationManager.ToAbsoluteUri("/mainhub"))
.Build();
await hubConnection.StartAsync();
await hubConnection.SendAsync("Init");
}
catch(Exception exception)
{
Logger.LogError(exception, exception.Message);
}
}
public async ValueTask DisposeAsync()
{
if (hubConnection is not null)
{
await hubConnection.DisposeAsync();
}
}
}
Finally, the MainHub.cs code:
public class MainHub : Hub
{
IEnumerable<IDataBroadcaster> _broadcasters;
private static bool _started;
public MainHub(IEnumerable<IDataBroadcaster> broadcasters)
{
_broadcasters = broadcasters;
}
public void Init()
{
if (!_started)
{
StartBroadcasting();
_started = true;
}
}
private void StartBroadcasting()
{
foreach (var broadcaster in _broadcasters)
{
broadcaster.Start();
}
}
}
This all worked fine locally, in our dev environment, and our test environment. In production, we found that the app was crashing after a number of hours. According to the server admins, the app is opening 100s or 1000s of ports and leaving them open until the number of allotted ports was hit, causing the app to crash.
What is the issue here? The broadcasters are registered as singletons. This app only runs on one web server.

signalr : after Authentication i get error 400 (Bad Request) in client-side

after Task.CompletedTask i get error 400 (Bad Request) in "client-side"
What am I missing to go through the Authentication phase?
Server:
public class Startup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = options.DefaultScheme;
options.DefaultChallengeScheme = options.DefaultScheme;
})
.AddJwtBearer(options =>
{
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
var accessToken = context.Request.Headers["Authorization"];
var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken))
{
context.Token = accessToken.ToString().Substring("Token ".Length).Trim();
}
return Task.CompletedTask;
}
};
});
services.AddSignalR();
services.AddSingleton<IMongoDBService, MongoDBService>();
}
public override void Configure(IApplicationBuilder builder, IEndpointRouteBuilder routes, IServiceProvider serviceProvider)
{
builder.UseCors("CorsPolicy");
builder.UseAuthentication();
builder.UseEndpoints(endpoints =>
{
endpoints.MapHub<PrintEventsHub>("/Events/PrintEventsHub");
endpoints.MapHub<NotificationEventsHub>("/Events/NotificationEventsHub");
});
}
}
Hub:
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class NotificationEventsHub : Hub//, IPrinterEventsHub
{
private readonly ISession _session;
private readonly ITelegramServices _telegramServices;
private readonly ISaveEventToDBServices _saveEventToDBServices;
private readonly IHubContext<NotificationEventsHub> _Context;
private string ConnectionID;
public NotificationEventsHub(IHubContext<NotificationEventsHub> context,
ISession session,
ITelegramServices telegramServices,
ISaveEventToDBServices saveEventToDBServices)
{
_Context = context;
_session = session;
_telegramServices = telegramServices;
_saveEventToDBServices = saveEventToDBServices;
}
public override Task OnConnectedAsync()
{
ConnectionID = this.Context.ConnectionId;
var connectedUser = Context.User.Identity;
return base.OnConnectedAsync();
}
public override Task OnDisconnectedAsync(Exception exception)
{
return base.OnDisconnectedAsync(exception);
}
public async Task GetNotificationMsg(string jsonStringNotification)
{
}
}
Client:
public static async Task<bool> SendPrinterEventToCloudManager()
{
var SignalRConnectionInfo = new SignalRConnectionInfo();
SignalRConnectionInfo.AccessToken = "test";
string _SignalRUrl =
"https://localhost:44300/Events/NotificationEventsHub";
try
{
HubConnection connection = new HubConnectionBuilder().WithUrl(_SignalRUrl,
o => o.AccessTokenProvider = () => Task.FromResult(SignalRConnectionInfo.AccessToken)).Build();
await connection.StartAsync();
await connection.InvokeAsync("GetNotificationMsg", "testmsg");
return true;
}
catch (Exception ex)
{
var msg = ex.Message;
return false;
}
}
i am try to use JwtBearer token and after i read the value what's next step to aprrove that the user Authentication?

ASP.NET core 2 act as reverse proxy usering rewrite middleware

I'm struggling to make my asp.net core 2 app act like a reverse proxy using URL Rewrite rules.
I have the following in my startup.cs:
var rewriteRules = new RewriteOptions()
.AddRedirectToHttps();
.AddRewrite(#"^POC/(.*)", "http://192.168.7.73:3001/$1", true);
app.UseRewriter(rewriteRules);
The rewrite rule is exactly as it is in my IIS settings (which I'm trying to replace with this method) which works fine.
I'm assuming it has something to do with forwarding the headers maybe? Or maybe I just don't understand how the Rewrite Middleware is supposed to work, if you want the requests to be forwarded instead of just rewritten relative to current hostname.
A reverse proxy can be emulated/implemeted within a middleware :
First the startup class where we add a IUrlRewriter service and the ProxyMiddleware.
public class Startup
{
private readonly IConfiguration _configuration;
public Startup(IConfiguration configuration)
{
_configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IUrlRewriter>(new SingleRegexRewriter(#"^/POC/(.*)", "http://192.168.7.73:3001/$1"));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseRewriter(new RewriteOptions().AddRedirectToHttps());
app.UseMiddleware<ProxyMiddleware>();
}
}
Next we will create a basic implementation of IUrlRewriter. The RewriteUri method must transform the HttpContext into an absolute Uri. Or null if the url should not be redirected in the middleware.
public interface IUrlRewriter
{
Task<Uri> RewriteUri(HttpContext context);
}
public class SingleRegexRewriter : IUrlRewriter
{
private readonly string _pattern;
private readonly string _replacement;
private readonly RegexOptions _options;
public SingleRegexRewriter(string pattern, string replacement)
: this(pattern, replacement, RegexOptions.None) { }
public SingleRegexRewriter(string pattern, string replacement, RegexOptions options)
{
_pattern = pattern ?? throw new ArgumentNullException(nameof(pattern));
_replacement = replacement ?? throw new ArgumentNullException(nameof(pattern));
_options = options;
}
public Task<Uri> RewriteUri(HttpContext context)
{
string url = context.Request.Path + context.Request.QueryString;
var newUri = Regex.Replace(url, _pattern, _replacement);
if (Uri.TryCreate(newUri, UriKind.Absolute, out var targetUri))
{
return Task.FromResult(targetUri);
}
return Task.FromResult((Uri)null);
}
}
And then the Middleware (stolen from an old verison of aspnet proxy repo) and customized. It get the IUrlRewrite service as parameter of Invoke method.
The pipeline is :
Try rewrite url
Create a HttpRequestMessage
Copy Request Header and content
Send the request
Copy response header
Copy response content
done
Et voila
public class ProxyMiddleware
{
private static readonly HttpClient _httpClient = new HttpClient(new HttpClientHandler()
{
AllowAutoRedirect = false,
MaxConnectionsPerServer = int.MaxValue,
UseCookies = false,
});
private const string CDN_HEADER_NAME = "Cache-Control";
private static readonly string[] NotForwardedHttpHeaders = new[] { "Connection", "Host" };
private readonly RequestDelegate _next;
private readonly ILogger<ProxyMiddleware> _logger;
public ProxyMiddleware(
RequestDelegate next,
ILogger<ProxyMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task Invoke(HttpContext context, IUrlRewriter urlRewriter)
{
var targetUri = await urlRewriter.RewriteUri(context);
if (targetUri != null)
{
var requestMessage = GenerateProxifiedRequest(context, targetUri);
await SendAsync(context, requestMessage);
return;
}
await _next(context);
}
private async Task SendAsync(HttpContext context, HttpRequestMessage requestMessage)
{
using (var responseMessage = await _httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted))
{
context.Response.StatusCode = (int)responseMessage.StatusCode;
foreach (var header in responseMessage.Headers)
{
context.Response.Headers[header.Key] = header.Value.ToArray();
}
foreach (var header in responseMessage.Content.Headers)
{
context.Response.Headers[header.Key] = header.Value.ToArray();
}
context.Response.Headers.Remove("transfer-encoding");
if (!context.Response.Headers.ContainsKey(CDN_HEADER_NAME))
{
context.Response.Headers.Add(CDN_HEADER_NAME, "no-cache, no-store");
}
await responseMessage.Content.CopyToAsync(context.Response.Body);
}
}
private static HttpRequestMessage GenerateProxifiedRequest(HttpContext context, Uri targetUri)
{
var requestMessage = new HttpRequestMessage();
CopyRequestContentAndHeaders(context, requestMessage);
requestMessage.RequestUri = targetUri;
requestMessage.Headers.Host = targetUri.Host;
requestMessage.Method = GetMethod(context.Request.Method);
return requestMessage;
}
private static void CopyRequestContentAndHeaders(HttpContext context, HttpRequestMessage requestMessage)
{
var requestMethod = context.Request.Method;
if (!HttpMethods.IsGet(requestMethod) &&
!HttpMethods.IsHead(requestMethod) &&
!HttpMethods.IsDelete(requestMethod) &&
!HttpMethods.IsTrace(requestMethod))
{
var streamContent = new StreamContent(context.Request.Body);
requestMessage.Content = streamContent;
}
foreach (var header in context.Request.Headers)
{
if (!NotForwardedHttpHeaders.Contains(header.Key))
{
if (header.Key != "User-Agent")
{
if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()) && requestMessage.Content != null)
{
requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray());
}
}
else
{
string userAgent = header.Value.Count > 0 ? (header.Value[0] + " " + context.TraceIdentifier) : string.Empty;
if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, userAgent) && requestMessage.Content != null)
{
requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, userAgent);
}
}
}
}
}
private static HttpMethod GetMethod(string method)
{
if (HttpMethods.IsDelete(method)) return HttpMethod.Delete;
if (HttpMethods.IsGet(method)) return HttpMethod.Get;
if (HttpMethods.IsHead(method)) return HttpMethod.Head;
if (HttpMethods.IsOptions(method)) return HttpMethod.Options;
if (HttpMethods.IsPost(method)) return HttpMethod.Post;
if (HttpMethods.IsPut(method)) return HttpMethod.Put;
if (HttpMethods.IsTrace(method)) return HttpMethod.Trace;
return new HttpMethod(method);
}
}
Bonus : some other Rewriter
public class PrefixRewriter : IUrlRewriter
{
private readonly PathString _prefix;
private readonly string _newHost;
public PrefixRewriter(PathString prefix, string newHost)
{
_prefix = prefix;
_newHost = newHost;
}
public Task<Uri> RewriteUri(HttpContext context)
{
if (context.Request.Path.StartsWithSegments(_prefix))
{
var newUri = context.Request.Path.Value.Remove(0, _prefix.Value.Length) + context.Request.QueryString;
var targetUri = new Uri(_newHost + newUri);
return Task.FromResult(targetUri);
}
return Task.FromResult((Uri)null);
}
}
public class MergeRewriter : IUrlRewriter
{
private readonly List<IUrlRewriter> _rewriters = new List<IUrlRewriter>();
public MergeRewriter()
{
}
public MergeRewriter(IEnumerable<IUrlRewriter> rewriters)
{
if (rewriters == null) throw new ArgumentNullException(nameof(rewriters));
_rewriters.AddRange(rewriters);
}
public MergeRewriter Add(IUrlRewriter rewriter)
{
if (rewriter == null) throw new ArgumentNullException(nameof(rewriter));
_rewriters.Add(rewriter);
return this;
}
public async Task<Uri> RewriteUri(HttpContext context)
{
foreach (var rewriter in _rewriters)
{
var targetUri = await rewriter.RewriteUri(context);
if(targetUri != null)
{
return targetUri;
}
}
return null;
}
}
// In Statup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IUrlRewriter>(new MergeRewriter()
.Add(new PrefixRewriter("/POC/API", "http://localhost:1234"))
.Add(new SingleRegexRewriter(#"^/POC/(.*)", "http://192.168.7.73:3001/$1")));
}
Edit
I found a project to do same but with way more other feature https://github.com/damianh/ProxyKit as a nuget package

Onion Architecture Unit Of Work Transaction Not getting Connection String

I am using Onion Architecture with Autofac. In my Dependency Injection Code, I am using:
[assembly: WebActivatorEx.PostApplicationStartMethod(typeof(IocConfig), "RegisterDependencies")]
namespace AppMVC.Infrastructure.Bootstrapper
{
public class IocConfig
{
public static void RegisterDependencies()
{
var builder = new ContainerBuilder();
builder.RegisterType(typeof(UnitOfWork)).As(typeof(IUnitOfWork)).InstancePerHttpRequest();
builder.Register<IEntitiesContext>(b =>
{
var context = new MyContext("My Connection String");
return context;
}).InstancePerHttpRequest();
}
}
}
Unit Of Work Code:
public class UnitOfWork : IUnitOfWork
{
private readonly IEntitiesContext _context;
private bool _disposed;
private Hashtable _repositories;
public UnitOfWork(IEntitiesContext context)
{
_context = context;
}
public int SaveChanges()
{
return _context.SaveChanges();
}
public IRepository<TEntity> Repository<TEntity>() where TEntity : BaseEntity
{
if (_repositories == null)
{
_repositories = new Hashtable();
}
var type = typeof(TEntity).Name;
if (_repositories.ContainsKey(type))
{
return (IRepository<TEntity>)_repositories[type];
}
var repositoryType = typeof(EntityRepository<>);
_repositories.Add(type, Activator.CreateInstance(repositoryType.MakeGenericType(typeof(TEntity)), _context));
return (IRepository<TEntity>)_repositories[type];
}
public void BeginTransaction()
{
_context.BeginTransaction();
}
public int Commit()
{
return _context.Commit();
}
public void Rollback()
{
_context.Rollback();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public virtual void Dispose(bool disposing)
{
if (!_disposed && disposing)
{
_context.Dispose();
foreach (IDisposable repository in _repositories.Values)
{
repository.Dispose();// dispose all repositries
}
}
_disposed = true;
}
}
MyContext Code:
public class MyContext : DbContext, IEntitiesContext
{
private ObjectContext _objectContext;
private DbTransaction _transaction;
public MyContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
}
public void BeginTransaction()
{
_objectContext = ((IObjectContextAdapter)this).ObjectContext;
if (_objectContext.Connection.State == ConnectionState.Open)
{
if (_transaction == null)
{
_transaction = _objectContext.Connection.BeginTransaction();
}
return;
}
_objectContext.Connection.Open(); // At this Line, I am getting Exception
if (_transaction == null)
{
_transaction = _objectContext.Connection.BeginTransaction();
}
}
public int Commit()
{
var saveChanges = SaveChanges();
_transaction.Commit();
return saveChanges;
}
public void Rollback()
{
_transaction.Rollback();
}
}
My problem is, On _objectContext.Connection.Open();, I am getting Connection String missing error.
Below is the screenshot of the Exception:

Structuremap error when using HttpContextBase in constructor

I am building a ASP.NET MVC 2.0 app on .NET 4.0 and am using Structuremap 2.6.1 for IoC. I recently added a ICookie and Cookie class, the Cookie class takes HttpContextBase as a constructor parameter (See below) and now when I run my app I get this error :No Default Instance defined for PluginFamily System.Web.HttpContextBase.
I have used this method before in another MVC app with the same stack but did not get this error. Am I missing something? If I do need to add some mapping code for HttoContextBase in my structuremap configuration file what would I use?
And help would be great!!!
Cookie.cs
public class Cookie : ICookie
{
private readonly HttpContextBase _httpContext;
private static bool defaultHttpOnly = true;
private static float defaultExpireDurationInDays = 1;
private readonly ICryptographer _cryptographer;
public Cookie(HttpContextBase httpContext, ICryptographer cryptographer)
{
Check.Argument.IsNotNull(httpContext, "httpContext");
Check.Argument.IsNotNull(cryptographer, "cryptographer");
_cryptographer = cryptographer;
_httpContext = httpContext;
}
public static bool DefaultHttpOnly
{
[DebuggerStepThrough]
get { return defaultHttpOnly; }
[DebuggerStepThrough]
set { defaultHttpOnly = value; }
}
public static float DefaultExpireDurationInDays
{
[DebuggerStepThrough]
get { return defaultExpireDurationInDays; }
[DebuggerStepThrough]
set
{
Check.Argument.IsNotZeroOrNegative(value, "value");
defaultExpireDurationInDays = value;
}
}
public T GetValue<T>(string key)
{
return GetValue<T>(key, false);
}
public T GetValue<T>(string key, bool expireOnceRead)
{
var cookie = _httpContext.Request.Cookies[key];
T value = default(T);
if (cookie != null)
{
if (!string.IsNullOrWhiteSpace(cookie.Value))
{
var converter = TypeDescriptor.GetConverter(typeof(T));
try
{
value = (T)converter.ConvertFromString(_cryptographer.Decrypt(cookie.Value));
}
catch (NotSupportedException)
{
if (converter.CanConvertFrom(typeof(string)))
{
value = (T)converter.ConvertFrom(_cryptographer.Decrypt(cookie.Value));
}
}
}
if (expireOnceRead)
{
cookie = _httpContext.Response.Cookies[key];
if (cookie != null)
{
cookie.Expires = DateTime.Now.AddDays(-100d);
}
}
}
return value;
}
public void SetValue<T>(string key, T value)
{
SetValue(key, value, DefaultExpireDurationInDays, DefaultHttpOnly);
}
public void SetValue<T>(string key, T value, float expireDurationInDays)
{
SetValue(key, value, expireDurationInDays, DefaultHttpOnly);
}
public void SetValue<T>(string key, T value, bool httpOnly)
{
SetValue(key, value, DefaultExpireDurationInDays, httpOnly);
}
public void SetValue<T>(string key, T value, float expireDurationInDays, bool httpOnly)
{
TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
string cookieValue = string.Empty;
try
{
cookieValue = converter.ConvertToString(value);
}
catch (NotSupportedException)
{
if (converter.CanConvertTo(typeof(string)))
{
cookieValue = (string)converter.ConvertTo(value, typeof(string));
}
}
if (!string.IsNullOrWhiteSpace(cookieValue))
{
var cookie = new HttpCookie(key, _cryptographer.Encrypt(cookieValue))
{
Expires = DateTime.Now.AddDays(expireDurationInDays),
HttpOnly = httpOnly
};
_httpContext.Response.Cookies.Add(cookie);
}
}
}
IocMapping.cs
public class IoCMapping
{
public static void Configure()
{
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ProjectName.Core.Properties.Settings.ProjectNameConnectionString"].ConnectionString;
MappingSource mappingSource = new AttributeMappingSource();
ObjectFactory.Initialize(x =>
{
x.Scan(scan =>
{
scan.Assembly("ProjectName.Core");
scan.Assembly("ProjectName.WebUI");
scan.WithDefaultConventions();
});
x.For<IUnitOfWork>().HttpContextScoped().Use<UnitOfWork>();
x.For<IDatabase>().HttpContextScoped().Use<Database>().Ctor<string>("connection").Is(connectionString).Ctor<MappingSource>("mappingSource").Is(mappingSource);
x.For<ILogger>().Singleton().Use<NLogLogger>();
x.For<ICacheManager>().Singleton().Use<CacheManager>().Ctor<System.Web.Caching.Cache>().Is(HttpRuntime.Cache);
x.For<IEmailSender>().Singleton().Use<EmailSender>();
x.For<IAuthenticationService>().HttpContextScoped().Use<AuthenticationService>();
x.For<ICryptographer>().Use<Cryptographer>();
x.For<IUserSession>().HttpContextScoped().Use<UserSession>();
x.For<ICookie>().HttpContextScoped().Use<Cookie>();
x.For<ISEORepository>().HttpContextScoped().Use<SEORepository>();
x.For<ISpotlightRepository>().HttpContextScoped().Use<SpotlightRepository>();
x.For<IContentBlockRepository>().HttpContextScoped().Use<ContentBlockRepository>();
x.For<ICatalogRepository>().HttpContextScoped().Use<CatalogRepository>();
x.For<IPressRoomRepository>().HttpContextScoped().Use<PressRoomRepository>();
x.For<IEventRepository>().HttpContextScoped().Use<EventRepository>();
x.For<IProductRegistrationRepository>().HttpContextScoped().Use<ProductRegistrationRepository>();
x.For<IWarrantyRepository>().HttpContextScoped().Use<WarrantyRepository>();
x.For<IInstallerRepository>().HttpContextScoped().Use<InstallerRepository>();
x.For<ISafetyNoticeRepository>().HttpContextScoped().Use<SafetyNoticeRepository>();
x.For<ITradeAlertRepository>().HttpContextScoped().Use<TradeAlertRepository>();
x.For<ITestimonialRepository>().HttpContextScoped().Use<TestimonialRespository>();
x.For<IProjectPricingRequestRepository>().HttpContextScoped().Use<ProjectPricingRequestRepository>();
x.For<IUserRepository>().HttpContextScoped().Use<UserRepository>();
x.For<IRecipeRepository>().HttpContextScoped().Use<RecipeRepository>();
});
LogUtility.Log.Info("Registering types with StructureMap");
}
}
I believe you would need to register the HttpContextBase on every request in your Begin_Request handler like so:
For<HttpContextBase>().Use(() => new HttpContextWrapper(HttpContext.Current));
Update: Make sure you register a lambda, otherwise you StructureMap will store the HttpContext available at registration time as a singleton.

Resources