Just like to clear this answer!
I've read your question and the answer has to do with the security context that has been put in place for a reason.
When using the
SPContext.Current.Web or any context appart from
.OpenWeb() it is already using the current users security context(read, write,full permissions). Open web is creating a new
SPWeb object as I've already stated!
Because it's running under the current user's security context, say I have an account that has read only access its regardless weather I've done runwithelevated priv it wouldn't work because the security is already set, unless as you noted you use usertoken! That being said the code is trying to update or add an item to a list or library but fails as the security context under the current user wouldn't allow to give me the permission to run under pool account or even admin account.
Having the open web is run under a new thread that needs to be disposed of as I've noted first time round as its creating a new object, anything with the "new" object needs to be disposed and can be elevated so doesn't have any security restrictions (security). this can also be interchangeable between
This is not the case with
SPContext.Current.Web , the only exception is when using the
SPUser object where it would run into a known bug and running with elevated priv would do nothing, you would need to create a new
SPUser and add
SPWeb.EnsureUser(user.LoginName); within the elevated security context for it to work.
So rule of thumb
SPContext.Current.Web) uses the current user's security context tied to it making a tighter security around your code.
SPContext.Current.Site.OpenWeb() creates a new
SPWeb object that doesn't have any security context tied to it, leaving you to change security context or elevate privs without restrictions!
Both open the same
SPSite, the only difference is the security context tied to the current context of the user that you should not dispose of!
Just as a note:
There are a few key takeaways for SharePoint projects:
• Always dispose your
SPSite objects --> memory leaks
• Make use of
SPContext.Current... when you are sure your code is running in a
• Unit Tests mean no Sharepoint context
• External utilities mean no Sharepoint context
• Powershell means no SharePoint context (e.g. activating a feature with feature receiver might fail)
•Do not dispose SPContext.Current... but create your own object (again
using) You might have problems with consistency with your multiple
In the end
SPSite site = SPContext.Current.Web.Site; is fine in some
instances, but you do not have control over this site object - that
might be the problem. If you go for
new SPSite(...) you will always
SPSite and not something SharePoint created and managed for
Personally I almost always go for the
using structure so all objects
are disposed properly afterwards. When I do quick and dirty solutions
SPContext.Current.Web without disposing.
Also as I've said:
What is the need of defining
SPWeb objects especially in
RunWithElevatedPrivileges block? If you use instances of
SPWeb, obtained prior to the
RunWithElevatedPrivileges block, it won't
work as expected because they are already associated to a non-elevated
security context [meaning current logger user]
Why can’t we use
SPContext.Current.Web can not be used
directly with in the
RunWithElevatedPrivileges block as the
object becomes a instance of current logged-in user's context and it
gives the below error if tries to update any content in the same Web
with READ only access. Error : Unable to evaluate expression because
the code is optimized or a native frame is on top of the call stack.
To address the issue, a new instance of
SPWeb should be
created within the
RunWithElevatedPrivileges code block as above.
in this case
SPContext.Current.Site.OpenWeb() creates a new thread
from the current context and is like creating a new spweb, this means
more control but also means you need to dispose of the object.
So you can see the picture here! That there are less privileges to the
CurrentContext that's using the same thread eg
SPContext.Current.Site.OpenWeb() is a new thread that doesn't have the restrictions in place due to the first one already being set and used whereas the second one is created by you and can be changed (security wise) means no restrictions on actions but also means you need to handle the disposing of the