Wednesday, June 10, 2009

Sharepoint Tips n Tricks

1) Export Spreadsheet menu is not visible in Forms Based application in SharePoint:

Solution: Go tO -


Central Administration > Application Management >
Authentication Providers > Edit Authentication


Checked "Yes" in "Enable Client Integration? "



Notes: Client Integration
Disabling client integration will remove features which launch client applications. Some authentication mechanisms (such as Forms) don't work well with client applications. In this configuration, users will have to work on documents locally and upload their changes.


2) Apply validation controls on SharePoint's DateTimeControl

Following code snippet displays, how to apply following validations on Sharepoint's DateTimeControl:
a) Required field validation
b) Valid date validation
c) Date compare validation


<table cellpadding="0" cellspacing="0" style="font-size: 8pt; font-family: Tahoma;">
<tr>
<td>
<SharePoint:DateTimeControl ID="dateTimeStartDate" runat="server"
DateOnly="true"></SharePoint:DateTimeControl>
</td>
<td></td>
</tr>
<tr>
<td>
<SharePoint:DateTimeControl ID="dateTimeEndDate" runat="server"
DateOnly="true"></SharePoint:DateTimeControl>
</td>
<td>
<asp:RequiredFieldValidator ID="RequiredFieldValidator5" runat="server"
ControlToValidate="dateTimeEndDate$dateTimeEndDateDate"
ErrorMessage="* Required value"
Display="Dynamic"></asp:RequiredFieldValidator>

<asp:CompareValidator ID="CompareValidator2" runat="server"
ForeColor="Red"
ControlToValidate="dateTimeEndDate$dateTimeEndDateDate" Type="Date"
Operator="DataTypeCheck" ErrorMessage="* Please enter an valid date."
Display="Dynamic"></asp:CompareValidator>

<asp:CompareValidator ID="valDate" runat="server" ForeColor="Red"
ControlToValidate="dateTimeEndDate$dateTimeEndDateDate"
ControlToCompare="dateTimeStartDate$dateTimeStartDateDate" Type="Date"
Operator="GreaterThanEqual"
ErrorMessage="* Please enter End Date Greater or Equal to Start Date."
Display="Dynamic"></asp:CompareValidator>
</td>
</tr>
</table>




3) Access denied issue for Forms based user

I did following thing to solve "Access Denied" issue in "Forms Based configuration" ---

Go to :
1) Central Administration > Application Management > Policy for Web Application
2) Select proper Web Application (from top-right)
3) Click "Add User" (top-left)
4) Add required User or Role in it.
5) Grant it "Full Control" (as per requirement).

Available options:
[
Full Control - Has full control.
Full Read - Has full read-only access.
Deny Write - Has no write access.
Deny All - Has no access.
]

Then its work fine for me !!!


4) Operation with SPCoulmn Type - SPFieldChoice

Following code snippet retrieves the values stored in a SPColumn.
You can used these values to populated either Dropdown or Listbox as per you requirement.


SPList list = oWebsite.Lists["SPList_Name"];
SPFieldChoice choice = (SPFieldChoice)list.Fields["Event Name"];

foreach(string s in choice.Choices)
Response.Write(s);



5) Open SharePoint page in edit-mode

There are basically two ways to open a sharepoint page in edit-mode
a) Go to Site Actions (Top-Right) and then selecte Edit page.
b) Append the query string of current page with ?toolpaneview=2
e.g. http://myserver.default.aspx?toolpaneview=2



6) Access AppSettings in SharePoint



//Web config entry
<appSettings>
<add key="UpdateTime" value="300" />
</appSettings>


//C# code to access appsetting
System.Configuration.ConfigurationSettings.AppSettings["UpdateTime"].ToString();

//or new way
System.Configuration.ConfigurationManager.AppSettings["UpdateTime"].ToString();




7) RichTextbox or InputFormTextBox in SharePoint





