The Best Practice Guidelines of Development on SharePoint 2010/SharePoint 2007 – Part 2

The Best Practice Guidelines of Development on SharePoint 2010/SharePoint 2007 - part 1

The Best Practice Guidelines of Development on SharePoint 2010/SharePoint 2007 – Part 2

Abstract:

This article describes how the objects are cached in the SharePoint2010 and the need to pay attention, but also introduces some of the technical optimization of the code.

Cache is the traditional. NET development of a common development approach to improve performance, but in SharePoint brought in to pay particular attention to the performance of the cache to improve the balance between and thread safe, some SharePoint objects are not thread-safe type, do Cache will lead to unexpected exception.

For example, when reading the list of data to cache SPListItemCollection is a common way of thinking, but because SPListItemCollection contains a non-secure threads SPWeb object, if the SPListItemCollection run directly to the cache will lead to error or abnormal operation.

The following example shows the cache SPListItemCollection not thread safe.

public void CacheData()
{
SPListItemCollection items;
items = (SPListItemCollection)Cache["AListItemCache"];
if(items == null)
{
items = DoQueryToReturnItems();
Cache.Add("AListItemCache", items, ...);
}
}







The code above working mechanism of the IIS is running multi-threaded, if DoQueryToResturnItems () query takes 10 seconds, in this time period, if a lot of users do the same operation, it will lead to the same query is also Run, and the object will be to modify the same items, it will not only result in thread-safe problems will also cause performance problems. In order to prevent the synchronization of multiple threads, you need to lock:




private static object _lock = new object();
public void CacheData()
{
SPListItemCollection items;
lock(_lock)
{
items = (SPListItemCollection)Cache["AListItemCache"];
if(items == null)
{
items = DoQueryToReturnItems();
Cache.Add("AListItemCache", items, ...);
}
}
}







In the above code, the location of the lock can be adjusted to  after if (items == null) and get a certain degree of performance improvement:




private static object _lock = new object();
public void CacheData()
{
SPListItemCollection items;
items = (SPListItemCollection)Cache["AListItemCache"];
if(items == null)
{
lock(_lock)
{
items = DoQueryToReturnItems();
Cache.Add("AListItemCache", items, ...);
}
}
}







But it also brings other problems, the implementation of this method when DoQueryToReturnItems long time when there may be multiple threads waiting outside in the lock, when the first thread is updating the Cache, the second thread will Incoming query data and update the thread, if there is a third thread will do the same thing. . . Can make the following improvements:




private static object _lock =  new object();

public void CacheData()
{
SPListItemCollection oListItems;
oListItems = (SPListItemCollection)Cache["ListItemCacheName"];
if(oListItems == null)
{
lock (_lock)
{
oListItems = (SPListItemCollection)Cache[“ListItemCacheName”];
if (oListItems == null)
{
oListItems = DoQueryToReturnItems();
Cache.Add("ListItemCacheName", oListItems, ..);
}
}
}
}







Although the above code to solve the cache problem, but the practice is still not recommended because it is a thread no-safe caching object SPListItemCollection. In order to solve the problem of thread no-safety, you can use DataTable to store data:




private static object _lock =  new object();

public void CacheData()
{
DataTable oDataTable;
SPListItemCollection oListItems;
lock(_lock)
{
oDataTable = (DataTable)Cache["ListItemCacheName"];
if(oDataTable == null)
{
oListItems = DoQueryToReturnItems();
oDataTable = oListItems.GetDataTable();
Cache.Add("ListItemCacheName", oDataTable, ..);
}
}
}







Code Optimization to SharePoint:



A common optimization:




SPWeb myWeb = SPContext.Current.Web;

myWeb.Lists["Tasks"].Title = "List_Title";
myWeb.Lists["Tasks"].Description = "List_Description";
myWeb.Lists["Tasks"].Update();







The following modified code is only one instance of a list of tasks and stored in the myList variable to reduce the access to the database to improve performance:




SPWeb myWeb = SPContext.Current.Web;

