EDIT
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 SPWebs
/SPSites
respectively.
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
(like SPContext.Current.Web
) uses the current user's security context tied to it making a tighter security around your code.
But 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 SPWeb
or 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 SPWeb
/ SPSite
objects --> memory leaks
• Make use of SPContext.Current
... when you are sure your code is running in a
SharePoint context
• 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
SP.. objects.
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
have your SPSite
and not something SharePoint created and managed for
you.
Personally I almost always go for the using
structure so all objects
are disposed properly afterwards. When I do quick and dirty solutions
I use SPContext.Current.Web
without disposing.
https://stackoverflow.com/questions/8052190/spsite-site-new-spsitespcontext-current-web-url-vs-spcontext-current-web-sit
Also as I've said:
What is the need of defining SPSite
, SPWeb
objects especially in
RunWithElevatedPrivileges
block? If you use instances of SPSite
or
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
inside
RunWithElevatedPrivileges
: SPContext.Current.Web
can not be used
directly with in the RunWithElevatedPrivileges
block as the SPWeb
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 SPSite
and SPWeb
should be
created within theRunWithElevatedPrivileges
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.
http://sharepointquicksolutions.blogspot.in/2012/11/all-ways-of-runwithelevatedprivileges.html
So you can see the picture here! That there are less privileges to the CurrentContext
that's using the same thread eg SPContext.Current.Web
whereas 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 SPWeb
object.