//C# code
InputFormTextBox body = new InputFormTextBox();
body.RichText = true;
body.RichTextMode = Microsoft.SharePoint.SPRichTextMode.Compatible;
body.Rows = 5;
body.TextMode = TextBoxMode.MultiLine;
body.Width = new Unit(300);

this.Controls.Add(body);


Reference--
sharepoint-using-the-rich-text-box-in-a-custom-user-control



8) Session usage in SharePoint

To enable session in your SharePoint pages, open you web application web.config file.

a) Search HttpModule in cofig file, uncomment the following code -

<add name="Session" type="System.Web.SessionState.SessionStateModule" />

b) If session still doesn't work, then set EnableSessionState property to true in page directive.


After enabling the session, if you face some error like...

unable to serialize the session state. in 'stateserver' and 'sqlserver' mode asp.net

Then again open you web.config file and delete following line...

<sessionState mode="StateServer" timeout="60" allowCustomSqlDatabase="true"
partitionResolverType=
"Microsoft.Office.Server.Administration.SqlSessionStateResolver,
Microsoft.Office.Server, Version=12.0.0.0, Culture=neutral,
PublicKeyToken=71e9bce111e9429c" />




9) User Profile in SharePoint



SPSite mySite = SPControl.GetContextSite(Context);
SPWeb myWeb = SPControl.GetContextWeb(Context);
ServerContext context = ServerContext.GetContext(mySite);
UserProfileManager myProfileManager = new UserProfileManager(context);
string CurrentUser = SPContext.Current.Web.CurrentUser.LoginName;
UserProfile myProfile = myProfileManager.GetUserProfile(CurrentUser);

if (myProfile[PropertyConstants.WorkEmail].Value != null)
{
oLabelWorkEmail.Text = myProfile[PropertyConstants.WorkEmail].Value.ToString();
}


References:
How to retrieve current user profile properties
MSDN Forum



10) Run the code with Elevated Privileges

While excuting the code if we face some Privilege or Access issue, then to solve this we can either use SPSecurity.RunWithElevatedPrivileges OR UserToken.

Check following code snippets...


try
{
// Get the Site ID before entering RunWithElevated...
Guid siteID = SPContext.Current.Site.ID;

SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(siteID))
{
// Your code logic here,
//without calling SPContext anywhere inside this method...
}
});
}
catch (SPException spex)
{
//Log exception
}


Note - It is very important to not call the SPContext from within any elevated method, as it'll result in your elevated privileges to cease.



SPUserToken sysToken = SPContext.Current.Site.SystemAccount.UserToken;

using (var spSite = new SPSite(SPContext.Current.Site.ID, sysToken))
{
using (var spWeb = spSite.OpenWeb(SPContext.Current.Web.ID))
{
//Your code
}
}

How to use LINQ in SharePoint

LINQ : Language Integrated Query

If you are writing in-line server code (C# and HTML code in same ASPX file), then you have to follow next 2 steps:

1) Page level directive


<%@ Assembly Name="System.Core, Version=3.5.0.0, Culture=neutral,
PublicKeyToken=B77A5C561934E089" %>
<%@ Import Namespace="System.Linq" %>
<%@ Import Namespace="System.Collections.Generic" %>



2) Modify application's web.config file
Add following lines just below </system.Web> node


  
</system.web><!-- Reference point -->

<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4"
type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
warningLevel="4" type="Microsoft.VisualBasic.VBCodeProvider, System,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
<providerOption name="OptionInfer" value="true"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
</compilers>
</system.codedom>




3) LINQ code

If you writing C# in seperate file (Code-behind) then you can skip first two steps.



SPList oList;
//To get a particular SPView specific SPListItems
SPView spView = oList.Views["MySPView_Name"];
SPListItemCollection itemCollec = oList.GetItems(spView);