SPList myList = myWeb.Lists["Tasks"];

myList.Title="List_Title";
myList.Description="List_Description";
myList.Update();



The Best Practice Guidelines of Development on SharePoint 2010/SharePoint 2007

The Best Practice Guidelines of Development on SharePoint 2010/SharePoint 2007 - part 1

The Best Practice Guidelines of Development on SharePoint 2010/SharePoint 2007 – Part 2

Summary:

This article is based on SharePoint SDK documents.Summarized the best practice guideline of development on SharePoint, you could apply this content to SharePoint 2010 and SharePoint 2007. Contains the using method to SPSite and SPWeb object, the naming when you deploy files to template file; Using SPSite and SPWeb object in event handler ; the handling to large files and large list items and the object cache and some examples of  code optimization.

Avoid unnecessary construct to the SPSite and SPWeb object

1. SPSite and SPWeb object will consume much cache, when development based on SharePoint, you should avoid unnecessary construct these new object. Specially just for getting the reference to SPWebApplication. For getting SPWebApplication, you could invoke SPWebApplication.LookUp(url) to get the referencing. Then getting the referencing to Farm by WebApplication.Farm. If you know the index value of content database, you could get the referencing to the content database by webApplication.Farm.

Code snippet:

SPWebApplication webApplication = SPWebApplication.Lookup(new Uri("http://localhost/");
SPFarm farm = webApplication.Farm;
SPContentDatabase content = webApplication.ContentDatabases[0];







2. If you have to construct the SPSite and SPWeb object, you have to dispose them when finish, you could using 3 method to do this:




A. Dispose method



B. using



C. try, catch, finally




When you use the using method, below is the code snippet:




String str;  

using(SPSite oSPsite = new SPSite("http://server"))

{

using(SPWeb oSPWeb = oSPSite.OpenWeb())

{

str = oSPWeb.Title;

str = oSPWeb.Url;

}

}







But at you using this method, you should avoid release the object which should not be released. For example:




using( SPWeb web = SPControl.GetContextWeb(HttpContext.Current)) { ... }





SPContext is maintained by SharePoint framework, do not release, SPContext.Site, SPContext.Current.Site, SPContext.Web, SPContext.Current.Web should not be released. try, catch , finally is sample to using, they implements the interface object of IDispose, the .NET RunTime will transfer using to try, catch, finally.




String str;
SPSite oSPSite = null;
SPWeb oSPWeb = null;

try
{
oSPSite = new SPSite("http://server");
oSPWeb = oSPSite.OpenWeb(..);

str = oSPWeb.Title;
}
catch(Exception e)
{
//Handle exception, log exception, etc.
}
finally
{
if (oSPWeb != null)
oSPWeb.Dispose();

if (oSPSite != null)
oSPSite.Dispose();
}





Resources released of redirect page:



As below example,when invoke Response.Redirect there will throw the exception:ThreadAbortedException. then the finally will be run, the thread exception will be throw, can’t ensure the resource be released. So before to any invokes of Response.Redirect, ensure the the SPSite and SPWeb object released.




String str;
SPSite oSPSite = null;
SPWeb oSPWeb = null;

try
{
oSPSite = new SPSite("http://server");
oSPWeb = oSPSite.OpenWeb(..);

str = oSPWeb.Title;
if(bDoRedirection)
{
if (oSPWeb != null)
oSPWeb.Dispose();

if (oSPSite != null)
oSPSite.Dispose();

Response.Redirect("newpage.aspx");
}
}
catch(Exception e)
{
}
finally
{
if (oSPWeb != null)
oSPWeb.Dispose();

if (oSPSite != null)
oSPSite.Dispose();
}







This method is for using also.



Do not create the static SPSite and SPWeb object



The returned SPSite object which created calling SPSiteCollection.Add() method need to be released.



The returned SPSite object by SPSiteColleciton index SPSiteColleciton[] need to be released.



The SPSite object using foreach in SPSiteCollection.



Next is the recommendation methods:




void SPSiteCollectionForEachNoLeak()
{
using (SPSite siteCollectionOuter = new SPSite("http://moss"))
{
SPWebApplication webApp = siteCollectionOuter.WebApplication;
SPSiteCollection siteCollections = webApp.Sites;

foreach (SPSite siteCollectionInner in siteCollections)
{
try
{
// ...
}
finally
{
if(siteCollectionInner != null)
siteCollectionInner.Dispose();
}
}
} // SPSite object siteCollectionOuter.Dispose() automatically called.
}







SPWeb object returned by SPSite.AllWebs.Add need to release;



SPWeb object returned by SPWebColleciton.Add need to release;



By SPSite.AllWebs [] SPWeb object returned by the indexer needs to release;



SPWeb object by Foreach loop through the SPWebColleciton need to release;



SPWeb object over the open OpenWeb need to release;



SPWeb objects created by SPSite.SelfServiceCreateSite need to release;



SPSite.RootWeb do not need to release;



SPSite object returned by Microsoft.Office.Server.UserProfiles.PersonalSite need to release;



Recommended the development as follows:




void PersonalSiteNoLeak()
{
// Open a site collection
using (SPSite siteCollection = new SPSite("http://moss"))
{
UserProfileManager profileManager = new UserProfileManager(ServerContext.GetContext(siteCollection));
UserProfile profile = profileManager.GetUserProfile("domain\\username");
using (SPSite personalSite = profile.PersonalSite)
{
// ...
}
}
}







Here you can save by constructing a new SPSite ProfileLoader to improve performance




UserProfile myProfile = ProfileLoader.GetProfileLoader().GetUserProfile();
using (SPSite personalSite = myProfile.PersonalSite)
{
// ...
}







In particular, if you create web parts for the MySite, you can use PersonalSite without release:




IPersonalPage currentMySitePage = this.Page as IPersonalPage; 
if (currentMySitePage != null && !currentMySitePage.IsProfileError)
{
SPSite personalSite = currentMySitePage.PersonalSite; // Will not leak. // ...
}







The returned SPSite by GetContextSite not need to release




void SPControlBADPractice()
{
SPSite siteCollection = SPControl.GetContextSite(Context);
//siteCollection.Dispose(); do not to release
SPWeb web = SPControl.GetContextWeb(Context);
//web.Dispose(); do not to release
}







Within SPLimitedWebPartManager contains a reference to the SPWeb, need to release




void SPLimitedWebPartManagerLeak()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb web = siteCollection.OpenWeb())
{
SPFile page = web.GetFile("Source_Folder_Name/Source_Page");
SPLimitedWebPartManager webPartManager =
page.GetLimitedWebPartManager(PersonalizationScope.Shared);
webPartManaber.Web.Dispose();
} // SPWeb object web.Dispose() automatically called.
} // SPSite object siteCollection.Dispose() automatically called.
}







