Pages

Thursday, 6 February 2014

No more post back after file download in sharepoint


I had this issue with sharepoint. I have a button on the page that sends a file and after clicking the button, the rest of the form was unresponsive. Turns out it is a sharepoint thing that sets the variable _spFormOnSubmitCalled to true to prevent any further submits. When we send a file this doesn't refresh the page so we need to manually set this variable back to false.
On your button in the webpart set the OnClientClick to a function in your javascript for the page.

 <asp:Button ID="generateExcel" runat="server" Text="Export Excel" 
OnClick="generateExcel_Click" CssClass="rptSubmitButton"
OnClientClick="javascript:setFormSubmitToFalse()" />
 
Then in the javascript I have this function.
 
function setFormSubmitToFalse() {
    setTimeout(function () { _spFormOnSubmitCalled = false; }, 3000);
    return true;
}
 
The 3 second pause I found was necessary because otherwise I was setting the variable before sharepoint set it. This way I let sharepoint set it normally then I set it back to false right after.

in C#

SharePoint registers a JavaScript "on submit" handler. In this handler the global variable _spFormOnSubmitCalled is set to true. SharePoint uses this variable to check if a submit was executed and prevents any further submits. Since your "download postback" does not refresh the page this variable remains true. With the effect that that all other buttons stop working.
As a workaround you can set this variable to false in a client click handler on your download button:

Button btn = new Button();
btn.Text = "Download";
btn.Click += DownloadButton_Click;

// set the client click handler
btn.OnClientClick = "window.setTimeout(function() { _spFormOnSubmitCalled = false; }, 10);"

Thursday, 30 January 2014

Tool Part for Visual Web Part – SharePoint 2010

Tool Part for Visual Web Part – SharePoint 2010

Hi SharePoint Friends, 
I would like to discuss some cool stuffs for developing custom “Tool Parts” for SharePoint 2010 Visual web part.
“Tool Part” is nothing but the set of controls that are required for your web part which works based on the tool part properties. It will be available as a new section in the web part properties area.
There are two ways for developing a Visual Web part with custom tool part
1. Designing the entire tool part using the server side code.
2. Designing the tool part using user controls
In this part, I will drive you thru Option 1. R u ready, lets get started.
Step 1:
Create a “Empty Project” using Visual Studio 2010 and name it as “CustomToolpartOtion1” and choose the deployment type as a “Farm Solution”. You should see a similar project structure in VS 2010.
ProjectStructure
Step 2:
Open “VisualWebpartwithTP1.cs” file and write the below mentioned code.
propertydeclaration
The above mentioned code is to declare a property which has to be rendered in the web part properties window.
  • Category – To display under which category or section the property should be displayed. If there are multiple  properties then the category must be same and obviously it depends on your requirement.
  • Personalizable – To make the information available common across all the users accessing the site.
  • WebDisplayName – its nothing but the caption for the property defined.
  • WebDescription – It’s a detailed description about the property.
Step 3:
Open “VisualWebpartwithTP1UserControl.ascx.cs” and declare a property with the class name of the above mentioned “VisualWebpartwithTP1.cs” file. The declaration is to access the properties in the user control server side code.
webpartclasspropertydeclaration
Step 4:
Open “VisualWebpartwithTP1.cs” file and write the below mentioned code in the “CreateChildControls” method.
createchildcontrol_method
Basically we are declaring loading the user control with its type and assigning the declared property to “this” which means using the declared property, we will be able to access the custom tool part properties. Finally we are adding the controls to the page.
Step 5:
Open “VisualWebpartwithTP1UserControl.ascx” and add one label control just like the below mentioned.
LabelDeclaration
Step 6:
Now on the code behind file “VisualWebpartwithTP1UserControl.ascx.cs” assign the web part property to the above added “Label’s text property” on the “Page_Load” function.
Pageload_method
Step 7:
That’s it we are done with the coding. Rebuild the project and deploy it. After deploying add the web part to the page and edit the web part, now you will be able to see the custom properties. Enter any value in the textbox and click ok and then save the page to see the label which displays the value that you have entered in the web part properties and you can try to edit the values too.
Finalresult
Finalresult1

Tuesday, 28 January 2014