if (itemCollec != null)
{
//You can also run following query directly
//over SPList (by replacing itemColle with oList)
List<SPListItem> items
= (from spLItem in itemCollec.OfType<SPListItem>()
where spLItem["Employee Name"] != null
&& Convert.ToString(spLItem["Employee Name"]) == "Avi"
select spLItem).ToList<SPListItem>();

//Write total items count
Response.Write(items.Count);

//To get individual SPListItem you can either use
//Foreach iteration or indexer e.g. items[i]
}




References:

1) SharePoint Development with LINQ
2) Use Linq inside ...
3) Using LINQ to query a SharePoint List
4) Linq in Sharepoint and querying listitems

How to write Server-side ( C# ) code in SharePoint custom pages

There are basically two approaches to write server side code:
A) Inline coding ( C# and HTML code in same ASPX page)
B) Code-Behind (C# and HTML code in seperate files)

A) Inline coding

1) In this approach, first you have to modify application's web.cofig file.
Locate PageParserPaths node in config file and then change it as per your requirement.

If you doesn't know page(s) name which is(are) using server side code, then write /* in VirtualParth attribute,
else write page name as /pagename.aspx in VirtualParth attribute.
[For each page add a seperate PageParserPath node,
for example you want to allow server side code in 5 pages then you have to add PageParserPath nodes.]



<PageParserPaths>
<PageParserPath VirtualPath="/*" CompilationMode="Always"
AllowServerSideScript="true" />
</PageParserPaths>




2) Write server side code as


<script runat="server">

protected void Page_Load(Object sender, EventArgs e)
{
Response.Write("Server code");
}

</script>



B) Code-Behind approach

1) Create a C# file (or VB file) for your server code


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyNameSPace
{
public class MyClass : Microsoft.SharePoint.WebControls.LayoutsPageBase
{
//Server control declarations
protected Label lblMessage;

protected void Page_Load(Object sender, EventArgs e)
{
lblMessage.Text = "Server Code";
}
}
}



Points to remember:
- Inherits the class with LayoutsPageBase (there are other options also available for choosing base class)
- Declare ASP.Net server control with protected modifier.



2) Register the DLL (that contains above class) in GAC.

3) safecontrol entry in application's web.config file.

4) Create ASPX file for HTML code


<%@ Assembly Name="MyNameSPace, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=bf118dafb4e11f4b" %>
<%@ Page Language="C#" MasterPageFile="~masterurl/default.master"
Inherits="MyNameSPace.MyClass" %>

<asp:Content ID="Content1" ContentPlaceHolderID="PlaceHolderMain" runat="server">
<asp:Label runat="server" ID="lblMessage" ForeColor="Red"
Visible="false"></asp:Label>
</asp:Content>



Points to remember:
- Specify assembly reference of class created in step 1 (with proper Name, Version, Culture and PublicKeyToken)
- In case of Master-Content page scenario specify MasterPageFile attribute in Page directive
- Specify Inherits attribute in Page directive with proper NameSpace and Class name (e.g. Inherits="MyNameSPace.MyClass" )
- Write ASP.Net server control(s) that we have declared in Step 1 (with protected modifier)


Pros n Cons

Inline
- Easy to deploy, no need to do DLL registration in GAC, IISRESET and safecontrol entry in web.config
- It is unsafe, to allow server side code by modifying PageParserPaths node in web.cofig
- Can't debug the page [Major disadvantage while development].
- In case of any change(s) in code (HTML + C#), replace the existing ASPX file with modified one in SharePoint Designer.


Code-Behind
- Can debug server side code ( Debug -> Attach to Process -> w3wp.exe process )
- Need to do DLL registration in GAC, IISRESET and safecontrol entry in web.config
- It's safer to use compare to inline code
- In case of any change(s) in HTML code, replace the existing ASPX file with modified one in SharePoint Designer.
- In case of any change(s) in server-side ( C# ) code, re-register the DLL in GAC (drag-n-drop dll in assembly folder) and do IISRESET [ Must ] to see the change(s).

Google