Microsoft.SharePoint.Publishing.PublishingWeb(SharePoint2007 only)



PublishingWeb.GetPublishingWebs will return  PublishingWebCollection, When use  the  foreach you should to invoke close() method to release every object.




void PublishingWebCollectionNoLeak()
{
using (SPSite siteCollection = new SPSite("http://moss"))
{
using (SPWeb web = siteCollection.OpenWeb())
{
// Passing in SPWeb object that you own, no dispose needed on
// outerPubWeb.
PublishingWeb outerPubWeb = PublishingWeb.GetPublishingWeb(web);
PublishingWebCollection pubWebCollection = outerPubWeb.GetPublishingWebs();
foreach (PublishingWeb innerPubWeb in pubWebCollection)
{
try
{
// ...
}
finally
{
if(innerPubWeb != null)
innerPubWeb.Close();
}
}
} // SPWeb object web.Dispose() automatically called.
} // SPSite object siteCollection.Dispose() automatically called.
}







Similarly, the returns PublishingWeb calling  PublishingWebCollection.Add need release;



3. In the event handler, you could use below method to avoid create new SPSite or SPWeb object.




// Retrieve SPWeb and SPListItem from SPItemEventProperties instead of 
// from a new instance of SPSite.
SPWeb web = properties.OpenWeb();//Here by properties.OpenWeb () returns the SPWeb not released;// Operate on the SPWeb object.
SPListItem item = properties.ListItem;
// Operate on an item.
Here by properties.OpenWeb () returns the SPWeb not released;