InfoPath cannot save the following form... This libary was either renamed or deleted, or network problems are preventing the file from being saved.



InfoPath cannot save the following form: Form Name. This Document Library was either renamed or deleted, or network problems are preventing the file from being saved. Contact your network administrator.


    This issue occurs because the Desktop Experience feature is not enabled on the Windows Server 2008 R2 server. Therefore, connections cannot be made from the Windows Server 2008 R2 server to the SharePoint server.

To work around this issue, install the Desktop Experience feature, and restart the Windows Server 2008 R2 server. Then, start the Themes service from the Windows Services console.

As desktop Experience feature is being relocated to be under User interface and infrastructure many people might believe it’s no longer there ! but it’s and below screenshot shows the exact location of desktop experience feature.

5-1-2012 3-18-02 PM     
do the following three steps
  • Add Windows Server Feature: User Interfaces and Infrastructure -> Desktop Experience 
  • Reboot 
  • Start Windows Services -> Themes service

Friday, 24 January 2014

InfoPath: Restrict visibility to users in a SharePoint Group

I receive lots of questions about how to limit a Section, a Button, or a View to only users within a specific SharePoint Group.  This is absolutely do-able, but a little tricky.  The trick is to use the UserGroup.asmx web service, and specifically the GetUserCollectionFromGroup method.
If you're familiar at all with the way that the Secondary Data Connections work in InfoPath, you will realize that the web service will pull in one or more resultant fields into an XML format structure that you can then retrieve with XSL - in other words, the data structure returned looks like and acts like the same as your Primary data source.  You can view secondary data sources by going to the Data Source Pane (Fields Pane in 2010), and clicking the dropdown at the top, and choosing your secondary data source.
 Data Source Dropdown 2007
Data Source Dropdown - InfoPath 2007
 Fields Dropdown 2010
