First of all welcome to one of thousands of posts with this error. If this is not your very first hit, you might already be frustrated. In this case I hope this post will help you at least a bit.
So, you are probably reading this, because you have got this error:
Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.
I get this error these days (years) only when working with SharePoint and some kind of service like WCF or even service implemented in ASH-handler.
As you expect, this error description should describe, what happened? You are right. It means the Debugger is unable to read anything as the message “says”. This message unfortunately does not contain any meaningful information. If you are developer of one API and want to make crazy anybody who calls into your API do following:
System.Threading.Thread.CurrentThread.Abort();
This is what SharePoint does implicitly somewhere deep in the COM world in the library C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\OWSSVR.DLL.
When the tread is dead, it means that you cannot read anything else on the stack as shown in the following picture.
This picture shows what happens when you step over (F10) line 2. If you set breakpoint on line 1 and press F5 no Thread Abort will be called. Instead, the line 5 will not be executed because web.CurrentUser is not set. Exactly this fact (CurrentUser = null) causes the SharePoint to crash!
1. using (SPWeb web = initializeSite.OpenWeb())
2. {
3. if (web.CurrentUser != null)
4. {
5. . . .
6. }
7. }
ASP.NET Impersonation
So to fix this, you need to setup Windows Authentication and Impersonation in your web.config file
<authentication mode="Windows" />
<identity impersonate="true"/>
WCF Impersonation
If you are working wit WCF Web Services then additionally following has to be set, but previous two line not necessarily:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
Additionally the WCF service has to be styled as follows:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class MyService : IMyService
Additionally WCF impersonation can be done imperatively too as shown here.
Anonymous Impersonation
However most interesting question is how to do impersonation, which is required by MOSS, if the current user is anonymous user?
Anonymous authentication in IIS 7.0 and 7.5 is enabled as follows:
In IIS 6 this looks like:
To make this working you have to understand that that COM model behind SharePoint at some point of time does this:
if(HttpContext.User.Identity.IsAuthenticated). . .
If the User Property is not set or Identity is not set or it is set but not authenticated, nothing will work. To illustrate how to fix this I used a service implemented in ASHX handler.
[WebService(Namespace = http://daenet.eu/DeepZoomExplorer)] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class DeepZoomHandler : IHttpHandler { private IRequestParser m_RequestParser = new HttpArgumentParser(); public void ProcessRequest(HttpContext context) { WindowsPrincipal wP = new WindowsPrincipal(System.Security.Principal.WindowsIdentity.GetCurrent()); HttpContext.Current.User = Thread.CurrentPrincipal = wP; } } |
The code shown above can be used in and ASPX page too. Note that SharePoint does not rely on Thread.CurrentPrincipal. Because of this setting of CurrentPrincipal is even not necessary. You could just use HttpContext.Current.User = wP.
I set CurrentPrincipal, because it should be used, I think. That is how .NET Framework works and should work. So, the best is set both and you will be sure that any security provider in MOSS tomorrow will work with this, we hope at least.
Damir
Posted
Mar 25 2010, 11:56 AM
by
Damir Dobric