File name restrictions in SharePoint:



If you need to be deployed files or file folder to% ProgramFiles% \ Common Files \ Microsoft Shared \ web server extensions \ 14 \ TEMPLATE directory in actual combat,for security reasons,SharePoint Foundation is only able to read the file name with ASCII characters, numbers, underscores, periods, dashes (dashed) components of the name,Particular file name can not include two consecutive periods, for example, the following is to allow the file name:




AllItems.aspx



Dept_1234.doc



Long.Name.With.Dots.txt






The following are not allowed to name:




Cæsar.wav



File Name With Spaces.avi



Wow...ThisIsBad.rtf






The Processing to Large file and Large list:



Do not use SPList.Items, because this call will return all the sub-folder all the records, use the following method instead:



Add record: use SPList.AddItem, do not use SPList.Items.Add;



Query : Using SPList.GetItemById, does not apply SPList.Items.GetItemById;



Back to list all the records: Use SPList.GetItems (SPQuery query) and not SPList.Items, by the requirements to use conditions filters, just select the necessary fields to return, if the return results over 2000, the use of paging:




SPQuery query = new SPQuery();
SPListItemCollection spListItems ; string lastItemIdOnPage = null; // Page position.
int itemCount = 2000 while (itemCount == 2000)
{
// Include only the fields you will use.
query.ViewFields = "<FieldRef Name=\"ID\"/><FieldRef Name=\"ContentTypeId\"/>"; query.RowLimit = 2000; // Only select the top 2000.
// Include items in a subfolder (if necessary).
query.ViewAttributes = "Scope=\"Recursive\"";
StringBuilder sb = new StringBuilder();
// To make the query order by ID and stop scanning the table, specify the OrderBy override attribute.
sb.Append("<OrderBy Override=\"TRUE\"><FieldRef Name=\"ID\"/></OrderBy>");
//.. Append more text as necessary ..
query.Query = sb.ToString(); // Get 2,000 more items. SPListItemCollectionPosition pos = new SPListItemCollectionPosition(lastItemIdOnPage);
query.ListItemCollectionPosition = pos; //Page info.
spListItems = spList.GetItems(query);
lastItemIdOnPage = spListItems.ListItemCollectionPosition.PagingInfo;
// Code to enumerate the spListItems.
// If itemCount <2000, finish the enumeration.
itemCount = spListItems.Count;

}







Pages display:




SPWeb oWebsite = SPContext.Current.Web;
SPList oList = oWebsite.Lists["Announcements"];

SPQuery oQuery = new SPQuery();
oQuery.RowLimit = 10;
int intIndex = 1;

do
{
Response.Write("<BR>Page: " + intIndex + "<BR>");
SPListItemCollection collListItems = oList.GetItems(oQuery);

foreach (SPListItem oListItem in collListItems)
{
Response.Write(SPEncode.HtmlEncode(oListItem["Title"].ToString()) +"<BR>");
}

oQuery.ListItemCollectionPosition = collListItems.ListItemCollectionPosition;
intIndex++;
} while (oQuery.ListItemCollectionPosition != null);





Poor performance of the API is not recommended




SPList.Items.Count



SPList.Items.XmlDataSchema



SPList.Items.NumberOfFields



SPList.Items[System.Guid]



SPList.Items[System.Int32]



SPList.Items.GetItemById(System.Int32)



SPList.Items.ReorderItems(System.Boolean[],System.Int32[],System.Int32)



SPList.Items.ListItemCollectionPosition




Better performance of the recommended API




SPList.ItemCount



Create SPQuery, just return the required data



Create SPQuery, designated ViewFields, just return the required data



SPList.GetItemByUniqueId(System.Guid)