Fields Dropdown - InfoPath 2010
The problem with the GetUserCollectionFromGroup web service, or more specifically with InfoPath itself (both 2007 and 2010) is that the data fields don't get pulled in correctly.
Using the references I list at the bottom of this post, I learned how to fix this.  However, I was hard pressed to find anyone who took it the final step and listed how to hook up the Button, Section, or View with Conditional Formatting and/or Rules to make it all happen.
So here I will put it all together for you.  Please let me be clear: the credit for the fixing of the service goes to Ian Chivers; I did not come up with this myself.  However I will list it here to make it easier for you to get this all in one post.
[EDIT - From here, I'm changing around the rest of my post based on trial and error. It requires more work, but is much more reliable.]

UserProfileService.asmx Web Service – GetUserProfileByName method

The first thing you need to do before you fiddle with getting the Group’s users, is to get the actual account name of the user that’s currently logged in. You need to do this because that is what you will use to compare against the list of users that come in from the Group.

Create the Data Connection

Steps for InfoPath 2007
 
Steps for InfoPath 2010
  • Open the Data Source Tool Pane.  If it is not open, go to View --> Task Pane and click "Data Source"
  • On the very bottom of the Data Source task pane, click "Manage Data Connections ..."
  • Click "Add..."
  • Click "Create a new connection to:" and choose "Receive Data"
  • Click "Next"
  • Click "Web service"
  • Click "Next"
  • Type in the url to your UserProfileService.asmx service.  It should be on your site you wish to get the group from.  Example:
    https://YourURLToServer/YourPath
    /YourSite/_vti_bin/UserProfileService.asmx
  • Click "Next"
  • You may have to authenticate at this point
  • Scroll down the list of methods and choose "GetUserProfileByName"
  • Click "Next"
  • You do not need to type in an Actual Value
  • Click "Next"
  • Click "Next"
  • Give the data connection a new name or keep the default, and make sure the checkbox is checked to automatically retrieve the data
  • Click "Finish"
 
  • Click the "Data" Ribbon Tab
  • Click "From Web Service"
  • Click "From SOAP Web Service"
  • Type in the url to your UserProfileService.asmx service.  It should be on your site you wish to get the group from.  Example:
    https://YourURLToServer/YourPath
    /YourSite/_vti_bin/UserProfileService.asmx
  • Click "Next"
  • You may have to authenticate at this point
  • Scroll down the list of methods and choose "GetUserProfileByName"
  • Click "Next"
  • You do not need to type in an Actual Value
  • Click "Next"
  • Click "Next"
  • Give the data connection a new name or keep the default, and make sure the checkbox is checked to automatically retrieve the data
  • Click "Finish"

Set up the first Dummy Field

Create a new field called CurrentUserAccountNameof type String.
  • Show the correct Pane
    • In InfoPath 2007, click to show the Data Source pane on the right-hand side
    • In InfoPath 2010, click to show the Fields pane on the right-hand side
  • Right-Click on the myFields or Top-Level data group (folder).
  • Click Add...
  • Type in CurrentUserAccountName for the field name
  • Keep the defaults of Field for Type and Text (string) for Data Type.  Press OK.

Set up the first Form Load Rule

Now we’re going to set a Form Opening (Form Load) rule so that we can populate the CurrentUserAccountName field. Keep in mind that the Form Opening rules will run after all the data connections retrieve their data (assuming you checked the checkbox to load the data as soon as the form opened).
In InfoPath 2007, you can get to this by selecting Tools --> Form Options --> Open and Save --> Open behavior --> Rules. In InfoPath 2010, you get to this by clicking the Data ribbon tab and then clicking “Form Load.”
  • Create a new Rule (Action rule in 2010)
  • Name the rule “Set Current User”
  • Do NOT set a condition – we want this to run every time the form loads
  • Add an action – “Set a Field’s Value”
  • For the field to set, Choose CurrentUserAccountName
  • For the value, press fx
  • Click “Insert Field or Group...”
  • On the top, press the dropdown box next to the word “Main”. Choose “GetUserProfileByName (Secondary)” .
  • Expand dataFields all the way out.
  • Expand Values all the way out.
  • Single-Click on Value – DO NOT PRESS OK
    GetUserProfileByName
  • Click “Filter Data...”
  • Click “Add...”
  • Click the first dropdown and select “Select a Field or Group”
  • Choose the field “Name” right underneath “PropertyData”
    GetUserProfileByName
  • Press OK
  • Keep “is equal to” in the second dropdown
  • Choose “Type text…” in the third Dropdown
  • Type in:
    AccountName
  • Press OK, Press OK (filter data), Press OK (select a field or group)
  • Your expression should look like the following:
    Insert Formula
  • Modify this function to make it all uppercase
    • Use the translate function to ensure that the AccountName that comes back is in all UpperCase
    • Formula is like this:
      translate(ValueYouWantToTranslate, "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
      Insert Formula
    • Click “Verify Formula” to ensure you typed in the function correctly.
  • Press OK, and press OK

UserGroup.asmx Web Service – GetUserCollectionFromGroup method

Now we need to pull in the list of users that are in the Group in question – the SharePoint group you set up with the people authorized to click that button.
Steps for InfoPath 2007
 
Steps for InfoPath 2010
  • Open the Data Source Tool Pane.  If it is not open, go to View --> Task Pane and click "Data Source"
  • On the very bottom of the Data Source task pane, click "Manage Data Connections ..."
  • Click "Add..."
  • Click "Create a new connection to:" and choose "Receive Data"
  • Click "Next"
  • Click "Web service"
  • Click "Next"
  • Type in the url to your UserGroup.asmx service.  It should be on your site you wish to get the group from.  Example:
    https://YourURLToServer/YourPath
    /YourSite/_vti_bin/UserGroup.asmx
  • Click "Next"
  • You may have to authenticate at this point
  • Scroll down the list of methods and choose "GetUserCollectionFromGroup"
  • Click "Next"
  • Click "Set Sample Value..."
  • Type in the name of the group you want to check against and press "OK"
  • Click "Next"
  • Click "Set Value..."
  • Again type in the name of the group you want to check against and press "OK"
  • Click "Next"
  • Click "Next"
  • Give the data connection a new name or keep the default, and make sure the checkbox is checked to automatically retrieve the data
  • Click "Finish"
 
  • Click the "Data" Ribbon Tab
  • Click "From Web Service"
  • Click "From SOAP Web Service"
  • Type in the url to your UserGroup.asmx service.  It should be on your site you wish to get the group from.  Example:
    https://YourURLToServer/YourPath
    /YourSite/_vti_bin/UserGroup.asmx
  • Click "Next"
  • You may have to authenticate at this point
  • Scroll down the list of methods and choose "GetUserCollectionFromGroup"
  • Click "Next"
  • Click "Set Sample Value..."
  • Type in the name of the group you want to check against and press "OK"
  • Click "Next"
  • Click "Set Value..."
  • Again type in the name of the group you want to check against and press "OK"
  • Click "Next"
  • Click "Next"
  • Give the data connection a new name or keep the default, and make sure the checkbox is checked to automatically retrieve the data
  • Click "Finish"

Take a look at what has been returned for Web Service

Remember in the other web service, that when we went to get the value for the Account Name, it presented us with information we had to drill down to. That was correct. However, for whatever reason, the GetUserCollectionFromGroup web service does not return the correct information. Let’s take a quick look at what it returns:
GetUserCollectionFromGroup
What we have to do here to fix this, is we have to actually manipulate the source files of the InfoPath form.

Create a Folder for your Source Files

On your file system (C Drive or Desktop for example), navigate to where you have saved your InfoPath form template. Create a new empty folder by the name of “TemplateName Source Files”. So if your Template Name is "Training Request Form” then name the folder "Training Request Form Source Files.”

Save as Source Files

In InfoPath 2007, Click the File menu, and click “Save As Source Files”. In InfoPath 2010, click the File ribbon tab, click “Publish” on the left hand side, and then click “Export Source Files”. Save the source files in the folder you just created. Close InfoPath completely.

Fix the GetUserCollectionFromGroup1.xsd file

Open the folder you created with the source files in it. You should see quite a few files in this folder. Using NOTEPAD, open the file named GetUserCollectionFromGroup1.xsd (choose GetUserCollectionFromGroup.xsd, GetUserCollectionFromGroup1.xsd, or GetUserCollectionFromGroup2.xsd based on which is the file with the greatest file size. This is usually the GetUserCollectionFromGroup1.xsd file).
At the top of the file, locate the following line:
<s:import namespace="http://www.w3.org/2001/XMLSchema"></s:import>
Right underneath that line, insert the following code:
<!-- Beginning of insert -->
<s:complexType name="GetUserCollectionFromGroupType">
 <s:sequence>
  <s:element minOccurs="0" maxOccurs="1" name="Users">
   <s:complexType>
    <s:sequence>
     <s:element maxOccurs="unbounded" name="User" >
      <s:complexType>
       <s:attribute name="Notes" type="s:string"></s:attribute>
       <s:attribute name="Name" type="s:string"></s:attribute>
       <s:attribute name="IsSiteAdmin" type="s:string"></s:attribute>
       <s:attribute name="Sid" type="s:string"></s:attribute>
       <s:attribute name="ID" type="s:string"></s:attribute>
       <s:attribute name="LoginName" type="s:string"></s:attribute>
       <s:attribute name="Email" type="s:string"></s:attribute>
       <s:attribute name="IsDomainGroup" type="s:string"></s:attribute>
      </s:complexType>
     </s:element>
    </s:sequence>
    </s:complexType>
  </s:element>
 </s:sequence>
</s:complexType>
<!-- End of Insert -->

[EDIT:  Please make sure there is no space in the above </s:complexType>]

Now find the following code:
<s:element name="GetUserCollectionFromGroup">
  <s:complexType>
    <s:sequence>
      <s:element minOccurs="0" maxOccurs="1" name="groupName" type="s:string"></s:element>
    </s:sequence>
  </s:complexType>
</s:element>

Comment out that code by placing a <!-- before the beginning and an --> after the end.  Result should look like this:
<!--<s:element name="GetUserCollectionFromGroup">
  <s:complexType>
    <s:sequence>
      <s:element minOccurs="0" maxOccurs="1" name="groupName" type="s:string"></s:element>
    </s:sequence>
  </s:complexType>
</s:element>-->

Right underneath that commented out code, insert the following code:
<!-- Beginning of Insert -->
<s:element name="GetUserCollectionFromGroup" type="tns:GetUserCollectionFromGroupType" />
<!-- End of Insert -->

Save and close the file
Go back to the folder where you saved those Source Files to.  Find the file "manifest.xsf" and RIGHT-click the file and choose "Design".  This will open your InfoPath file back up.  Click SAVE AS and save as a new .xsn file.

A few Notes to keep in mind, before we go on

It is important to note the following 2 things:
  • Don't modify your GetUserCollectionFromGroup secondary data source (or if you do, you'll have to do this all over again, from the part where you open up the files).
  • Make sure the group in question allows "Everyone" to see the membership of the group
    • Site Actions --> Site Settings --> People and Groups
    • Click on "Groups" on the left
    • Locate your Group
    • Click on the Edit button next to it
    • For "Who can view the membership of the Group" click the option "Everyone"

Take a new look at the fields for the Web Service

Let's take a quick look at what it returns now:
GetUserCollectionFromGroup Modified
These are the fields that we need.

Set up another dummy Field

Create a new field called IsCurrentUserInGroupof type True/False (boolean).
  • Show the correct Pane
    • In InfoPath 2007, click to show the Data Source pane on the right-hand side
    • In InfoPath 2010, click to show the Fields pane on the right-hand side
  • Right-Click on the myFields or Top-Level data group (folder).
  • Click Add...
  • Type in IsCurrentUserInGroup for the field name
  • Keep the defaults of Field for Type
  • Change the Data Type to True/False (boolean). Keep the default value equal to FALSE.
  • Press OK.

Set up another Form Load Rule

Now we’re going to set a Form Opening (Form Load) rule so that we can populate the IsCurrentUserInGroup field.
In InfoPath 2007, you can get to this by selecting Tools --> Form Options --> Open and Save --> Open behavior --> Rules. In InfoPath 2010, you get to this by clicking the Data ribbon tab and then clicking “Form Load.”
  • Create a new Rule (Action rule in 2010)
  • Name the rule “Set Current User”
  • Do NOT set a condition – we want this to run every time the form loads
  • Add an action – “Set a Field’s Value”
  • For the field to set, Choose IsCurrentUserInGroup
  • For the value, press fx
  • Click “Insert Field or Group...”
  • On the top, press the dropdown box next to the word “Main”. Choose “GetUserCollectionFromGroup (Secondary)” .
  • Expand dataFields all the way out.
  • Single-Click on LoginName. DO NOT PRESS OK.
    Select Field or Group
  • Press “Filter Data...”
  • Click “Add...”
  • In the first dropdown, keep “LoginName”
  • Keep the second dropdown at “is equal to”
  • Click the third dropdown and click “Select a Field or Group”
  • Change the Data Source (top dropdown) back to Main
  • Select the CurrentUserAccountName field
  • Press OK, press OK (filter Data), press OK (select a field or group)
  • Do not close the window “Insert Formula”. It now looks like this:
    Insert Formula
  • Add the boolean and count functions, to turn this into a True/False
    • We’re going to type in the following:
      boolean(count(expression) > 0)
    • So for our example, it should now look like this:
      Insert Formula

Modify the XPath Directly to set to Upper Case

Unfortunately, this does not give us exactly what we want, but it gets us really close. We’ll use what we currently have to change the XPath expression directly into what we need it to be.
  • Click the checkbox “Edit XPath (advanced)”
  • You will now see something like this:
    Insert Formula
  • Notice how I highlighted the period (.) in the picture above, right after @LoginName[
  • We’re going to put the translate function around that period:
    translate(., "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
  • So it should now look like this:
    Insert Formula
  • Click the checkbox again “Edit XPath (advanced)”
  • This will take it out of advanced mode and give you a little more simplified of a view.
  • It should read something like
    boolean(count(@LoginName[translate(., "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ") = CurrentUserAccountName]) > 0)
To recap, what this function is saying is this:
  • Go get the @LoginName from the web service
  • Translate it all to Upper Case
  • Find the number of times that the Upper Case LoginName is equal to the CurrentUserAccountName field
  • If it’s greater than 0 times, return true
  • Change the “true” word to a Boolean value

Set up the condition on the Button

And finally after all of that trouble, we use a reasonably simple Conditional Formatting condition to get the button to Hide when the current user is not part of that group.
  • In InfoPath 2007, right-click the button and choose Conditional Formatting
  • In InfoPath 2010, click Manage Rules in the Home ribbon tab, and add a new “Formatting” rule
  • Set the Condition
    • In the first dropdown, click “Select a Field or Group”
    • Choose “IsCurrentUserInGroup” from the Main data source
    • Keep “is equal to” in the second dropdown
    • Choose “FALSE” in the third dropdown (remember, we’re HIDING the button when the user is NOT in the group)
    • Click OK
  • Set the Formatting
    • Click “Hide this control”

Test the functionality

We need to make sure that we test the functionality. Even if you are the administrator for the site, you won’t see the button if you’re not in that group, so you can effectively test.
  • Publish the form to your SharePoint Site. Ensure that the Forms Library is set to serve up the form as a Web Page.
  • Put yourself INTO the group you set up in the form
  • Test the form by clicking New and switching views – do you see the button? You should.
  • Close the new InfoPath form.
  • Take yourself Out of the group you set up in the form
  • Test the form by clicking New and switching views – do you see the button? You should not.

Monday, 30 December 2013

Alert Summary App - Sharepoint 2013

Description:

Alert Summary: -
If current user has ManageWeb permissions, we'll consider them an administrator. Otherwise, we'll consider them a viewer.
So Administrator can add alert, edit alert and delete alert items.
Viewer can only view the alert items which are created by an administrator. It has been categorized in three ways, I) critical, ii) warning, iii) information.


