JsonResult has closed ISession, yet NHibernateSession.Current is open?!

Mar 23, 2010 at 5:26 PM
Edited Mar 23, 2010 at 5:47 PM

I have a controller method that returns a JsonResult. A method call to Rhino.Security.AuthorizationRepository.GetUsersGroupByName always fails saying that my session is closed inside the rhino method. Funny, going into and coming out of that same method -- NHibernateSession.Current -- says the session is open in my Task class' method:

 

        public UsersGroup GetUsersGroup(string name)
        {
            Check.Require(!string.IsNullOrEmpty(name), "name cannot be null or empty");
// NHibernateSession.Current.IsOpen() is true here.
            return _authorizationRepository.GetUsersGroupByName(name); //ERROR Session is closed!
// NHibernateSession.Current.IsOpen() is true here.
        }

 

Here's Rhino's code here including the constructor:

		public AuthorizationRepository(ISession session)
		{
		    this.session = session;
		}
///...
		public virtual UsersGroup GetUsersGroupByName(string groupName)
		{
			return session.CreateCriteria<UsersGroup>()
                .Add(Restrictions.Eq("Name", groupName))
                .SetCacheable(true)
                .UniqueResult<UsersGroup>();
		}

 

I have a registrar that wires up ISession to SharpArch.Data.NHibernateSession.Current all in the same registrar:

container.AddFacility<FactorySupportFacility>()
.Register(Component.For<ISession>()
.UsingFactoryMethod(() => NHibernateSession.Current)
.LifeStyle.Is(LifestyleType.Transient));

Even if I don't close the session in Application_EndRequest. My call to GetUsersByGroupName fails with a closed session -- it has to be Windsor that doesn't like NHibernateSession.Current.

Any ideas?

Developer
Mar 24, 2010 at 10:26 AM
You're doing a whole bunch of stuff I'm unfamiliar with here so it's not obvious to me what the problem is. If you'd like to post the code that causes the issue I'm happy to have a look at what you're doing and see if I can help.

Cheers
Jon

On 23 March 2010 17:26, kujotx <notifications@codeplex.com> wrote:

From: kujotx

I have a controller method that returns a JsonResult. A method call to Rhino.Security.AuthorizationRepository.GetUsersGroupByName always fails saying that my session is closed inside the rhino method. Funny because going into and coming out of that same method -- NHibernateSession.Current says it is open.

I have wired up Rhino. I have a registrar that wires up ISession to SharpArch.Data.NHibernateSession.Current:

container.AddFacility<FactorySupportFacility>()
.Register(Component.For<ISession>()
.UsingFactoryMethod(() => NHibernateSession.Current)
.LifeStyle.Is(LifestyleType.Transient));

Even if I don't close the session in Application_EndRequest. My call to GetUsersByGroupName fails with a closed session -- it has to be Windsor that doesn't like NHibernateSession.Current.

 

Any ideas?

Read the full discussion online.

To add a post to this discussion, reply to this email (whocanhelpme@discussions.codeplex.com)

To start a new discussion for this project, email whocanhelpme@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com


Mar 24, 2010 at 5:45 PM

Jon,

Thanks... What parts would tell you the most? Controller, tasks, etc.

I thought I gave you enough. It really happens in the task method. Before I call the method that throws, I can confirm my ISession is open. During the method, it has a session from a ctor injected ISession that should have been created by Windsor from a facility method. But that session is closed. If I skip out of that method, I can confirm again that NHibernateSession.Current.IsOpen() is still true.

So inside my Tasks layer, I have a session. Going into Rhino, I have no open session. I am tempted to roll Castle in and step through the creation of my ISession to learn up some Windsor. I was just hoping that my error was obvious from above.

Let me know if I can post more code -- like what layer might reveal more for you.

Thanks again.

Mar 30, 2010 at 2:36 PM

This is what you need to do:

- create a class implementing IPersistenceConfigurer

public class RhinoSecurityPersistenceConfigurer: IPersistenceConfigurer
    {
      
        public Configuration ConfigureProperties(Configuration nhibernateConfig)
        {
            Security.Configure<User>(nhibernateConfig, SecurityTableStructure.Schema);

            return nhibernateConfig;
        }
    }

- modify InitializeNHibernateSessions:

private void InitializeNHibernateSessions()
        {
            NHibernateSession.Init(
                webSessionStorage,
                new[] { Server.MapPath("~/bin/YOURProject.Data.dll") },
                new AutoPersistenceModelGenerator().Generate(),
                Server.MapPath("~/Configuration/NHibernate/{0}.config").FormatWith(SessionKeys.Data)
                ,null, null, new RhinoSecurityPersistenceConfigurer()
                );
        }

If it works for you, credit should go to David Archer: http://groups.google.com/group/sharp-architecture/browse_thread/thread/4093c52596f54d23/194f19cd08c8fdd7

Best, Jun

 

Mar 31, 2010 at 1:47 PM

Thanks for reading!