SPList.GetItemById(System.Int32)



SPList.GetItemById(System.Int32)



Using SPQuery paging



ContentIterator.ProcessListItems(SPList, ContentIterator.ItemProcessor, ContentIterator.ItemProcessorErrorCallout) (Microsoft SharePoint Server 2010 only)




Reference:



Release checking tool: SPDisposeCheck @ http://code.msdn.microsoft.com/SPDisposeCheck



http://msdn.microsoft.com/en-us/library/aa973248(office.12).aspx



http://msdn.microsoft.com/en-us/library/bb687949%28office.12%29.aspx

How to access the list data using javascript in ShaerPoint 2007

When we custom SharePoint, we maybe limited to access the server or we can’t deploy our solution.So many developments just could be completed in client. In SharePoint 2010, we could use the Client Object to resolve this problem, but in SharePoint 2007, how should we do?

This article will resolve this problem. We could use javascript to invoke the WebService to access the list data of SharePoint 2007.

First, we will download the package JavaScript SharePoint API. Then we should reference the JS. One is the core library:SPAPIcore.js, another is the package SPAPI_Lists.js which supply many interface you could invoke.

<script src="SPAPI_Core.js"></script>
<script src="SPAPI_Lists.js"></script>

The interface methods which we often use is: getListItems(listName, viewName, query, viewFields, rowLimit, queryOptions, webID)

Below is the requirement when we custom SharePoint : get the user’s information