Note: Alert Items will be displayed based on Start Date and End Date , If  Start Date <= Current Date && Current Date <= new End Date  the condition is satisfied then display the alerts.


Step 1 :


Alert Summary app Added


Step 2 :

For Administrator - Currently No alerts

Add New Alert :

Alert Items:



Delete Alert :

Edit Alert :











Viewer can only view the alert Details :


Friday, 20 September 2013

All ways of RunWithElevatedPrivileges


  1. RunWithElevatedPrivileges?
  2. Why can’t we use RunWithElevatedPrivileges in event handlers?
  3. Impersonation Improvements in SharePoint 2010 Event Receivers?
  4. Best recommended practice use of it?
  5. Best recommended practice to use of it in Event Receivers?
  6. Best recommended practice to use of it in Feature Receivers?
  7. RunWithElevatedPrivileges in visual studio workflows:
  8. Is RunWithElevatedPrivileges allowed in sandbox solution?
  9. By using which credentials the RunWithElevatedPrivileges will run?
  10. Difference between SPSecurity.CodeToRunElevated and SPSecurity. RunWithElevatedPrivileges?


Impersonation:
Impersonation is the process of executing code in the context (or on behalf) of another user identity.
What are the Impersonation methods in SharePoint 2010?
  • RunWithElevatedPrivileges to impersonate as System Account user
  • Passing User Token inside SPSite to impersonate as particular user
  • Using Windows API