I  am well past applying the RhinoSecurityPersistenceConfigurer to my NHibernate Configuration. I already have read (thoroughly) through the David Archer posts and have even already migrated my registrations into IComponentRegistrars for auto-wire up by MEF. We're all good there.

Outside of the JsonResult, I can easily query my IUser derived User class on a list view, edit it, etc. I am confident that Rhino is configured. Rhino gets a valid and open ISession resolved in my current method using any method that returns a ViewResult.

My problem is specific to a JsonResult invoked from jQuery in a tree control. The call comes back just fine from my client. Calls my JsonResult method above. The Session is readily available and open before and after the call to RhinoSecurity.

For whatever reason, MEF/Windsor does not seem to pass ISession over to Rhino. That same factory method is just fine in any other ActionResult.

My question is why doesn't Rhino.Security resolve ISession correctly with an open session. It's not even null. It's just closed.

I am wondering if Rhino.Security cannot get an ISession resolved by Sharp's NHibernateSession.Current method in a JsonResult. I don't what alternative I have.

I have experimented with the static file method inside the Application_BeginReqest and commenting that out to force a session on each request. No dice. This is not pressing, I am moving on... but it should get resolved eventually.

Mar 31, 2010 at 1:48 PM

For whatever reason, I can't upload over ssh to github inside my corporate firewall. Do you know of an alternative where I can share my source?

 

Mar 31, 2010 at 3:36 PM

I was able to replicate your problem: the same RhinoSecurity API worked in ActionResult but not JsonResult/JsonNetResult.

What if you create a viewmodel embodying a Json data object, still use an ActionResult, and then deserialize the viewModel in your view? JsonNewTon.Net should be helpful. This way you get around with the JsonResult object and do the work yourself. Just an idea.

Mar 31, 2010 at 3:47 PM

Awesome. I was hoping I didn't mess up the config.

So I will change my JsonResult to ActionResult. I will try that today.

I am already using custom json tree classes that I had to create for my tree are essentially viewmodels,

Your looking into this is greatly appreciated.

Trying to grok github problems with my corp network. I want to upload my code before it gets to be too project specific.

Mar 31, 2010 at 4:16 PM

Let me know how that works for you.

Looks like that we are doing similar work. I am working on a large project using S#arp/wchm framework, Rhino.Security. Right now, I am in the middle of building the administrative UI for managing privileges (authorization). It will be interesting to see what you have. Email me if you have any thoughts or problems.

Cheers, Jun

 

Mar 31, 2010 at 5:11 PM

Absolutely. Collaboration works! I hope I can figure out github because that would be a great place to store the source. If not there, I will try googlecode.

My project requires that users be able to browse themselves and anyone who works under them hierarchically. I am trying to leverage the Entitiesgroups in Rhino.Security to make users browseable as members of their managers group, or their company or division.

You appear to be further along.

I will keep you posted on my findings.

From: brownbear [mailto:notifications@codeplex.com]
Sent: Wednesday, March 31, 2010 11:17 AM
To: Johnson, Kurt A. (Commercial Card)
Subject: Re: JsonResult has closed ISession, yet NHibernateSession.Current is open?! [whocanhelpme:207043]

From: brownbear

Let me know how that works for you.

Looks like that we are doing similar work. I am working on a large project using S#arp/wchm framework, Rhino.Security. Right now, I am in the middle of building the administrative UI for managing privileges (authorization). It will be interesting to see what you have. Email me if you have any thoughts or problems.

Cheers, Jun

Read the full discussion online.

To add a post to this discussion, reply to this email (whocanhelpme@discussions.codeplex.com)

To start a new discussion for this project, email whocanhelpme@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on CodePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at CodePlex.com

Mar 31, 2010 at 10:06 PM

I am interested to see if you add a generic repository, such as IRepository in S#arp, to use the AddPermissionsToQuery function in RS. The function takes an ICriteria/DetachedCriteria parameter, but the IRepository in S#arp does not. I am thinking of building a generic repository, which will have similar methods in that in IRepository except that most of them will take a SecuritySetting parameter. The SecuritySetting class will have three properties: User, UserGroup, Operation, so a GetAll method will look like this:

public IList<T>GetAll(SecuritySetting setting)

{

            ICriteria criteria = Session.CreateCriteria(typeof(T));

            authorizationService.AddPermissionsToQuery(setting.usersgroup, setting.Operation, criteria);
            return criteria.List<T>();

}

Let me know if you have any comments.

Coordinator
Apr 1, 2010 at 12:30 PM

I could create a new branch on codeplex for the rhino security bits. If you still have something generic that works you can email me at howardvanrooijen [at] g m a i l . c o m 

I too would be very interested to see it integrated into WCHM / #Arch

 

/howard

Apr 1, 2010 at 2:31 PM

Hi Howard,

I'll email you the Rhino.Security implementation once it is done.

Thanks, Jun

Apr 5, 2010 at 6:01 PM

Now, I am seeing ISession not work for non-Ajax related calls. What is going on with my ISession lifestyle? When I call AuthenticationRepository a second time, it tells me that the ISession is closed.

