I am trying to bind the IIdentity from HttpContext.Current.User.Identity to a custom IPrincipal but from what I can gather, IIdentity is null before user is authenticated.
Sample code:
public interface ICustomPrincipal
{
int UserID { get; set; }
}
public class CustomPrincipal : ICustomPrincipal
{
private readonly IIdentity _identity;
private readonly IUserRepository _userRepository;
public CustomPrincipal(IIdentity identity, IUserRepository repository)
{
_identity = identity;
_repository = repository;
}
}
And then
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
if (Request.IsAuthenticated && !Request.Url.AbsoluteUri.Contains(".axd"))
{
HttpContext.Current.User as CustomPrincipal;
}
}
I can bind IUserRepository no problem but I do not know how to properly bind IIdentity.
I have tried to bind the HttpContext.Current.User.Identity in CreateKernel() on Application_Start, but the problem is, the IIdentity is null.
I have also tried using GlobalFilters and Ninject.BindFilter method to set the CustomPrincipal but the problem revolves back to IIdentity being null.
I do not want to call the constructor of CustomPrincipal because IUserRepository also involves constructor injection.
I'm unsure of whether I am not binding correctly, or my implementation method is not right, any ideas or suggestions would be appreciated.
What I am trying to achieve in the end is to pass ICustomPrincipal down to the DB level to record the UserID on transactions.
Thanks
here is a sample showing bootstrap AFTER and BEFORE authentication
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//WebApiConfig.Register(GlobalConfiguration.Configuration);
//BundleMobileConfig.RegisterBundles(BundleTable.Bundles);
}
private bool _isBootStrapped;
private bool _isBootStrappedAuthenticated;
public override void Init()
{
base.Init();
// handlers managed by ASP.Net during Forms authentication
BeginRequest += new EventHandler(BeginRequestHandler);
PostAuthorizeRequest += new EventHandler(PostAuthHandler);
EndRequest += new EventHandler(EndRequestHandler);
}
public void EndRequestHandler(object sender, EventArgs e)
{
}
public void BeginRequestHandler(object sender, EventArgs e)
{
BootStrapUnauthentiated();
}
public void PostAuthHandler(object sender, EventArgs e)
{
if (_isBootStrappedAuthenticated)
{
return; // nuff done...
}
BootStrapAuthenticated();
BootStrapUnauthentiated();
}
private void BootStrapAuthenticated()
{
if (Request.IsAuthenticated)
{
BootStrapHttp(Context);
BootStrapper.RegisterInfrastureAdapters();
_isBootStrapped = true;
_isBootStrappedAuthenticated = true;
}
}
private void BootStrapUnauthentiated()
{
if (!_isBootStrapped)
{ // minimal bootstrap for launch but user not yet known, eg logon screen
BootStrapHttp(Context);
BootStrapper.RegisterInfrastureAdapters();
_isBootStrapped = true; // just a connection, if no persisted cookie, the may not be authenticated yet
}
}
}
Related
I am trying to store data in an old program / application on the API side, and while I am able to access the session, I can store data, but every sessions is new, so I do not have my data from "last" session.
The session is InProc.
The question is what could be wrong, since I get a new session every time. I can see that IsNewSession is always true and I get a new SessionId.
I searched a lot a put this together. I am new to sessions, so I cannot ask specifically.
The application is using nuget packages for AspNet.Mvc version 5.2.7
My code:
public class WebApiApplication : System.Web.HttpApplication
{
...
protected void Session_Start()
{
// I always get a new session here
Log.Information(Session.Keys.Count.ToString());
Log.Information(Session.SessionID);
Log.Information(Session.IsNewSession ? "Yes":no");
Session.Add("x", DateTime.Now.ToString());
}
protected void Session_End(object sender, EventArgs e)
{
// here I have session data
Log.Information("session end");
}
protected void Application_PostAuthorizeRequest()
{
if (IsWebApiRequest())
{
HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
}
}
private bool IsWebApiRequest()
{
return HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.StartsWith(WebApiConfig.UrlPrefixRelative);
}
And the web.config
public static class WebApiConfig
{
public static string UrlPrefix { get { return "api"; } }
public static string UrlPrefixRelative { get { return "~/api"; }
}
I have an API application in which I have this code:
public class MyModule : IHttpModule
{
public void Dispose() { }
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}
void context_BeginRequest(object sender, EventArgs e)
{
var myClaim = (string)new ClaimProvider().GetClaim(Thread.CurrentPrincipal, CustomClaimTypes.Culture);
}
}
And then in a controller:
public MyViewModel Get(int id)
{
return GetById(id, new ClaimProvider().GetClaim(Thread.CurrentPrincipal, CustomClaimTypes.Culture));
}
As you can see, in both places I call the method GetClaim() with the same parameters. In controller, it gives me a result. In the context_BeginRequest event, it returns null. Why does this happen? I need it not to be null in context_BeginRequest, because I want to set the current culture in one place and then use it in all the controllers.
I have implemented the Repository pattern in my WinForms Application:
UnitOfWork:
using RCCGSPP.Core;
using RCCGSPP.Persistence.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
namespace RCCGSPP.Persistence
{
//Implements the Logic for Methods in the IUnitOfWork Interface
public class UnitOfWork
{
//Our App contextClassName
private readonly SPPContext _context;
private DbContext dbContext;
//Recieves our App ContextClassName
public UnitOfWork(SPPContext context)
{
//stores our App ContextName in _context
_context = context;
//Then uses the context to initialise both Repositories
Persons = new PersonRepository(_context);
SundayServices = new SundayServiceRepository(_context);
UserPasses = new UserRepository(_context);
NewComers = new NewComerRepository(_context);
}
public UnitOfWork(DbContext dbContext)
{
this.dbContext = dbContext;
}
//properties
public PersonRepository Persons { get; private set; }
public SundayServiceRepository SundayServices { get; private set; }
public UserRepository UserPasses { get; private set; }
public NewComerRepository NewComers { get; private set; }
//Calls the SaveChanges on the Context
public int Complete()
{
return _context.SaveChanges();
}
//Implementation of the Dispose Method to Dispose the Context
public void Dispose()
{
_context.Dispose();
}
}
}
My Form whwere I want to use my UnitOfWork, I have declared it as a readonly property so I have included it in the contructor to initialise it but since by form is load from another at the click of a Button I get "There is no argument given that corresponds to the required formal parameter 'unitOfWork'"
Form Where To Use UNITOFWORK
public partial class Register : MaterialForm
{
private readonly IUnitOfWork _unitOfWork;
string userName;
string psswrd;
string Confirmpsswrd;
public Register(IUnitOfWork unitOfWork)
{
InitializeComponent();
//Set your preferred colors &theme (Material Skin)
var materialSkinManager = MaterialSkinManager.Instance;
materialSkinManager.AddFormToManage(this);
materialSkinManager.Theme = MaterialSkinManager.Themes.DARK;
materialSkinManager.ColorScheme = new ColorScheme(Primary.Blue400, Primary.Red900, Primary.Brown900, Accent.LightBlue200, TextShade.BLACK);
//prevent Form from Resizing
Sizable = false;
//UnitOfWork
_unitOfWork = unitOfWork;
}
private void Register_Load(object sender, EventArgs e)
{
}
private void btnSubmit_Click(object sender, EventArgs e)
{
//Get the User email and Password to register in the DB
userName = textEmail.Text;
psswrd = textPassword.Text;
Confirmpsswrd = textConfirmPassword.Text;
//Compare the password
bool conRes = ComparePassword(psswrd, Confirmpsswrd);
if (conRes)
{
//Insert to db using the UnitOfWork
UserPass userToDb = new UserPass
{
UserName = this.userName,
password = this.psswrd,
};
_unitOfWork.UserPasses.Add(userToDb);
//Commit calling complete()
_unitOfWork.Complete();
//FeedBack Registered Sucessfull
LabelErrorPassword.Text = "Successful, Login!";
}
else
{
LabelErrorPassword.BackColor = Color.Red;
LabelErrorPassword.Text = "The Passwords don't match!"; //show in the Label that password are not the same
}
}
/**********Method to compare Password**********************/
public bool ComparePassword(string pss1, string pss2)
{
if (pss1.Equals(pss2))
{
return true;
}
else return false;
}
}
lOADING MY fORM :
private void BtnRegister_Click(object sender, EventArgs e)
{
//lOAD THE rEGISTER fORM,
Register nForm = new Register();
nForm.Show();
}
How can I make use of my UnitOfWork in my WinForm Application.
As #stuartd said, the parameterless contructor for a Form in WinForms is recommended. But of course you can add a constructor with arguments.
public Register()
{
InitializeComponent();
//Set your preferred colors &theme (Material Skin)
var materialSkinManager = MaterialSkinManager.Instance;
materialSkinManager.AddFormToManage(this);
materialSkinManager.Theme = MaterialSkinManager.Themes.DARK;
materialSkinManager.ColorScheme = new ColorScheme(Primary.Blue400, Primary.Red900, Primary.Brown900, Accent.LightBlue200, TextShade.BLACK);
//prevent Form from Resizing
Sizable = false;
//UnitOfWork, not initialized here
//_unitOfWork = unitOfWork;
}
public Register(IUnitOfWork unitOfWork) : this() // call default constructor!
{
_unitOfWork = unitOfWork;
}
I strongly recommend to leave all the auto-generated and custom initialization code in the default (parameterless) constructor. So, the WinForms designer does not stop working.
We use this strategy in combination with DI containers in several projects without any problem.
Thank You all.
I have used the Simple Ijector package to Inject the UnitOfWork into my Program.cs as Follow:
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Bootstrap();
//Get instance of my Registered HomeForm
Application.Run((container.GetInstance<Home>()));
}
private static void Bootstrap()
{
// Create the container as usual.
container = new Container();
// Register my types, for instance:
container.Register<UnitOfWork, UnitOfWork>();
//Register my HomeForm
container.Register<Home>();
// Optionally verify the container.
//container.Verify();
}
}
Then in my Principal Form: I injected the registered UnitOfWork in it's constructor:
//Declare my UnitOfwORK
private readonly UnitOfWork _unitOfWork;
public Home(UnitOfWork unitOfWork)
{
InitializeComponent();
this._unitOfWork = unitOfWork;
}
Then I pass it to the New Register Form that will be loaded at the click of the Register Button, inside of which I will use the UnitOfWork to persist and commit to the DB
//lOAD THE rEGISTER fORM,
Register nForm = new Register(this._unitOfWork);
nForm.Show();
}
Finally in the Register I use this UnitOfWork to perform my CRUD Operations and Commit to the DB:
public partial class Register : MaterialForm
{
//Declare my UnitOfwORK
private readonly UnitOfWork _unitOfWork;
string userName;
string psswrd;
string Confirmpsswrd;
//I Inject IUnitOfOfClass with the Help of Simple Injector dependency injection library
public Register(UnitOfWork unitOfWork)
{
InitializeComponent();
//Set your preferred colors &theme (Material Skin)
var materialSkinManager = MaterialSkinManager.Instance;
materialSkinManager.AddFormToManage(this);
materialSkinManager.Theme = MaterialSkinManager.Themes.DARK;
materialSkinManager.ColorScheme = new ColorScheme(Primary.Blue400, Primary.Red900, Primary.Brown900, Accent.LightBlue200, TextShade.BLACK);
//prevent Form from Resizing
Sizable = false;
_unitOfWork = unitOfWork;
}
private void SetUnitOfWork()
{
}
private void Register_Load(object sender, EventArgs e)
{
}
private void btnSubmit_Click(object sender, EventArgs e)
{
//Get the User email and Password to register in the DB
userName = textEmail.Text;
psswrd = textPassword.Text;
Confirmpsswrd = textConfirmPassword.Text;
//Compare the password
bool conRes = ComparePassword(psswrd, Confirmpsswrd);
if (conRes)
{
//Insert to db using the UnitOfWork
UserPass userToDb = new UserPass
{
UserName = this.userName,
password = this.psswrd,
LastAcess = DateTime.Now
};
_unitOfWork.UserPasses.Add(userToDb);
//Commit calling complete()
_unitOfWork.Complete();
//FeedBack Registered Sucessfull
LabelErrorPassword.Text = "Successful, Login!";
}
else
{
LabelErrorPassword.BackColor = Color.Red;
LabelErrorPassword.Text = "The Passwords don't match!"; //show in the Label that password are not the same
}
}
/**********Method to compare Password**********************/
public bool ComparePassword(string pss1, string pss2)
{
if (pss1.Equals(pss2))
{
return true;
}
else return false;
}
}
It might not be the best way to implement it but It works absolutely fine, I have tested it and I could see the data in the database.
Is the setter injection supported in the Xamarin.forms?
I have a service injected in the bootstrapper like this
Container.RegisterType<ICommonService, CommonService>();
And inside a viewmodel, I want to have an instance injected to a property like this
[Dependency]
public ICommonService CommonService { get; set; }
But in the runtime, the property CommonService is always null.
The attribute I used is the Microsoft.Practices.Unity.DependencyAttribute, not Xamarin.Forms.DependencyAttribute
If I inject inside the constructor, it works
public LandingPageViewModel(INavigationService navigationService, ICommonService commonService)
Edited: added code snippet
public class Bootstrapper : UnityBootstrapper
{
protected override Page CreateMainPage()
{
try
{
return Container.Resolve<Views.LandingPage>();
}
catch (Exception exception)
{
//TODO: intent to get exception info
throw;
}
}
protected override void RegisterTypes()
{
DependencyResolver.Instance.Initialize(Container);
this.RegisterViews();
this.RegisterServices();
this.RegisterSingleton();
}
private void RegisterViews()
{
Container.RegisterTypeForNavigation<LandingPage>();
Container.RegisterTypeForNavigation<Page1>();
}
private void RegisterServices()
{
Container.RegisterType<ICommonService, CommonService>();
}
private void RegisterSingleton()
{
}
}
public partial class App : Application
{
public App()
{
InitializeComponent();
var bootstrapper = new Bootstrapper();
bootstrapper.Run(this);
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
Hmm they removed the DependencyAttribute injection feature since Prism 7.0, I think we should register it manually. (your code snippet should work)
Look: https://brianlagunas.com/whats-new-in-prism-for-xamarin-forms-7-0/
Throughout my web app I am using a UnitOfWork class to handle all my interactions with the data source. Below is the interface it inherits.
public interface IUnitOfWork : IDisposable
{
ActivityService ActivityService { get; }
AmendmentService AmendmentService { get; }
AspUserService AspUserService { get; }
AttachmentService AttachmentService { get; }
CampaignService CampaignService { get; }
CommentService CommentService { get; }
EventRegistrationService EventRegistrationService { get; }
GroupService GroupService { get; }
InstanceService InstanceService { get; }
void Commit();
}
It inherits Idisposable so i dispose the entity context during the UnitOfWorks Dispose method. However when using this class in my web pages i am never sure whether i should create one UnitOfWork class as a variable of the page like so.
public partial class Members_Request : BasePage
{
UnitOfWork uow = new UnitOfWork();
protected void Page_Load(object sender, EventArgs e)
{
Instance instance = uow.InstanceService.GetById(base.instanceId)
}
protected void Page_PreRender(object sender, EventArgs e)
{
//I don't think disposing here will work in all scenarios
uow.Dispose();
}
private void SomeOtherMethod(string name)
{
Group newGroup = new Group{Name = name}
uow.GroupService.Add(group))
uow.Commit();
}
}
Doing it this way i need to be careful when i dispose for example, if i need the UnitOfWork in the Page_PreRender method but it never gets called becuase the request was a Callback, then my context will never get disposed. I am not sure if i should be disposing it during every method i use it then simply reinitialize it as a new UnitOfWork when i need it again to ensure it is always disposed.
An alternative way which ensures it gets dispose is to create a new UnitOfWork for every method i need it in so the above exmaple would become
public partial class Members_Request : BasePage
{
protected void Page_Load(object sender, EventArgs e)
{
UnitOfWork uow = new UnitOfWork();
Instance instance = uow.InstanceService.GetById(base.instanceId)
uow.Dispose();
}
private void SomeOtherMethod(string name)
{
UnitOfWork uow = new UnitOfWork();
Group newGroup = new Group{Name = name}
uow.GroupService.Add(group))
uow.Commit();
uow.Dispose();
}
}
So my question is how can i ensure that my UnitOfWork is always disposed when i share the same one each request, or should i just be creating many UnitOfWork objects whenever i need them and disposing them straight away. I think a solution by sharing the UnitOfWork would be better as it reducing code bloat.
Edit -- One alternative way i am thinking of doing this is to have this code in my base page
protected UnitOfWork uow = new UnitOfWork();
protected override void OnUnload(EventArgs e)
{
uow.Dispose();
base.OnUnload(e);
}
Then i think i can just use the same instance of uow throughout the lifecycle and know it will always be disposed.
I use this: override dispose in every page
public override void Dispose()
{
if(uow != null)
{
uow.Dispose();
}
base.Dispose();
}
uow is my UnitOfWork