SPUserToken:
The SPSite object takes an SPUserToken object in its constructor in order to support impersonation.To impersonate the system, use the SystemAccount.UserToken property of the current SPSite context, such as:
var site = new SPSite(SPContext.Current.Site.ID, SPContext.Current.Site.SystemAccount.UserToken);

Difference between RunWithElevatedPrivileges Vs SPUserToken:
  • RunWithElevatedPrivileges to impersonate as System Account user
  • Passing User Token inside SPSite to impersonate as particular user
RunWithElevatedPrivileges?
As per the msdn: Executes the specified method with Full Control rights even if the user does not otherwise have Full Control. 

Whenever we use SPSecurity.RunWithElevatedPrivileges (), it will execute the code under the context of Application Pool identity, so you must ensure that the App Pool account is a member of a site collection group with sufficient perms to add/edit/delete or whatever your code is trying to do. If not, the code will quietly break without popping an exception.

Method: Microsoft.SharePoint. SPSecurity.RunWithElevatedPrivileges

The code will not run within the elevated privilege if the object accessed was not created within the SPSecurity.RunWithElevatedPrivileges block. The main reason for doing so is to ensure that all the objects are in the context of the App Pool's identity.


SPSecurity.RunWithElevatedPrieveleges, there are too much tricks that you should take care of.
For Instance: You must create the new SPSite objects inside the delegate because SPSite objects created outside do not have Full Control even when referenced inside the delegate.