I also used the Factory method for registering ISession to register a method for determining the current principal -- I call it ISecurityContext. That part does not work either. I want to blame lifestyle. The ISecurityContext appears to retain the last, despite the Lifestyle being set to PerWebRequest.

Howard has this code, so perhaps my error will be glaring enough that it will stand out.

 

Kurt

Coordinator
Apr 5, 2010 at 8:15 PM

Will try and take a look at the code tomorrow - hopefully shouldn't be too difficult to get up and running with.

 

h

Apr 7, 2010 at 3:21 PM

OK... I have resolved my original issue. It ended up being lifestyle.

Stepping through the code, I would eventually hit the pdb code for AuthorizationRepository. Inside the constructor overloaded with ISession, you can put a breakpoint to see the session come in and check its state. I would notice that this breakpoint would only hit every once in a while.

I have an index method on a controller that lists a bunch of users. Each user would require a hit to AuthorizationRepository. Each iteration successfully registered a hit of that breakpoint.

The problem arose when I would drill into a single user record. The AuthorizationRepository constructor never hit -- the breakpoint on the constructor was consistently bypassed. The method I was calling would always get a session object from ServiceLocator with an IsOpen() that returned false. This was my issue.

I reasoned that there was a lifestyle mismatch between the AuthorizationRepository in Rhino that is constructor injected into my Tasks object, and the ISession that is constructor injected into AuthorizationRepository. As soon as I changed the Register code for the Rhino components to include a Transient lifestyle, code that once failed is now working.

Additionally, I marked my tasks as they are registered with a Transient lifestyle. I noticed that one of my calls to my tasks-dependent objects failed to obtain a registered object with the proper state.

If you inject interfaces using constructors, it seems as though your components will not resolve properly if they too have constructor-injected dependencies. Is there a reason why all registered components in Sharp rely on Singleton lifestyles? I might have to pose that over there.

The code is here:

        public void Register(IWindsorContainer container)
        {
            container.Register(
                    AllTypes.Pick()
                        .FromAssembly(Assembly.GetAssembly(typeof(TasksRegistrarMarker)))
                        .Configure(c => c.LifeStyle.Transient)
                        .WithService.FirstNonGenericCoreInterface("My.Core.Contracts.Tasks"));
        }

Apr 7, 2010 at 7:19 PM

Sure enough. I have more confirmations that this lifestyle fix works. I just found another interface that consumes ISession. It was not set with the correct lifestyle, and it failed -- ISession is closed!

I have been going through all of my registrars and replacing those component lifestyles with Transients.

May 19, 2010 at 2:42 PM
Hi there, can you post your Rhino.Security implementation, or create a branch of WCHM / #Arch with RS integrated? Any help would be greatly appreciated.
May 21, 2010 at 1:59 PM

Anyone?

May 21, 2010 at 2:17 PM

I sent Howard some code a while back. I didn't use WCHM, but a SharpArch project that I refactored to the WCHM style. The team might be working on incorporating Rhino.Security presently.

I will take a stab at a straight-up WCHM branch this weekend. I am going to include my FormsAuthentication adapter, since I have seen some other folks who want so to leverage the Rhino User for authentication.

May 21, 2010 at 2:32 PM

i'd like to see wchm with Rhino Security too.

Coordinator
May 23, 2010 at 9:10 PM

Hello,

Sorry we've been a little quiet - we've been migrating the codebase to GitHub so that users can fork and alter the codebase - so that you can create and share branches that include other OSS frameworks like Rhino.Security. If you are interested the master is located at http://github.com/jongeorge1/Who-Can-Help-Me

We'd all be very interested to see a Rhino.Security implementation.

regards,

Howard

May 25, 2010 at 2:27 AM

Hi Howard,

Great news on the Github migration :)

I've also been out of the loop, but hope to return to web stack work shortly!

May 25, 2010 at 4:23 PM

I checked out the VS2010 branch last night. I noticed that PostSharp wasn't in there -- is that because of the licensing?

The only git I knew how to do was clone a remote repo. Once I did a checkout of the VS2010 branch and saw my VS2008 SLN instantenously switch over to a VS2010 solution, I was hooked. No wonder the git folks sacrificed performance on adds for performance everywhere else; what a small price to pay for this type of branching.

I will spend more time tonight incorporating files and pruning my domain-specific items.

Coordinator
May 25, 2010 at 5:26 PM

AFAIK - Jon has put PostSharp 2.0 CTP 5 Community Edition (what a mouthful) back into one of the branches - I think it requires you to install the framework as we haven't worked out how to integrate it back in the way we did with PS 1.0.

If you're using GitHub - you should be able to clone / fork the repo - then send pull requests back to jon (if you want to keep his repo as the master).

Looking forward to seeing your commits.

Howard

May 25, 2010 at 5:32 PM

No prob. I ended up getting the Community Edition and putting PS2.0 in there.

I was able to clone and fork locally with no problems. I am working in the VS2010 branch, presently.

I will likely have a question later on how best to incorporate IUser into WCHM.

Kurt