I am evaluating CSLA.NET for an MVC project that I am working on. We would like to us MVC 4 but we are running into some issues with the Csla.ApplicationContext.User.IsInRole method and custom principals and identities. I have been working on a solution using the CSLA.NET 4.5.11 beta, but we have experienced the issues with the 4.5.1 release as well. Here is a link to solution that demostrates the issue.
Here is what we have been observing.
1. After a user successfully logs into the system, the CustomPrincipal object is loaded into the Csla.ApplicationContext.User property. This occurs in the Application_AuthenticateRequest as seen in the code examples I have found.
2. Immediately after loading the principal, the Csla.ApplicationContext.User.IsInRole method works as expected within the context of the global.asax.cs.
3. The Csla.ApplicationContext.User.IsInRole method does not work as expected when you are in a Controller. IsInRole appears to always return false.
I examined the Csla.ApplicationContext.User property. Based upon the GetType() call it is the CustomPrincipal class I have defined.
I'm stuck and would appreciate any help that is offered.
I'm on my phone, so I can't look at the sample, but are you referencing csla.web as well acsla.dll
In the MVC4 project, I am referencing Csla, Csla.Web, Csla.Web.Mvc4 and Csla.XmlSerializers
In terms of helping you debug the issue, I want to point out that Csla.ApplicationContext.User is just a wrapper over existing .NET principal concepts.
In the case of ASP.NET what you are actually getting is the User property of the current HttpContext. So from a debugging perspective you might want to step through the code and confirm that HttpContext.Current.User gets set properly, and that it doesn't change over time (though it obviously IS changing). That might help you figure out what code is changing the HttpContext.Current.User value.
I took a closer look today. I could not see the HttpContext.User being set anywhere else. I added my included references to the csla source code to facilitate deeper debugging.
Here are some of my observations:
That's what I have so far.
Thanks for the help!
I haven't been able to find anything else. I wonder if there is something with the built-in Internet App MVC 4 template that is causing the issue.
Whuch template did you use for your MVC project?
ASP.NET MVC 4 offers six Project Templates:
If you used Intranet it would certainly change the Principal object.
I used the Internet template.
Ahh, yes, you are right, we hadn't split that functionality out yet at that point in time.
Obviously MVC 4 didn't exist back then, so it is possible that there is some difference in behavior that is causing issues.
I don't know if this applies to Tom as well but my problem turned out to have nothing to do with CSLA. I was setting Csla.ApplicationContext.User (which is really HttpContext.User for me) in the Application_AuthenticateRequest event handler. I have moved the code to the Application_PostAuthenticateRequest event handler and now it works fine.
I have a very large ASP.NET website that I converted to an ASP.NET MVC 4 Web Application. What I did to solve this problem was to set <roleManager enabled="false"> in <system.web>. If you don't then your custom Principal will be replace with a RolePrincipal.
I, too, am encountering this behavior. I always use Csla.ApplicationContext.User (not HttpContext). In Global.asax, it gets set and can be retrieved just fine. As soon as I try to access Csla.ApplicationContext.User from a controller, however, Csla.ApplicationContext.User contains a generic System.Web.Security.RolePrincipal instead of my custom IPrincipal object. The System.Web.Security.RolePrincipal object does have its values filled-in but of course I cannot access my custom IsInRole or any other custom methods/properties.
I am using CSLA 220.127.116.11, IIS (not Cassini), MVC 4 and .NET 4.0. Does that info help anyone figure out what's going here?
Can you confirm that Csla.Web.dll is in your bin folder?
I do not have the csla.web.dll in my bin folder, which I'm assuming now is the problem. I didn't know that there existed a separate dll. I looked in my CSLA project from which I built the csla.dll assembly (a loooooooong time ago. I wasn't using the Csla.ApplicationContext before) and there is no project to build anything other than the csla.dll. So, assuming that this is the problem, here's what I've tried:
1. Build the 3.8.3 version of csla.web.dll - couldn't find a project to do that.
2. Install from NuGet the latest version of csla (4.5-ish) - too many changes since 3.8.3 which would require me to refactor a bunch of stuff.
3. Build the 3.8.4 version of csla.web.dll (which I'm assuming is the end-of-the line for non-breaking changes for the version I'm using) - downloaded and tried but hit a bunch of errors about classes that existed in multiple namespaces. Noticed that there are references to .NET 3.5 and 4.0.
What is my least painful option? Am I missing some files from the 3.8.3 version?
The simplest thing is probably to download the 3.8.3 code from the old download page
Because you obviously don't have the full set of code and projects at the moment.
I got the 3.8.3 from the old download page. I still cannot find a project to build Csla.Web.dll. There is a project to build Csla.Web.Mvc.dll but I'm not using any CSLA MVC stuff. Am I missing something?
Although I can't absolutely verify it, I'm thinking that Csla.Web.dll did not exist before version 4.0. I'm using the 2008 book (version 3.6) and there's no mention of it. Was it created in 4.0 to solve a problem in the 3.x line?
Copyright (c) Marimer LLC