RunWithElevatedPrivileges does not work when HTTPContext is null:
RunWithElevatedPrivileges don’t work when HTTPContext (SPContext to be more specific) is null. So, you will not have elevation of privilege when using RunWithElevatedPrivileges in Console Application, Workflow, Timer Job or Event handlers not initiated by a request in browser.

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[ means 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 cerated within the RunWithElevatedPrivileges code block as above. 

Impersonation Improvements in SharePoint 2010 Event Receivers?
Instead of using RunWithElevatedPrivileges, In SharePoint 2010, there are new properties namely OriginatingUserToken, UserDisplayName and UserLoginName which help the developers to revert back to the original user who triggered the event very easily. 

I will update once get the clear idea on what use of the new properties OriginatingUserToken, UserDisplayName and UserLoginName introduced in SharePoint 2010.

RunWithElevatedPrivileges in visual studio workflows:
No need to use any elevated privileges when working with workflows because it runs under SharePoint System Account by default (the App Pool account).

Is RunWithElevatedPrivileges allowed in sandbox solution?
You cannot use SPSecurity.RunWithElevatedPrivileges method in case of Sandboxed solution. The main reason is Sandbox solutions execute in User Code service with limited privileges.

Best recommended practice use of it:
Can’t use SPContext inside the code being RunWithElevatedPrivileges. We may get “access denied” error if instead write the SPWeb site = SPContext.Current.Web inside the RunWithElevatedPrivileges, because your web was created in the context of the current user.

Best recommended practice is: Take the current context outside the SPSecurity.RunWithElevatedPrivileges block and then create a new instance of SPSite and SPWeb inside the block which will run under application pool identity.

Simply to say is: The objects you’re working with need to be recreated within your RunWithElevatedPrivileges code block.
  

Recommended practice #1: 
  1. private void Test()  
  2. {  
  3.     Guid webID = SPContext.Current.Web.ID;  
  4.     Guid siteID = SPContext.Current.Site.ID;  
  5.     SPSecurity.RunWithElevatedPrivileges(delegate()  
  6.     {  
  7.         using (SPSite site = new SPSite(siteID))  
  8.         {  
  9.             using (SPWeb web = site.OpenWeb(webID))  
  10.             {  
  11.                 // Code Using the SPWeb Object goes here  
  12.             }  
  13.         }  
  14.     });  
  15. }  
Best recommended practice #2: 
  1. private void Test()  
  2.         {  
  3.             SPSite site = SPContext.Current.Site;  
  4.             SPWeb web = SPContext.Current.Web;  
  5.   
  6.             SPSecurity.RunWithElevatedPrivileges(delegate()  
  7.             {  
  8.                 using (SPSite CurrentSite = new SPSite(site.ID))  
  9.                 {  
  10.                     using (SPWeb CurrentWeb = CurrentSite.OpenWeb(web.ID))  
  11.                     {  
  12.                         // Code Using the SPWeb Object goes here  
  13.                     }  
  14.                 }  
  15.             });  
  16.         }  
RunWithElevatedPrivileges” in Feature Receivers: 
  1. [Guid("b321499d-9b43-410e-8a8f-779ffb81d738")]  
  2.     public class Feature1EventReceiver : SPFeatureReceiver  
  3.     {  
  4.         public override void FeatureActivated(SPFeatureReceiverProperties properties)  
  5.         {  
  6.             try  
  7.             {  
  8.                 using (SPSite spSite = properties.Feature.Parent as SPSite)  
  9.                 {  
  10.                     using (SPWeb spWeb = spSite.OpenWeb())  
  11.                     {  
  12.                         SPSecurity.RunWithElevatedPrivileges(delegate()  
  13.                         {  
  14.                             //code here  
  15.                         });  
  16.                     }  
  17.                 }  
  18.             }  
  19.             catch (Exception ex)  
  20.             {  
  21.             }  
  22.         }  
“RunWithElevatedPrivileges” in Event Receivers: Better to use the ID properties of the properties object, to get new instances of SPSite, SPWeb and SPListItem. If you need to run actions with elevated privileges on SPSite and SPWeb object use new SPSite(properties.SiteId); and site.OpenWeb(properties.RelativeWebUrl) instead of properties.web and web.site;
Best Recommended Practice #1 
  1. namespace MyCustomDlgFramework.EventReceiver  
  2. {  
  3.     /// <summary>  
  4.     /// List Item Events  
  5.     /// </summary>  
  6.     public class EventReceiver : SPItemEventReceiver  
  7.     {  
  8.        /// <summary>  
  9.        /// An item is being added.  
  10.        /// </summary>  
  11.        public override void ItemAdding(SPItemEventProperties properties)  
  12.        {  
  13.            SPSecurity.RunWithElevatedPrivileges(delegate()  
  14.            {  
  15.                using (SPSite site = new SPSite(properties.SiteId))  
  16.                {  
  17.                    using (SPWeb web = site.OpenWeb(properties.RelativeWebUrl))  
  18.                    {  
  19.                        //code here  
  20.                    }  
  21.                }  
  22.            });  
  23.              
  24.        }  
  25.   
  26.     }  
  27. }  
Best recommended practice #2: 
  1. namespace MyCustomDlgFramework.MyEventReceiver  
  2. {  
  3.     /// <summary>  
  4.     /// List Item Events  
  5.     /// </summary>  
  6.     public class MyEventReceiver : SPItemEventReceiver  
  7.     {  
  8.        /// <summary>  
  9.        /// An item is being added.  
  10.        /// </summary>  
  11.        public override void ItemAdding(SPItemEventProperties properties)  
  12.        {  
  13.             using (SPSite site = new SPSite(properties.WebUrl))  
  14.            {  
  15.                using (SPWeb web = site.OpenWeb())  
  16.                {  
  17.                    SPSecurity.RunWithElevatedPrivileges(delegate()  
  18.                    {    
  19.                        //Code here  
  20.                    });  
  21.                }  
  22.         }  
  23.     }  
  24.   }  
  25. }  
Best recommended practice #3: 
  1. namespace MyCustomDlgFramework.EventReceiver  
  2. {  
  3.     /// <summary>  
  4.     /// List Item Events  
  5.     /// </summary>  
  6.     public class EventReceiver : SPItemEventReceiver  
  7.     {  
  8.        /// <summary>  
  9.        /// An item is being added.  
  10.        /// </summary>  
  11.        public override void ItemAdding(SPItemEventProperties properties)  
  12.        {  
  13.            SPSecurity.RunWithElevatedPrivileges(delegate()  
  14.            {  
  15.                using (SPWeb web = properties.OpenWeb())  
  16.                {  
  17.                    //Code here  
  18.                }  
  19.   
  20.            });  
  21.        }  
  22.   
  23.     }  
  24. }  
Chances of getting “Access Dined” error:

Note: Elevation of privilege occurs only if new SPSite created inside the block : 

  1. private void Test()  
  2.         {  
  3.             SPSecurity.RunWithElevatedPrivileges(delegate()  
  4.             {  
  5.                 SPWeb currentWeb = SPContext.Current.Web;  
  6.                 SPList spList = currentWeb.Lists["MyList"];  
  7.             });  
  8.         }  
  1. private void Test()  
  2. {  
  3.     SPSecurity.RunWithElevatedPrivileges(delegate()  
  4.     {  
  5.         using (SPSite currentSite = new SPSite(SPContext.Current.Site.Url))  
  6.         {  
  7.             using (SPWeb currentWeb = currentSite.OpenWeb())  
  8.             {  
  9.                 // Access granted as System account!!   
  10.             }  
  11.         }  
  12.     });  
  13. }  
  1. private void Test()  
  2.         {  
  3.             SPSecurity.RunWithElevatedPrivileges(delegate()  
  4.             {  
  5.                 SPSite site = SPContext.Current.Site;  
  6.                 SPWeb web = SPContext.Current.Web;  
  7.                 web.AllowUnsafeUpdates = true;  
  8.   
  9.                 SPList list = web.Lists["MyList"];  
  10.                 SPListItem item = list.GetItemById(1);  
  11.                 item["MyField"] = "SharePoint";  
  12.                 item.Update();  
  13.   
  14.                 web.AllowUnsafeUpdates = false;  
  15.             });  
  16.         }  


Reason: SPContext.Current.Site and SPContext.Current.Web runs the List Item update code in the context of the currently logged in user and not in the context of the App Pool identity.