Web Api Autofac InstancePerRequest - c#

I have a custom AuthorizationFilter Attribute on my Web Api project like this
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
public class GenericAuthenticationFilter : AuthorizationFilterAttribute
{
/// <summary>
/// Public default Constructor
/// </summary>
public GenericAuthenticationFilter()
{
}
private readonly bool _isActive = true;
/// <summary>
/// parameter isActive explicitly enables/disables this filter.
/// </summary>
/// <param name="isActive"></param>
public GenericAuthenticationFilter(bool isActive)
{
_isActive = isActive;
}
/// <summary>
/// Checks basic authentication request
/// </summary>
/// <param name="filterContext"></param>
public override void OnAuthorization(HttpActionContext filterContext)
{
if (!_isActive) return;
var identity = FetchAuthHeader(filterContext);
if (identity == null)
{
ChallengeAuthRequest(filterContext);
return;
}
var genericPrincipal = new GenericPrincipal(identity, null);
Thread.CurrentPrincipal = genericPrincipal;
if (!OnAuthorizeUser(identity.Name, identity.Password, filterContext))
{
ChallengeAuthRequest(filterContext);
return;
}
base.OnAuthorization(filterContext);
}
My StartUpClass is like this
public class Startup
{
public void Configuration(IAppBuilder app)
{
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
// Get your HttpConfiguration. In OWIN, you'll create one
// rather than using GlobalConfiguration.
var config = new HttpConfiguration();
WebApiConfig.Register(config);
IoC.Instance.RegisterApiControllers(Assembly.GetExecutingAssembly());
config.DependencyResolver =
new AutofacWebApiDependencyResolver(IoC.Instance.GetComponentsContainer());
// Register your Web Api controllers.
IoC.Instance.RegisterApiControllers(Assembly.GetExecutingAssembly());
IoC.Instance.RegisterWebApiModelBinders(Assembly.GetExecutingAssembly());
IoC.Instance.RegisterWebApiModelBinderProvider();
IoC.Instance.RegisterWebApiFilterProvider(config);
// Register the Autofac middleware FIRST, then the Autofac Web API middleware,
// and finally the standard Web API middleware.
app.UseAutofacMiddleware(IoC.Instance.GetComponentsContainer());
app.UseAutofacWebApi(config);
app.UseWebApi(config);
}
}
and my IoC class where all dependencies are resolved is like this
public class IoC : ContainerBuilder
{
/// <summary>
///
/// </summary>
private readonly static IoC _instance = new IoC();
/// <summary>
///
/// </summary>
private static object _lock;
/// <summary>
///
/// </summary>
private IContainer _componentsContainer;
/// <summary>
///
/// </summary>
public static IoC Instance
{
get
{
return _instance;
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public IContainer GetComponentsContainer()
{
if (_componentsContainer == null)
{
lock (_lock)
{
if (_componentsContainer == null)
_componentsContainer = this.Build();
}
}
return _componentsContainer;
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Resolve<T>() where T : class
{
return GetComponentsContainer().Resolve<T>();
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public ILifetimeScope BeginLifetimeScope()
{
return GetComponentsContainer().BeginLifetimeScope();
}
/// <summary>
///
/// </summary>
private IoC()
{
_lock = new object();
ConfigureDependencies();
}
/// <summary>
///
/// </summary>
private void ConfigureDependencies()
{
//Configure all your depedendencies here!!
//Database connection
var connectionString = ConfigurationManager.ConnectionStrings["DBConnectionStringName"].ConnectionString;
this.Register(c => new SqlConnection(connectionString)).As<IDbConnection>().InstancePerRequest();// InstancePerLifetimeScope();
//Database Connection OrmLite
OrmLiteConfig.DialectProvider = SqlServerDialect.Provider;
//Register Repositories
this.RegisterType<Repository>().As<IRepository>().InstancePerRequest();// InstancePerLifetimeScope();
// Register Services
this.RegisterType<UserService>().As<IUserService>().InstancePerRequest();// InstancePerLifetimeScope();
this.RegisterType<TokenService>().As<ITokenService>().InstancePerRequest();
this.RegisterType<DKMenuService>().As<IDKMenuService>().InstancePerRequest();// InstancePerLifetimeScope();
this.RegisterType<DKGRIDTblService>().As<IDKGRIDTblService>().InstancePerRequest();// InstancePerLifetimeScope();
this.RegisterType<FKService>().As<IFKService>().InstancePerRequest();// InstancePerLifetimeScope();
this.RegisterType<LOVService>().As<ILOVService>().InstancePerRequest();// InstancePerLifetimeScope();
this.RegisterType<JobService>().As<IJobService>().InstancePerRequest();// InstancePerLifetimeScope();
this.RegisterType<MADEService>().As<IMADEService>().InstancePerRequest();// InstancePerLifetimeScope();
}
}
And I decorate my Controllers with this filter like this
[GenericAuthenticationFilter]
public AuthenticateController(ITokenService tokenService)
{
_tokenService = tokenService;
}
My Problem is that the OnAuthorazation method of the GenericAuthenticationFilter is never fired.
If on the IoC Class class I change InstancePerRequest to InstancePerLifetimeScope everything works ok, but I want my dependencies to work per Request
Any Ideas?

I'm not sure if this is part or all of your issue, but... you can only build a ContainerBuilder once. In Startup.Configuration() I see on lines 11-12:
config.DependencyResolver =
new AutofacWebApiDependencyResolver(IoC.Instance.GetComponentsContainer());
And IoC.Instance.GetComponentsContainer() calls Build() to create the container.
But just two lines later I see you're adding more components to the container, and after that I see a second call:
app.UseAutofacMiddleware(IoC.Instance.GetComponentsContainer());
Based on your code, that's going to be the same container that was built before you added the new registrations. The container won't include the API controllers, the model binders, or the filter provider.
I'm actually not sure why you're not having more problems than you're having now.
Try moving the setting of the containers (the calls to IoC.Instance.GetComponentsContainer()) until all the way at the end, after you've finished registering all of your dependencies.

The only configuration that worked was the following
public class Startup
{
public void Configuration(IAppBuilder app)
{
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=316888
// Get your HttpConfiguration. In OWIN, you'll create one
// rather than using GlobalConfiguration.
var config = new HttpConfiguration();
WebApiConfig.Register(config);
// Register your Web Api controllers.
IoC.Instance.RegisterApiControllers(Assembly.GetExecutingAssembly());
IoC.Instance.RegisterWebApiModelBinders(Assembly.GetExecutingAssembly());
IoC.Instance.RegisterWebApiModelBinderProvider();
config.DependencyResolver =
new AutofacWebApiDependencyResolver(IoC.Instance.GetComponentsContainer());
// Register your Web Api controllers.
//IoC.Instance.RegisterApiControllers(Assembly.GetExecutingAssembly());
//IoC.Instance.RegisterWebApiModelBinders(Assembly.GetExecutingAssembly());
//IoC.Instance.RegisterWebApiModelBinderProvider();
// Register the Autofac middleware FIRST, then the Autofac Web API middleware,
// and finally the standard Web API middleware.
app.UseAutofacMiddleware(IoC.Instance.GetComponentsContainer());
app.UseAutofacWebApi(config);
app.UseWebApi(config);
}
}
I am still not sure whether it is right.
Examples of usage. I have a filter like the following
public class ApiAuthenticationFilter : GenericAuthenticationFilter
{
/// <summary>
/// Default Authentication Constructor
/// </summary>
public ApiAuthenticationFilter()
{
}
}
A method in this filter is using a service which is resolved like this
protected override bool OnAuthorizeUser(string username, string password, HttpActionContext actionContext)
{
var provider = actionContext.Request.GetDependencyScope().GetService(typeof(IUserService)) as IUserService;
}
My controllers on the other hand do not have parameterless constructors and the dependencies are resolved automatically
public class DKMenuController : ApiController
{
#region Private variable.
private readonly ITokenService _tokenService;
private readonly IDKMenuService _dkMenuService;
private readonly IUserService _userservice;
private const string Token = "Token";
#endregion
#region Public Constructor
/// <summary>
/// Public constructor to initialize DKMenu service instance
/// </summary>
public DKMenuController(ITokenService tokenService, IUserService userservice, IDKMenuService dkMenuService)
{
_tokenService = tokenService;
_dkMenuService = dkMenuService;
_userservice = userservice;
}
}
I don't know whether it is correct but it works

Related

Ninject Data injection in ASP.NET MVC project

I'm developing a web app that uses Ninject Data injection in my ASP.NET MVC5 project. I set up an NinjectDependencyResolver that inherits from IDependencyResolver like this:
public class NinjectDependencyResolver : IDependencyResolver
{
private IKernel kernel;
public NinjectDependencyResolver(IKernel kernelParam)
{
kernel = kernelParam;
AddBindings();
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
private void AddBindings()
{
// here I have all my bindings set up
kernel.Bind<ProConnect.Domain.Abstract.IMyRepository>().To<MyRepository>();
}
}
and here is the NinjectWebCommon class that is fired on application launch and that registers the services:
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(MyApp.WebUI.App_Start.NinjectWebCommon), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(MyApp.WebUI.App_Start.NinjectWebCommon), "Stop")]
namespace ProConnect.WebUI.App_Start
{
using System;
using System.Web;
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
using Ninject;
using Ninject.Web.Common;
using Ninject.Web.Common.WebHost;
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application.
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
RegisterServices(kernel);
return kernel;
}
catch
{
kernel.Dispose();
throw;
}
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
// creating the bridge between the NinjectDependencyResolver class and the MVC support for dependency injection.
System.Web.Mvc.DependencyResolver.SetResolver(new
MyApp.WebUI.Infrastructure.NinjectDependencyResolver(kernel));
// maybe I have to add some code here to create the bridge between
// NinjectDependencyResolver class and my standard classes that
// have nothing to do with MVC????
}
}
}
I use this to inject Repository object coming from the domain into my MVC controllers and this all works perfectly well.
The problem I have is that I would like to inject some other Repository Objects into a Settings Class that will retrieve some settings data from the database. Since my settings class is not a MVC controller but just a plain old class, it doesn't figure out how to inject the data.
Could some one help me on this one? I tried to set up again data injection like this but it didn't work:
public class Settings
{
private Domain.Abstract.ISettingRepository settingRepository;
private StandardKernel kernel;
public Settings()
{
this.kernel = new StandardKernel();
// I don't know if this loads a new kernel or the one that is used in the rest of the MVC application
kernel.Load(Assembly.GetExecutingAssembly());
// I tryed re-specifying the bindings but this didn't help
kernel.Bind<Domain.Abstract.ISettingRepository>().To<Domain.Concrete.SettingRepository>();
this.settingRepository = kernel.Get<Domain.Abstract.ISettingRepository>();
}
public void DoSomethigWithSettings(){
this.settingRepository.Settings()......
}
}
Ok I figured out the answer thanks to https://stackoverflow.com/a/19585471/11011693
I simply had get the object I wanted to inject in a non MVC class from the current MVC DependencyResolver that is set up on Application Start
public class Settings
{
private Domain.Abstract.ISettingRepository settingRepository;
public Settings()
{
// simply get the object you want to inject in a non MVC class
// from the current MVC DependencyResolver that is set up on Application Start
this.settingRepository = (Domain.Abstract.IAppSettingService)System.Web.Mvc.DependencyResolver.Current.GetService(typeof(Domain.Abstract.IAppSettingService));
}
public void DoSomethigWithSettings(){
this.settingRepository.Settings()......
}
}

Unable to read localized key value from Resource file

I am working on .NET Core Web API localization and I have done all configurations but I am unable to get local specific values.
Created 3 resource files for de-DE, fr-FR and English languages.
Created a common Middleware to set the current culture based on the
query string value.
Trying to get the respective local key but it is always giving English value.
Can anyone suggest and tell did I miss anything in the configuration.
Middleware
namespace i18n
{
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
/// <summary>
/// The LocalizationMiddleware class.
/// </summary>
public class LocalizationMiddleware
{
private readonly RequestDelegate _next;
/// <summary>
/// Initializes a new instance of the <see cref="LocalizationMiddleware"/> class.
/// </summary>
/// <param name="next">The next.</param>
public LocalizationMiddleware(RequestDelegate next)
{
_next = next;
}
/// <summary>
/// Invokes the specified context.
/// </summary>
/// <param name="context">The context.</param>
/// <returns>Task.</returns>
public async Task Invoke(HttpContext context)
{
var localValue = "en-US";
if (context.Request.Query.ContainsKey("locale"))
{
localValue = context.Request.Query["locale"];
}
Thread.CurrentThread.CurrentCulture = new CultureInfo(localValue);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(localValue);
await _next.Invoke(context);
}
}
/// <summary>
/// The LocalizationMiddlewareExtensions class.
/// </summary>
public static class LocalizationMiddlewareExtensions
{
/// <summary>
/// Uses the localization middleware.
/// </summary>
/// <param name="builder">The builder.</param>
/// <returns>The ApplicationBuilder.</returns>
public static IApplicationBuilder UseLocalizationMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<LocalizationMiddleware>();
}
} }
Startup class
I have registered the Middleware.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseLocalizationMiddleware();
}
Web API Controller
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
var name = Employees.Name; // Always Name is coming english value
return new string[] { name };
}
This is my solution structure:

Able to store in IHttpContextAccessor.HttpContext.Session - Retrieval is empty

I'm working with an API and using the session feature in .Net Core 2.1 with the standard dependency injection to store and retrieve values in the session store. My issue is that I'm able to set and store string values into the Session.store but when I then try to retrieve those values in another method, the store is empty.
Here is my Startup.cs setting up the IHttpContextAccessor for DI and enabling session storage.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non- // essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
// Configure app settings to inject in other classes.
services.AddOptions();
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
// Services to be injected.
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IAuthenticationService, AuthenticationService>();
services.AddSingleton<IConstituentsService, ConstituentsService>();
services.AddSingleton<ISessionService, SessionService>();
// Add MVC.
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// Configure session.
services.AddMemoryCache();
services.AddDistributedMemoryCache();
services.AddSession(options => {
options.IdleTimeout = TimeSpan.FromMinutes(10);
options.Cookie.Name = ".AuthCodeFlowTutorial.Session";
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseSession();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
Here is the class I'm using where I'm storing in the session store and then the method right after to retrieve. SetTokens() and TryGetString() respectively.
using System;
using System.Collections.Generic;
using System.Net.Http;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
namespace CHS.SkyApiAuthCodeFlow
{
/// <summary>
/// Sets, gets, and destroys session variables.
/// </summary>
public class SessionService : ISessionService
{
private const string ACCESS_TOKEN_NAME = "token";
private const string REFRESH_TOKEN_NAME = "refreshToken";
private readonly IHttpContextAccessor _httpContextAccessor;
public SessionService(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
/// <summary>
/// Destroys access and refresh tokens from the session.
/// </summary>
public void ClearTokens()
{
try
{
_httpContextAccessor.HttpContext.Session.Remove(ACCESS_TOKEN_NAME);
_httpContextAccessor.HttpContext.Session.Remove(REFRESH_TOKEN_NAME);
}
catch (Exception error)
{
Console.WriteLine("LOGOUT ERROR: " + error.Message);
}
}
/// <summary>
/// Return access token, if saved, or an empty string.
/// </summary>
public string GetAccessToken()
{
return TryGetString(ACCESS_TOKEN_NAME);
}
/// <summary>
/// Return refresh token, if saved, or an empty string.
/// </summary>
public string GetRefreshToken()
{
return TryGetString(REFRESH_TOKEN_NAME);
}
/// <summary>
/// Sets the access and refresh tokens based on an HTTP response.
/// </summary>
public void SetTokens(HttpResponseMessage response)
{
if (response.IsSuccessStatusCode)
{
string jsonString = response.Content.ReadAsStringAsync().Result;
Dictionary<string, string> attrs = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonString);
_httpContextAccessor.HttpContext.Session.SetString(ACCESS_TOKEN_NAME, attrs["access_token"]);
_httpContextAccessor.HttpContext.Session.SetString(REFRESH_TOKEN_NAME, attrs["refresh_token"]);
}
}
/// <summary>
/// Return session value as a string (if it exists), or an empty string.
/// </summary>
private string TryGetString(string name)
{
byte[] valueBytes = new Byte[700];
bool valueOkay = _httpContextAccessor.HttpContext.Session.TryGetValue(name, out valueBytes);
if (valueOkay)
{
return System.Text.Encoding.UTF8.GetString(valueBytes);
}
return null;
}
}
}
Below is the AuthenticationService that calls on the SessionService methods.
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using Microsoft.Extensions.Options;
namespace CHS.SkyApiAuthCodeFlow
{
/// <summary>
/// Contains business logic and helper methods that interact with the authentication provider.
/// </summary>
public class AuthenticationService : IAuthenticationService
{
private readonly IOptions<AppSettings> _appSettings;
private ISessionService _sessionService;
public AuthenticationService(IOptions<AppSettings> appSettings, ISessionService sessionService)
{
_appSettings = appSettings;
_sessionService = sessionService;
}
/// <summary>
/// Fetches access/refresh tokens from the provider.
/// <param name="requestBody">Key-value attributes to be sent with the request.</param>
/// <returns>The response from the provider.</returns>
/// </summary>
private HttpResponseMessage FetchTokens(Dictionary<string, string> requestBody)
{
using (HttpClient client = new HttpClient())
{
// Build token endpoint URL.
string url = new Uri(new Uri(_appSettings.Value.AuthBaseUri), "token").ToString();
// Set request headers.
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
client.DefaultRequestHeaders.TryAddWithoutValidation(
"Authorization", "Basic " + Base64Encode(_appSettings.Value.AuthClientId + ":" + _appSettings.Value.AuthClientSecret));
// Fetch tokens from auth server.
HttpResponseMessage response = client.PostAsync(url, new FormUrlEncodedContent(requestBody)).Result;
// Save the access/refresh tokens in the Session.
_sessionService.SetTokens(response);
return response;
}
}
/// <summary>
/// Fetches a new set of access/refresh tokens (from an authorization code).
/// <param name="code">The authorization code contained within the provider's authorization response.</param>
/// </summary>
public HttpResponseMessage ExchangeCodeForAccessToken(string code)
{
return FetchTokens(new Dictionary<string, string>(){
{ "code", code },
{ "grant_type", "authorization_code" },
{ "redirect_uri", _appSettings.Value.AuthRedirectUri }
});
}
/// <summary>
/// Refreshes the expired access token (from the refresh token stored in the session).
/// </summary>
public HttpResponseMessage RefreshAccessToken()
{
return FetchTokens(new Dictionary<string, string>(){
{ "grant_type", "refresh_token" },
{ "refresh_token", _sessionService.GetRefreshToken() }
});
}
/// <summary>
/// Builds and returns a string representative of the provider's authorization URI.
/// </summary>
public Uri GetAuthorizationUri()
{
return new Uri(
new Uri(_appSettings.Value.AuthBaseUri), "authorization" +
"?client_id=" + _appSettings.Value.AuthClientId +
"&response_type=code" +
"&redirect_uri=" + _appSettings.Value.AuthRedirectUri
);
}
/// <summary>
/// Determines if the session contains an access token.
/// </summary>
public bool IsAuthenticated()
{
return (_sessionService.GetAccessToken() != null);
}
/// <summary>
/// Destroys the access/refresh tokens stored in the session.
/// </summary>
public void LogOut()
{
_sessionService.ClearTokens();
}
/// <summary>
/// Encodes a string as Base64.
/// </summary>
private static string Base64Encode(string plainText)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(plainText);
return System.Convert.ToBase64String(bytes);
}
}
}

System.ArgumentNullException occurred in Microsoft.AspNet.Identity.Owin.dll

I am trying to develop an ASP MVC application and tried to created a simple Authentication which always works when creating a new project on my computer.
Now, i have a solution that was created on another machine which throws an exception when being run on my computer.
Here is the code that's throwing the exception
public IdentitySignInManager(BusinessModuleList modules, IAuthenticationManager authenticationManager)
: base(modules.Get<IdentityUserManager<TUser, TDataAccessModule, TDataContext>>(), authenticationManager)
{
Prerequisites = new List<Prerequisite>();
Modules = modules;
}
The above method is inside the IdentitySignInManager.cs file which looks like the following
public class IdentitySignInManager<TUser, TDataAccessModule, TDataContext> : SignInManager<TUser, String>, IBusinessModule
where TUser: UserBase
where TDataAccessModule : IdentityDataAccessModule<TUser, TDataContext>
where TDataContext : IdentityDataContext<TUser>
{
#region Properties
/// <summary>
/// The module list.
/// </summary>
public BusinessModuleList Modules { get; private set; }
/// <summary>
/// The prerequisites of the normal functionality of the module.
/// </summary>
public List<Prerequisite> Prerequisites { get; private set; }
#endregion
#region Constructors
/// <summary>
/// Initializes the new instance of IdentitySignInManager.
/// </summary>
/// <param name="modules">The module list.</param>
/// <param name="authenticationManager">The authentication manager.</param>
public IdentitySignInManager(BusinessModuleList modules, IAuthenticationManager authenticationManager)
: base(modules.Get<IdentityUserManager<TUser, TDataAccessModule, TDataContext>>(), authenticationManager)
{
Prerequisites = new List<Prerequisite>();
Modules = modules;
}
/// <summary>
/// Initializes the new instance of IdentitySignInManager. Supressed.
/// </summary>
private IdentitySignInManager(UserManager<TUser, String> userManager, IAuthenticationManager authenticationManager)
: base(userManager, authenticationManager)
{
}
#endregion
#region Methods
/// <summary>
/// Creates the claims based identity from the user.
/// </summary>
/// <param name="user">The user.</param>
/// <param name="authenticationType">The authentication type. Ther default is "ApplicationCookie".</param>
/// <returns>The claims based identity.</returns>
public async Task<ClaimsIdentity> CreateUserIdentityAsync(TUser user, String authenticationType = DefaultAuthenticationTypes.ApplicationCookie)
{
return await Modules.Get<IdentityUserManager<TUser, TDataAccessModule, TDataContext>>().CreateIdentityAsync(user, authenticationType);
}
/// <summary>
/// If disposing, calls dispose on the Context. Always nulls out the Context. Also disposes the Modules.
/// </summary>
/// <param name="disposing">True to dispose managed resources, false to not to dispose them.</param>
protected override void Dispose(bool disposing)
{
if (disposing)
{
Modules.Dispose();
Modules = null;
}
base.Dispose(disposing);
}
#endregion
}
The exception it throws is the following
An exception of type:
'System.ArgumentNullException' occurred in
Microsoft.AspNet.Identity.Owin.dll but was not handled in user code
If i click F5 and continue with the code, it shows me this error on the browser
Value cannot be null.
Parameter name: userManager
Microsoft.AspNet.Identity.Owin.SignInManager2..ctor(UserManager2 userManager, IAuthenticationManager authenticationManager)
at Core.BusinessModules.Users.Modules.IdentitySignInManager3..ctor(BusinessModuleList modules, IAuthenticationManager authenticationManager) in d:\projects\payroll\Trunk\Sources\Core.BusinessModules.Users\Modules\IdentitySignInManager.cs:line 50
at PR.Web.Application.Common.Modules.AppSignInManager..ctor(BusinessModuleList modules, IAuthenticationManager authenticationManager) in d:\projects\payroll\Trunk\Sources\PR.Web.Application\Common\Modules\AppSignInManager.cs:line 30
at PR.Web.Application.Common.Web.OWinContextCallbacks.CreateBusinessModules(IdentityFactoryOptions1 options, IOwinContext context) in d:\projects\payroll\Trunk\Sources\PR.Web.Application\Common\Web\OWinContextCallbacks.cs:line 37
at Microsoft.AspNet.Identity.Owin.IdentityFactoryProvider1.Create(IdentityFactoryOptions1 options, IOwinContext context)
at Microsoft.AspNet.Identity.Owin.IdentityFactoryMiddleware`2.d__0.MoveNext()
On the startup.cs i have the following code, among others
private static void ConfigureAuthentication(IAppBuilder appBuilder)
{
appBuilder.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<AppUserManager, User>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie))
}
});
appBuilder.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
}
The exception is thrown immediately after it finishes executing the above code.
How would i fix this error?

How do i set up dependencies using ninject with WebAPI [duplicate]

This question already has answers here:
How to use Ninject with ASP.NET Web API?
(4 answers)
Closed 8 years ago.
I've installed the Ninject.Web.WebAPI package using Nuget and i cant figure out how to bind my dependencies.
I regularly use Ninject with my MVC apps and when i install the Ninject package it creates a NinjectWebCommon.cs file where i set up my bindings. This file doesnt appear to generate for the WebAPI project.
Anyone help me out on where to put my bindings.
cheers
Create a class to fix NinjectDependencyResolver issue of web api.
public class NinjectDependencyResolverHelper : IDependencyScope
{
IResolutionRoot resolver;
public NinjectDependencyResolverHelper(IResolutionRoot resolver)
{
this.resolver = resolver;
}
public object GetService(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has been disposed");
return resolver.TryGet(serviceType);
}
public System.Collections.Generic.IEnumerable<object> GetServices(Type serviceType)
{
if (resolver == null)
throw new ObjectDisposedException("this", "This scope has been disposed");
return resolver.GetAll(serviceType);
}
public void Dispose()
{
var disposable = resolver as IDisposable;
if (disposable != null)
disposable.Dispose();
resolver = null;
}
}
public class NinjectDependencyResolver : NinjectDependencyResolverHelper, IDependencyResolver
{
IKernel kernel;
public NinjectDependencyResolver(IKernel kernel)
: base(kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return new NinjectDependencyResolverHelper(kernel.BeginBlock());
}
}
Then create NinjectWebCommon class
public static class NinjectWebCommon
{
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
/// <summary>
/// Starts the application
/// </summary>
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
bootstrapper.Initialize(CreateKernel);
}
/// <summary>
/// Stops the application.
/// </summary>
public static void Stop()
{
bootstrapper.ShutDown();
}
/// <summary>
/// Creates the kernel that will manage your application.
/// </summary>
/// <returns>The created kernel.</returns>
private static IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel);
RegisterServices(kernel);
return kernel;
}
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel)
{
//Bind your stuff
}
}
Hope this helps.

Categories