function getCurrentUserStat()
{
var lists = new SPAPI_Lists('');
var items = lists.getListItems(
'UserInfo',
'',
'<Query><Where><Eq><FieldRef Name="ID"/><Value Type="Counter">' + _spUserId + '</Value></Eq></Where></Query>', // query
'<ViewFields><FieldRef Name="Department"/></ViewFields>',
1, // rowLimit
'' // queryOptions
);





We could handle the returned XML file to get the information:




if (items.status == 200)
{
var rows = items.responseXML.getElementsByTagName('z:row');
if (rows.length == 1)
{
var dep = rows[0].getAttribute('ows_Department');
return rows[0].getAttribute('ows_Department');
}
}







This method send the request is synchronization, If you want to know the property and values when you debug, you could view the returned result by alert(items.responseText).



Source: http://darrenjohnstone.net/2008/07/22/a-cross-browser-javascript-api-for-the-sharepoint-and-office-live-web-services/



You could contact to me by Email: jieiyan@gmail.com

Taking the BCS list offline in Sharepoint 2010

After you’ve created and secured your external list, SharePoint supports taking the list offline so that you can program against the cached data on the client from your external data source. BCS also offers a client-side object model to allow you to program against the cached data once you’ve taken it offline. in this post we’ll take the external list MyCustomers that we created offline and expose the list in SharePoint Workspace.

Here are few easy steps for how to do that

1. Open the MyCustomers list external list.
2. Click the List tab on the SharePoint ribbon. Note that in the “Connect & Export” group, you have different options available to you (for example, to sync with Outlook or SharePoint Workspace) to take the external list offline.
3. Click the “Sync to SharePoint Workspace” button, and you’ll be prompted to accept the Installation of a file to your local machine. Click Install to initiate the VSTO Package installation on your machine.
4. After the client-side package is installed, you will be prompted with a dialog that indicates the Office Customization was successfully installed. You can then open SharePoint Workspace to view the external list offline in SharePoint Workspace.

Programmatically Create Relation between lists in Sharepoint 2010

In this we will create two lists in SharePoint 2010 and setup the Relation between the lists by adding the lookup column. Please note that the belwo example is a console application.

string lookupFieldName = “RelatedField”;

using (SPSite site = new SPSite(“http://SpSite”))
{
using (SPWeb web = site.OpenWeb())
{
SPListCollection lists = web.Lists;
//Creating Parent list
Guid SourceListId = lists.Add(“Parent List”,”", SPListTemplateType.GenericList);
Console.WriteLine(“Parent List Done…”);

//Creating Child List
Guid TargetListId = lists.Add(“Child List”,”"
,SPListTemplateType.GenericList);
Console.WriteLine(“Child List Done…”);

SPList SourceList = lists[SourceListId];
SPList TargetList = lists[TargetListId];

SPFieldCollection Fields = TargetList.Fields;
//Adding a lookup Field in Child List
Fields.AddLookup(lookupFieldName, SourceList.ID, true);
Console.WriteLine(“Lookup Field Created”);

//Adding the Restrict behaviour
SPFieldLookup NewLookupField = Fields[lookupFieldName] as SPFieldLookup;
NewLookupField.Indexed = true;
NewLookupField.LookupField = “Title”;
NewLookupField.RelationshipDeleteBehavior = SPRelationshipDeleteBehavior.Restrict;
NewLookupField.Update();
Console.WriteLine(“Lookup field integrity enforced”);

//Adding Items in the List
SPListItem NewSourceItem = SourceList.Items.Add();
NewSourceItem["Title"] = “Parent Data”;
NewSourceItem.Update();
Console.WriteLine(“Source listitem created”);

SPListItem NewTargetItem = TargetList.Items.Add();
NewTargetItem["Title"] = “Child Data”;
NewTargetItem[lookupFieldName] = new SPFieldLookupValue(1, “Source Data”);
NewTargetItem.Update();
Console.WriteLine(“Parent listitem created”);
TargetList.Update();
SourceList.Update();
}
}



User Profile Synchronization Service Hanged at “Starting” in Sharepoint 2010

A lot of people have mentioned their user profile Synchronization service getting stuck on ‘starting’. You could try the below steps to come of the situation.

Firstly, stop the User Profile Synchronization service which was stuck at a status of ‘starting. To do this we will use our big boss PowerShell.
1. Get the GUID of the Profile Synchronization Service application using get-spserviceinstance . It will probably show a status of ‘provisioning’ in PowerShell.
2. Use cmdlet stop-spserviceinstance [Servuce-guid] to stop the Synchronization service.

Now, to troubleshoot the issue lets look at some things

1. After starting the User Profile Synchronization service, wait for 5-10 minutes before proceeding to the next step.

2. Run services.msc and verify that the Forefront Identity Manager Synchronization Service and the Forefront Identity Manager Service are running.These services are started automatically when the User Profile Synchronization service is started. It may take up to 10 minutes for these to start after starting the User Profile Synchronization Service. Do not start them manually. If they are started then stop the service using powershell and proceed to the next step.

2. Confirm that the user account performing this procedure is a member of the Farm Administrators SharePoint group. If you are using a Windows Server 2003 AD DS forest, the Service Administrator account must be a member of the Pre-Windows 2000 Compatible Access group for the domain with which you are synchronizing. Now restart the service.

Lastly, If Central Administration and the User Profile Synchronization service are provisioned on the same server, you will need to run IISReset on that server.

How to Check if file is attached to a list item in sharepoint 2010

A quick way to check if the user has attached a file to a list item that they just entered, is by using the PreSaveAction that runs on the “Save” button of the List item.
So whenever a user creates or edits and list item a javascript or jquery code can run in PreSaveAction() to check if the user has attached a document to the list item.

In code words here is how you do it -

//The below code uses jQuery Library for SharePoint Web Services and needs to be added into NewForm or Editform.aspx in a content editor webpart.

<script type=”text/javascript”>// <![CDATA[
var isAttached=0;

function PreSaveAction()
{
$(“input[name^='fileupload']“).each(function() {
if ($(this).val() != “”)
{
isAttached=1;
}
});

if(isAttached==1)
{
alert(‘File is attached.’);
}
else if(isAttached==0)
{
alert(‘No File is attached’);
}
}
// ]]></script>



Rich text editor (RTE) and PreSaveAction() in Sharepoint 2010/2007

As you may know PreSaveAction() is manly used to validate controls before the item is saved( new item or edit). Last week we had some requirement where we needed to get some values from the Rich text box on the save of NewForm.aspx page and parse through all the urls in the Rich text box’s text value.

In that case what we did was to execute our code in the PreSaveAction() function to get and parse through the RichTextbox’s value. Firstly, to find all the Html controls on the page we will use a handy function “getTagFromIdentifier“.
Some details about this function from this article are below.

This function finds the HTML element rendered by a given SharePoint FormField control. It takes the following parameters:

tagName – The name of the tag rendered in the form’s HTML
identifier – The string associated with the SharePoint type of the relevant field
title – The value of the relevant HTML tag’s “title” attribute, which also matches the field’s display name

Here’s a partial table of SharePoint column types and their corresponding “identifiers” and “tagNames”:

SharePoint Field Type       identifier       tagName

Single Line of Text                                           TextField                              input

Multiple Lines of Text                                      TextField                              input

Number                                                            TextField                                 input

Currency                                                          TextField                                 input

Choice (dropdown)                                 DropDownChoice                      select

Lookup (single)*                                            Lookup                                  select

So using this Function and the PreSaveAction() we wrote something like below to get to our RTe’s value

function PreSaveAction()
{
var _body = getTagFromIdentifierAndTitle(“input”,”TextField”,”Body”);
var _body = RTE_GetEditorDocument(_body.id);
var _bodyText = _body.body.innerText;
alert(_bodyText);
return true;
}

function getTagFromIdentifierAndTitle(tagName, identifier, title)
{
var len = identifier.length;
var tags = document.getElementsByTagName(tagName);
for (var i=0; i < tags.length; i++)
{
var tempString = tags[i].id;
if (tags[i].title == title && (identifier == “” || tempString.indexOf(identifier) == tempString.length – len)) {
return tags[i];
}
}
return null;
}



How to Get current loggedin user in Sharepoint using Javascript

This a script that gets the current logged-in user’s name from the welcome menu and populates it in a People Picker control.

Firstly, to run the function on page sharepoint load user spBodyOnLoadFunctionNames something like below.

_spBodyOnLoadFunctionNames.push(“AddCurrentUserToPP”);

Next add this script in any content editor webpart or just on your custom page.

function AddCurrentUserToPP()
{
var currentUser = GetUser();
if(currentUser != null)
{
var pp = GetPeoplePickerText(document.getElementById(‘PeoplePickerId’).parentNode);

//set the People picker field to current user
if(pp != null)
pp.innerText = currentUser;
}
}

function GetUser()
{
var tags = document.getElementsByTagName(‘a’);
for (var i=0; i < tags.length; i++)
{
if(tags[i].innerText.substr(0,7) == ‘Welcome’)
{
return tags[i].innerText.substr(8,tags[i].innerText.length);
}
}

}

function GetPeoplePickerText(container)
{
var result = “”;

var _divs = container.getElementsByTagName(“DIV”);
for(var k=0; k < divs.length; k++)
{
if(divs[k].id.indexOf(identifier) > 0 && divs[k].id.indexOf(“UserField_upLevelDiv”) > 0)
{
result = divs[k];
break;
// You can also access the text in the control by using the below
var innerSpans = divs[k].getElementsByTagName(“SPAN”);
for(var j=0; j < innerSpans.length; j++)
{ if(innerSpans[j].id == ‘content’)
{ return innerSpans[j].innerHTML;}
}

}
return result;
}



WSDL is not available by default for ASMX Web Services deployed to _VTI_BIN

Some SharePoint solution might require creating custom ASMX Web Services that operates within the context of SharePoint 2010, and there is a good description of how to create and deploy ASMX Web Service for SharePoint http://msdn.microsoft.com/en-us/library/ms464040.aspx.

However, after Web Service is built and deployed to _vti_bin folder you might experience one issue that <service>.asmx/?WSDL returns "<404> Page not found" error. This error is only specific to the _vti_bin folder, and service returns ?WSLD description if deployed to other folders (for example to _layouts).

The fix is adding "<protocols><add name="Documentation"/></protocols>" to the WebServices element of web.config of webservice.