share point customization tricks

63
SharePoint Customization Tricks: Part I By Ayman ElHattab January 20, 2009 This multipart series of articles is intended to help you get ramped up with SharePoint customizations. In this article we will see how to hide List View Toolbar Menu Items. This multipart series of articles is intended to help you getting ramped up with SharePoint Customization. It's about modifying the default SharePoint user experience, list forms customization, branding, skinning SharePoint portals, etc. When I looked around the “SharePoint Landscapeâ€, I noticed the lack of documented experiences in the SharePoint customization area and thus this multipart series of articles was born. Prerequisites First you need to have prerequisite skills in .NET Development and in particular ASP.NET Development, you should also have basic understanding of JavaScript, SharePoint and how to use it from the User Interface and of course you should have some experience in using the SharePoint customization tool (SharePoint Designer). Trick #1 : Hiding List View Toolbar Menu Items! I've gone through SharePoint projects on different scales; a common requirement among most of these projects is hiding some menu items that are implemented by default within the framework of SharePoint. The obvious

Upload: semalaiappan

Post on 10-Apr-2015

3.318 views

Category:

Documents


7 download

TRANSCRIPT

Page 1: Share Point Customization Tricks

SharePoint Customization Tricks: Part I By  Ayman ElHattab January 20, 2009 This multipart series of articles is intended to help you get ramped up with SharePoint customizations. In this article we will see how to hide List View Toolbar Menu Items.

 

This multipart series of articles is intended to help you getting ramped up with SharePoint Customization. It's about modifying the default SharePoint user experience, list forms customization, branding, skinning SharePoint portals, etc. When I looked around the “SharePoint Landscape†�, I noticed the lack of documented experiences in the SharePoint customization area and thus this multipart series of articles was born. PrerequisitesFirst you need to have prerequisite skills in .NET Development and in particular ASP.NET Development, you should also have basic understanding of JavaScript, SharePoint and how to use it from the User Interface and of course you should have some experience in using the SharePoint customization tool (SharePoint Designer).

Trick #1 : Hiding List View Toolbar Menu Items! 

    I've gone through SharePoint projects on different scales; a common requirement among most of these

projects is hiding some menu items that are implemented by default within the framework of SharePoint. The obvious choice from the SDK is HideCustomAction ! After digging through the web, I found out the following:

The "HideCustomAction" feature can merely hide the items which have been rendered through the

"CustomAction" feature framework such as Site Actions and Site setting.... etc. ECB (Context Menu) items are rendered by JavaScript from Core.js file so we can't hide them

via "HideCustomAction" feature. However, you can add a new menu item in the ECB menu through "CustomAction" feature and hide it again through The "HideCustomAction" feature. In other words," HideCustomAction" feature can be used to hide the ECB menu items that you created via CustomAction but can't be used to hide the out of the box menu items.

The ListViewWebPart menu items ( New menu, Upload menu, Actions menu,... etc ) are rendered through a class library as a web control from the Microsoft.SharePoint.dll so they

Page 2: Share Point Customization Tricks

can't be hidden through The "HideCustomAction" feature. Hmm, I thought of delving back into the world of JavaScript and I came up with some generic functions that can be used to hide any menu item in SharePoint and I decided to share them with the community. hideListViewToolbarItems("Edit in Datasheet","export to Spreadsheet","view rss feed","settings:create view"); function hideListViewToolbarItems(){        var menuItem;         var menuItemName;var menuItemIndex=-1;var menuItemNames=new Array("edit in datasheet","open with windows explorer","connect to outlook",'export to spreadsheet','view rss feed','alert me',"create column","settings:create view","list settings","document library settings","explorer view","all documents","all items","modify this view","view:create view","new document","new item","new folder","upload document","upload multiple documents");var menuItems = new Array("EditInGridButton","OpenInExplorer","OfflineButton","ExportToSpreadsheet","ViewRSS","SubscribeButton","AddColumn","AddView","ListSettings","ListSettings","View1","DefaultView","DefaultView","ModifyView","CreateView","New0","New0","NewFolder","Upload","MultipleUpload");              var allMenuItems = document.getElementsByTagName('ie:menuitem');

for(var i = 0; i < hideListViewToolbarItems.arguments.length; i++ ) {                                                                                     menuItemName= hideListViewToolbarItems.arguments[i].toLowerCase();          for (j=0;jif(menuItemNames[j]==menuItemName)                   {                                                                  menuItemIndex = j;                             break;                   }          }                     menuItem=menuItems[menuItemIndex];          for (var l = 0; l < allMenuItems.length; l++)          {                                     if(menuItemName.indexOf(":")!=-1)                   {                             menuItemName = menuItemName.split(":")[1];                   }                   if (allMenuItems[l].id.indexOf(menuItem)!=-1                     && allMenuItems[l].text.toLowerCase() == menuItemName )                   {                                               // For FireFox Compatibility                             var parentNodeOfMenuItem = allMenuItems[l].parentNode;                             parentNodeOfMenuItem.removeChild(allMenuItems[l]);                   }          }                  }

Page 3: Share Point Customization Tricks

}You can use this function to hide any menu items rendered in the ListViewWebPart toolbar which is used in the list view pages, just call the function and pass the menu item names ( comma separated ) as they appear in the toolbar ignoring the case. Only one exception to that when you need to hide "Create View" which appears twice one in "List Settings" and the other one in the view selector, in order to resolve this conflict just call the function as follows : hideListViewToolbarItems("settings:create view") or hideListViewToolbarItems("view:create view")

SharePoint Customization Tricks: Part II By  Ayman ElHattab January 26, 2009 In this article, I'll show you another two tricks for customizing the list form toolbar.

 

Introduction

This multipart series of articles is intended to help you getting ramped up with SharePoint Customization. It's about modifying the default SharePoint user experience, list forms customization, branding, skinning SharePoint portals, etc. In Part 1, I introduced a generic function that can be used to hide the list view toolbar menu items (e.g. New Item, Upload, Edit in Grid view, etc). If you haven't read it yet, I would encourage you do to that first. Today I'll show you another two tricks for customizing the list form toolbar.

Trick #2 : Hiding List Form Toolbar Menu Items!

Sometimes, you need to remove some items from the toolbar that appears at the top of DispForm.aspx.

Unfortunately, the "HideCustomAction" feature can merely hide the items which have been rendered through the "Custom Action" feature framework such as Site Actions and Site setting so let's take the same approach we took in Part 1 which is delving back into the world of JavaScript which I really find very handy when it comes to SharePoint customization.

The following function can be used to hide any toolbar item in dispform.aspx. Just call the function passing the names of the items comma separated (e.g. New Items, Alert Me, etc.). The function removes the items and of course the images rendered beside them (if found). Trick #3 will deal with where and how you can add the function to your list form.

Kindly note that the function is case sensitive so take care of the case the toolbar item names are rendered.

Page 4: Share Point Customization Tricks

       hideFormMenuItems("New Item", "Alert Me");        function hideFormMenuItems() {            var titleToHide = "";            var anchorTag;            var allAnchorTags = document.getElementsByTagName('a');            for (var i = 0; i < hideFormMenuItems.arguments.length; i++) {                titleToHide = hideFormMenuItems.arguments[i];                if (titleToHide != 'Alert Me') {                    for (var j = 0; j < allAnchorTags.length; j++) {                        anchorTag = allAnchorTags[j];                        if (anchorTag.title.indexOf(titleToHide) != -1) {                            anchorTag.parentNode.parentNode.parentNode.parentNode.parentNode.style.display = "none";                            anchorTag.parentNode.parentNode.parentNode.parentNode.parentNode.nextSibling.style.display = "none";                            break;                        }                    }                }                else {                    for (var k = 0; k < allAnchorTags.length; k++) {                        anchorTag = allAnchorTags[k];                        if (anchorTag.id.indexOf("SubscribeButton") != -1) {                            anchorTag.parentNode.parentNode.parentNode.parentNode.parentNode.style.display = "none";                            break;                        }                   }                 }            }            var allSpanTags = document.getElementsByTagName("span");            var spanTag;            var toolbarRow;            var lastCell;            for (var m = 0; m < allSpanTags.length; m++) {                spanTag = allSpanTags[m];                if (spanTag.id == 'part1') {                    toolbarRow = spanTag.childNodes[2].firstChild.firstChild;                    lastCell = toolbarRow.lastChild.previousSibling                    while (lastCell.style.display == 'none') {                        lastCell = lastCell.previousSibling;                    }                    if (lastCell.innerText == '|') {                        lastCell.style.display = 'none';                    }                    break;                }            }        }

Page 5: Share Point Customization Tricks

Trick #3 : Adding JavaScript through Content Editor Web Part!

The content editor web part gives you the ability to add any valid HTML on the web part page you place it and this surely includes <script> elements. The major advantage when using the content editor web parts that anyone with Designer permissions can do it quickly and easily.

Nice and Easy, let's do it, just go to Site Actions, Edit Page!!

Where the heck is Edit Page Menu Item?!!

Just like the old version, it's not available, I'm still not sure why they did that!

Trick #3 : Just append "&ToolPaneView=2" to the URL and you will have DispForm.aspx in the Edit Mode in your Browser.

Page 6: Share Point Customization Tricks

Add a content editor web part just below the web part that renders the list form and insert the JavaScript of Trick #2 as shown in the figure below. (It's preferable to mark the content editor web part as hidden).

Page 7: Share Point Customization Tricks

Exit the edit mode.

Page 8: Share Point Customization Tricks

Tremendous, we managed to hide "New Item" and "Alert Me".

What about renaming "Edit Item" to "Edit Program" and Removing "Delete Item" but leaving the small image (x)? That is what I'm going to cover in trick#4 in the next part!

SharePoint Customization Tricks: Part III By  Ayman ElHattab February 05, 2009 This multipart series of articles is intended to help you getting ramped up with SharePoint Customization.

 

IntroductionThis multipart series of articles is intended to help you getting ramped up with SharePoint Customization. It's about modifying the default SharePoint user experience, list forms customization, branding, skinning SharePoint portals, etc.In Part I, I introduced a generic function that you can use to hide the list view toolbar menu items (e.g. New Item, Upload, Edit in Grid view, etc.). In Part II, I showed you how to remove items from the list form toolbar. If you haven't read both posts yet, I would encourage you do to that first .After posting the previous articles, I received a lot of e-mails from SharePointers asking how to rename the items in the list form toolbar. That's why I decided to write Part 3 in the series. After I finished writing the article and taking some snapshots, another SharePointer asked me on MSDN Forums if it's possible to remove the Text while retaining the images, for instance, removing "Delete Item" while retaining the (X) rendered beside it. Today I'll show you to do both tasks by JavaScript.Trick #4 : Renaming List Form Toolbar Items!Sometimes, you need to rename some items in the toolbar rendered at the top of DispForm.aspx to match the List Name. For instance, you have a custom list named "Programs" that stores the courses offered by a university. It would be better to have "New Program" rather than the default "New Item" and "Edit Program" rather than "Edit Item". Sometimes, you just need to totally delete the text and just leave the images with a tooltip that explains the action performed on clicking them.Before :

Page 9: Share Point Customization Tricks

 After :

The following function can be used to achieve both tasks, just call the function passing the old and new names of the item. For instance if you need to rename "Add Item" to "Add Program", use renameFormMenuItems("Add Item","Add Program");. In case you need to remove the text and leave the image, call the function passing an empty string as the new name as follows: renameFormMenuItems("Delete Item","");.renameFormMenuItems("New Item","New Program");renameFormMenuItems("Edit Item","Edit Program");renameFormMenuItems("Delete Item","");

function renameFormMenuItems(oldName,newName){

var anchorTag;var allAnchorTags = document.getElementsByTagName('a');

if(oldName.length!=0){

for (var j = 0; j < allAnchorTags.length; j++){

anchorTag= allAnchorTags[j];

if (anchorTag.innerText.indexOf(oldName)!=-1){

anchorTag.innerText=newName; try {

if(newName.length!=0) {

anchorTag.parentNode.previousSibling.firstChild.

Page 10: Share Point Customization Tricks

firstChild.alt=newName;

} else {

anchorTag.parentNode.previousSibling.firstChild.

firstChild.alt=oldName; }

} catch(err) { }

}

}}

}Kindly note that the function is case sensitive so take care of the case the toolbar item names are rendered.Nice and easy, isn't it?Now a question is imposing itself, how can we use this function? The answer is the content editor web part; please refer to trick #3 in the previous article for more info.Now what about hiding the toolbar altogether? There are a lot of solutions that imply unghosting the pages from SharePoint Designer but I don't prefer them! Again, the solution is JavaScript, I've included in the zip file two functions one for renaming the toolbar items and the other for hiding the toolbar altogether! I'll be waiting for your feedback.

Site Definition in SharePoint By  Dhananjay Kumar January 08, 2009 This article will explain about Site Definition, why we do need custom site definition ?and how to create and deploy a custom site definition.

 

Site Definition Site Definitions are the foundations on which all sites and user templates are built.  Site Definition is collection ox XML and .aspx file. Site Definitions are predefined components needs to be included when a site was created in

SharePoint server. Site Definition contains information of Web Part , Lists, Features and navigation bars to be

included in the site.

Page 11: Share Point Customization Tricks

Customizing Portal Sites and other SharePoint sites using Site Definition is most appropriate for third party developer and SharePoint Administrator.

Site Definitions requires access to a file system of the Web Server. Server administrator must be also involved in deployment of Site Definitions.  Custom Site Definitions are Version and Upgrade independent.  Subsequent upgrades to SharePoint products  and technologies may overwrite  existing Site

Definitions. Using Custom Site definition exclude site from potential upgrade issues.  To avoid Unghosting  , Custom Site Definition is to be create. There are two options to create it

1. Create New Site Definition File : Either Start from Scratch and create files one by one  or Copy an existing Site Definition and modify it.

2. Copy a Site Definition and change it in Visual Studio:   We can make copy an existing site definition and modify it in visual studio to create new site definition.

The configuration of this site definitions are defined in XML file which is available in

C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\XML folder.

In the file system these definitions are available in C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\Site Templates.

Each of these site definitions consists a XML folder and a Home page (default.aspx).Steps to create custom Site Definition1. Log on as an administrator 2. Browse to C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\SiteTemplates. Copy STS folder-> Paste it at same place -> Rename it as TIGER.3. Open the folder Tiger4. Search for default.aspx 5. Open default.aspx in notepad. 6. Modify code. Here we need to add code for site definition. Default.aspx<%@ Page language="C#" MasterPageFile="~masterurl/default.master" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=12.0.0.0,Culture=neutral,P ublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Import Namespace="Microsoft.SharePoint" %> <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %><asp:Content ID="Content1" ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">

<SharePoint:EncodedLiteral runat="server" text="<%$Resources:wss,multipages_homelink_text%>" EncodeMethod="HtmlEncode"/> - <SharePoint:ProjectProperty Property="Title" runat="server"/>

Page 12: Share Point Customization Tricks

</asp:Content><asp:Content ID="Content2" ContentPlaceHolderId="PlaceHolderPageImage" runat="server"><IMG SRC="/_layouts/images/blank.gif" width=1 height=1 alt=""></asp:Content><asp:Content ID="Content3" ContentPlaceHolderId="PlaceHolderPageTitleInTitleArea" runat="server">

<label class="ms-hidden"><SharePoint:ProjectProperty Property="Title" runat="server"/></label></asp:Content><asp:Content ID="Content4" ContentPlaceHolderId="PlaceHolderTitleBreadcrumb" runat="server"/><asp:Content ID="Content5" ContentPlaceHolderId="PlaceHolderTitleAreaClass" runat="server"><style type="text/css">TD.ms-titleareaframe, .ms-pagetitleareaframe {

height: 10px;}Div.ms-titleareaframe {

height: 100%;}.ms-pagetitleareaframe table {

background: none;height: 10px;

}</style></asp:Content><asp:Content ID="Content6" ContentPlaceHolderId="PlaceHolderAdditionalPageHead" runat="server">

<META Name="CollaborationServer" Content="SharePoint Team Web Site"><script type="text/javascript">var navBarHelpOverrideKey = "wssmain";</script>

</asp:Content><asp:Content ID="Content7" ContentPlaceHolderId="PlaceHolderSearchArea" runat="server">

<SharePoint:DelegateControl runat="server"ControlId="SmallSearchInputBox" />

</asp:Content><asp:Content ID="Content8" ContentPlaceHolderId="PlaceHolderLeftActions" runat="server"></asp:Content><asp:Content ID="Content9" ContentPlaceHolderId="PlaceHolderPageDescription" runat="server"/><asp:Content ID="Content10" ContentPlaceHolderId="PlaceHolderBodyAreaClass" runat="server"><style type="text/css">.ms-bodyareaframe {

padding: 0px;}</style></asp:Content><asp:Content ID="Content11" ContentPlaceHolderId="PlaceHolderMain" runat="server">

<table cellspacing="0" border="0" width="100%"> <tr> <td class="ms-pagebreadcrumb">

<asp:SiteMapPath SiteMapProvider="SPContentMapProvider" id="ContentMap"

Page 13: Share Point Customization Tricks

SkipLinkText="" NodeStyle-CssClass="ms-sitemapdirectional" runat="server"/>

</td> </tr> <tr> <td class="ms-webpartpagedescription"><SharePoint:ProjectProperty

Property="Description" runat="server"/></td>

</tr> <tr>

<td> <table width="100%" cellpadding=0 cellspacing=0 style="padding: 5px 10px 10px

10px;"><tr><td valign="top" width="100%" colspan="3"><WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Top" Title="loc:Top" /></td></tr>

<tr> <td valign="top" width="70%">

<WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Left" Title="loc:Left" />

&nbsp; </td> <td>&nbsp;</td> <td valign="top" width="30%">

<WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Right" Title="loc:Right" />

&nbsp; </td> <td>&nbsp;</td> </tr> </table></td>

</tr> <tr> <td valign=†�top†� width=†�100%†� colspan=†�3†�> <WebPartPages:WebPartZone runat="server" FrameType="TitleBarOnly" ID="Bottom" Title="loc:Bottom" /> </td> </tr>

</table></asp:Content>7. Register new site definition to SharePoint.8. Open the folderC:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\XML

Page 14: Share Point Customization Tricks

9. Copy the file WEBTEMP.XML and save it as WEBTEMPTIGER.xml. here make a note that , we need to append name of folder which we created in step 2 ( in this case it is tiger) to WEBTEMP. So here name would be WEBTEMPTIGER.xml 10. Open WEBTEMPTIGER.XML in notepad and replace it with following content.<?xml version="1.0" encoding="utf-8"?><!-- _lcid="1033" _version="12.0.4518" _dal="1" --><!-- _LocalBinding --><Templates xmlns:ows="Microsoft SharePoint">

<Template Name="TIGER" ID="10009">

<Configuration ID="1" Title="Tiger Definition" Hidden="FALSE" ImageUrl="/_layouts/images/Eye.GIF" Description="Tiger Site." DisplayCategory="Custom" AllowGlobalFeatureAssociations="False" > </Configuration>

</Template></Templates>Make sure here ID should be greater than 10000. It must not collide with id of any other Site Definition.11. Restart IIS. Go to Start->Run->IISRESET12. Now you would be able to see this Site Definition inside Custom category.

Modifying Spell Check for SharePoint Server 2007

IntroductionSharePoint is Microsoft's server dedicated to the interchange of information and thus a system where writing is a critical component. As with other Office family products, Microsoft Office SharePoint Server (MOSS) provides tools to check and correct the orthography in texts. The service is used in some default components of MOSS, allowing developers to utilize it in custom software, such as WebParts or specialized pages.

Page 15: Share Point Customization Tricks

The SharePoint Object Model offers spell check as a WebService to control the orthography in different languages, providing suggestions and alternatives to correct errors. It's important to point out that the service is not equal to the system used by other Office products. Consequently—as an on-line server—the SharePoint system is less advanced, and provides limited functionality in contrast to the default spell check of Word or Excel; for example, there is no possibility to check grammar nor does it offer a thesaurus.MOSS uses spell check in various locations; for example, in each List where there are Text Fields there is a "Spelling" button in the horizontal tools bar. When you click the button, a popup window appears, allowing you to loop through the words on the page, making a comparison with the internal dictionary and displaying words with errors, together with suggestions to rectify them.

(Full Size Image)Figure 1: SharePoint List with the Spelling button and popup windowThe same window allows users to select the Language and Dialect for the corrector (the configured default Language is initially used). The corrector only compares words with the internal dictionary, without grammar or syntax corrections. Another disadvantage is that it is not possible to add new words to the dictionary; to circumvent that situation, a list of words can be created that will be ignored by the corrector; in fact, it's a specially designed dictionary.WebServiceAll the corrector's functionality is available as a default Microsoft Office SharePoint Server (MOSS) WebService. The "SpellCheck.asmx" WebService has three input parameters:

chunksToSpell: An array of strings with the texts to check declaredLanguage: An integer that gives the Language Identifier to be used by the checker. This

Identifier is not the same as that used by SharePoint for its internal configuration; the values can be found on the Microsoft site http://msdn2.microsoft.com/en-us/library/0h88fahh.aspx; use the value of the column "Decimal value"

useLad: A Boolean that indicates whether the spell check should detect the MOSS default language

At first glance, the WebService is very straightforward to apply following a simple sequence: create a reference, give the service user credentials, configure the input parameters, and execute the service. Unfortunately, the MOSS implementation has two crucial errors that hamper its use.

Page 16: Share Point Customization Tricks

First, if the parameter "useLad" is employed in such a way that spell check uses the default MOSS language, the checker will apply the Language Identifier of MOSS, not the target Language Identifier to be checked. This is not a problem in English, because the two Language Identifiers are the same (1033), but in other languages it is always different. For example, in Spanish the WebService will use 3082 (MOSS Language Identifier for Spanish) instead of 1034 (Language Identifier for Spanish Spell Check). Consequently, the corrector never provides accurate results in languages other than English.To avoid this problem, declare the "useLad" parameter as false and give the correct Language Identifier in the "declaredLanguage" parameter. The downside to this workaround is that you always need to use a constant identifier or you must create a lookup table with the necessary logic to link the MOSS Language Identifier to the spell check Language Identifier.The second problem may be more serious. Because the WebService has irregularities in the code, vocabulary suggestions are not provided. To resolve this problem, it is obligatory to call the WebService using the methods of the class "HttpWebRequest" from the NameSpace "System.Net", creating the SOAP envelope and XML query manually, as outlined in the following paragraphs.In the source code where the WebService will be called, create references ("using" in CSharp) to System, System.IO, System.Net, System.Text and System.Xml. The following code lines call the WebService using the HttpWebRequest class:

StringBuilder myStringBuilder = new StringBuilder(EnvelopeSoap);myStringBuilder.Insert(myStringBuilder.ToString(). IndexOf("</soap:Body>"), MyQuery);

XmlDocument EnvelopeSoapXml = new XmlDocument();EnvelopeSoapXml.LoadXml(myStringBuilder.ToString());

HttpWebRequest myQueryWeb = (HttpWebRequest)WebRequest.Create(UrlChequerWS);myQueryWeb.UseDefaultCredentials = true;myQueryWeb.Headers.Add("SOAPAction", AccionSoap);myQueryWeb.ContentType = "text/xml;charset=\"utf-8\"";myQueryWeb.Accept = "text/xml";myQueryWeb.Method = "POST";

using (Stream myStream = myQueryWeb.GetRequestStream()){ EnvelopeSoapXml.Save(myStream);}IAsyncResult ResultAsync = myQueryWeb.BeginGetResponse(null, null);ResultAsync.AsyncWaitHandle.WaitOne();

string ResponseSoap = string.Empty;using (WebResponse ResponseWeb = myQueryWeb.EndGetResponse(ResultAsync))using (StreamReader myStreamReader = new StreamReader(ResponseWeb.GetResponseStream())){ ResponseSoap = myStreamReader.ReadToEnd();}

In the code, create a StringBuilder that contains the SOAP call to the WebService. The SOAP envelope is directly added by using the following syntax:

Page 17: Share Point Customization Tricks

static string EnvelopeSoap = @"<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'

xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'> <soap:Body></soap:Body> </soap:Envelope>";

Then, immediately before closing the envelope, add the XML query with the following syntax:

static string MyQuery = @"<SpellCheck xmlns= 'http://schemas.microsoft.com/sharepoint/publishing/spelling/'> <chunksToSpell> <string>This rou</string> <string> has an error </string> </chunksToSpell> <declaredLanguage>1033</declaredLanguage> <useLad>false</useLad> </SpellCheck>";

There are two strings in the query that need to be adjusted, namely "This rou" and "has an error", the Language Identifier is declared (1033) and the MOSS Language Identifier must be blocked with the code; useLead=false. As stated earlier, at this point you need to define the spell check Language Identifier if you are using a language other than English.After the creation of the envelope and the query in a string, they are converted to a XmlDocument that can be used in the service call. The object "myQueryWeb" (of the "HttpWebRequest" type) is created using as input parameter the URL of the spell check WebService:

static string UrlChequerWS = "http[s]://ServerName/_vti_bin/SpellCheck.asmx";

The object receives the default credentials of the user, the content type, the type of the method to be used, and finally, the form to send the envelope. The SOAP action type is added to the header in the following manner:

static string AccionSoap = "http://schemas.microsoft.com/sharepoint/publishing/ spelling/SpellCheck";

With this action, the envelope is assigned to the WebService call and using the interface, IAsyncResult, the anticipated result is asynchronous; this avoids a delay in the functioning of SharePoint while awaiting the responseFinally, the call to the WebService is executed and the results come back in the form of a "WebResponse" object that is converted to a "StreamReader" that needs to be interpreted; the final result is a XML string, "ResponseSoap". The response of the example is in the form:

<?xml version="1.0" encoding="utf-8" ?>- <soap:Envelope xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema">- <soap:Body>

Page 18: Share Point Customization Tricks

- <SpellCheckResponsexmlns="http://schemas.microsoft.com/sharepoint/publishing/spelling/">- <SpellCheckResult><errorCode>Ok</errorCode><detectedLanguage>1033</detectedLanguage>- <spellingErrors>- <SpellingErrors><chunkIndex>0</chunkIndex>- <flaggedWords>- <FlaggedWord><word>rou</word><type>UnknownWord</type><offset>3</offset></FlaggedWord></flaggedWords></SpellingErrors></spellingErrors>- <spellingSuggestions>- <SpellingSuggestions><word>rou</word>- <sug><string>roue</string><string>rout</string><string>roux</string><string>roe</string><string>row</string><string>rob</string></sug></SpellingSuggestions></spellingSuggestions></SpellCheckResult></SpellCheckResponse></soap:Body></soap:Envelope>

In the SOAP response, note that the corrector—in the first string (chunkIndex=0)—has identified an unknown word (FlaggedWord-word=rou), that probably has an error in the third character (offset=3). The suggestions section indicates that the unidentified word has six possible corrections in the dictionary. The second string is not found in the response, signifying it is accepted by the corrector.The remaining code implementation is elemental and can be used in each SharePoint component (WebParts, WebControls, Web pages, and so forth). The last task is to extract the relevant information from the XML response and present it to the user in the desired way.Spell Check Default ComponentsIt is not necessary to use WebService spell check directly, as indicated in the last section; it is also possible to use the existing SharePoint default infrastructure for this purpose. The default implementation of spell check for MOSS is based in one ASPX page and two JavaScript files:

Page 19: Share Point Customization Tricks

SpellChecker.aspx: (C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\SpellChecker.aspx) contains the Web page used to show words with errors and the suggestions (shown in Figure 1)

SpellChecker.js: (C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\3082\SpellChecker.js) contains the routines to call the WebService, show and rectify words with errors

SpellCheckerEntirePage.js: (C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\3082\SpellChecker.js) works as a link between the aspx page and the routines of the JavaScript in SpellChecker.js.

In the event the Language cannot be detected, the ASPX page initially shows a menu to select it from the available Languages List.The default MOSS corrector page can be initiated from each ASPX page as well. To view the process, create a new file with the .aspx extension ("spellcheck.aspx", for example) in the directory "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS\". Open the file with any ASCII text editor (Notepad) and add a reference to the SharePoint assembly:

<%@ Register Tagprefix="SharePoint"Namespace="Microsoft.SharePoint.WebControls"Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral,PublicKeyToken=71e9bce111e9429c" %>

Then, create references to the files with the JavaScripts:

<SharePoint:ScriptLink language="javascript" name="core.js" runat="server" /><SharePoint:ScriptLink language="javascript" name="SpellCheckEntirePage.js" runat="server" />

And a JavaScript section to call Spell Check:

<script language="javascript" type="text/javascript"> function CheckSpell() { SpellCheckEntirePage('/_vti_bin/SpellCheck.asmx', '/_layouts/SpellChecker.aspx'); }</script>

Finally, create the content controls where the user can write a text to be checked. In the example, it is one text box, but as many as are required can be created and spell check will loop through all of them scanning for errors. Use the syntax:

Some text to check &nbsp;&nbsp;<input type="text" name="SomeText"><br><br>

The button at the end will call the JavaScript and spell check:

<a href="javascript:" onclick="CheckSpell();">Spell Checker</a>

Call the aspx from MOSS using the URL (http[s]://ServerName/_layouts/ spellcheck.asp). After clicking the button, a popup window will appear, showing the incorrect words and the correction suggestions:

Page 20: Share Point Customization Tricks

(Full Size Image)Figure 2: ASPX custom page using default spell checkWith the preceding code, all the texts found on the page will be scanned. If you want to exclude any of the text from correction, use the attribute "excludeFromSpellCheck" in the HTML syntax. For example, to create a text box controlled by the server where no spell check is desired, use:

<asp:TextBox ID="TextBoxNoControled" runat="server" excludeFromSpellCheck="true" />

Note: The "excludeFromSpellCheck" attribute can be used in a similar way in client-side controls by using HTML code.If necessary, it also is possible to modify the files SpellChecker.aspx, SpellChecker.js and/or SpellCheckerEntirePage.js, but it is not recommended or effective because any future Microsoft Service Pack can revert the files to the original state.

Page 21: Share Point Customization Tricks

Dictionary ModificationsMOSS has default correction dictionaries for each supported language, but it is impossible to modify them. However, it is possible to add words in such a way that they are not identified as errors. The following process creates a type of custom dictionary for these words:

1. Create a new Document Library, "Spelling," at the root of the Portal. 2. Create a text file, "Custom Dictionary.txt," locally. 3. Add all the words that should not be recognized as spelling errors in the text file, one word per

line. 4. Upload the text file to the newly created Library above.

Only one "Custom Dictionary" Document Library is possible for each site collection; the names of the Library and text file need to be exactly as indicated and the Library must be located at the root of the Portal.ConclusionA valuable feature of SharePoint 2007 is the introduction of an online spell check program. The system is presented as a WebService, but the feature has some errors that need workarounds to function properly.Spell Check is a default component of Microsoft Office SharePoint Server (MOSS) but is not available in Windows SharePoint Services (WSS). The system is a welcome adaption and covers the supported SharePoint Languages. It is effective for detecting orthography errors and provides correction suggestions; however, the downside is that it lacks a grammar and a thesaurus and the dictionaries cannot be modified.The default window of the corrector can be used in custom components inside SharePoint, as ASPX pages, with the inclusion of a few lines of code. Finally, although the dictionaries cannot be modified, it is possible resolve this inadequacy by creating a list of words to be excluded from Spell Check control.

Code Practices - getting\setting values from\to the lookup and the hyperlink fields How to get data from a field that is a lookup? how to set data into a field that is a hyperlink?

I don't believe I didn't write about this yet. It's so common!

For both cases, sharepoint object model exposes classes to help us get or set the data we want. These are the SPFieldLookupValue and the SPFieldUrlValue.

Example 1: Set the url field of a link

Use the SPFieldUrlValue class to create an object that holds the url to link to, and the title to display:

SPList list = web.Lists["Links"];SPListItem newLink = list.Items.Add();SPFieldUrlValue value = new SPFieldUrlValue();value.Description = "test";value.Url = "http://www.microsoft.com/sharepoint";newLink["URL"] = value;newLink.Update();

Example 2: Get the url field of a link

Use the SPFieldUrlValue class to create an object that gets the url and description:

Page 22: Share Point Customization Tricks

SPList list = web.Lists["Links"];SPListItem existingLink = list.Items[0];SPFieldUrlValue value = new SPFieldUrlValue(existingLink["URL"].ToString());string linkTitle = value.Description;string linkURL = value.Url;

Example 3: Set the value of a lookup field for a known title and ID

In the following example I am using SPFieldLookupValue to set the value of a lookup field ("Group Name") to item "Program Operations", whose ID is 14:

SPList list = web.Lists["Branches"];SPListItem newBranch = list.Items.Add();newBranch["Title"] = "A New Branch";SPFieldLookupValue newValue = new SPFieldLookupValue(14,"Program Operations");newBranch["Group Name"] = newValue;newBranch.Update();

Example 4: Get the value of a lookup field from an item

Here I am reading the value of the group name field (which is a lookup field in the branches list):

SPList list = web.Lists["Branches"];SPListItem existingBranch = list.Items[0];SPFieldLookupValue group = new SPFieldLookupValue(existingBranch["Group Name"].ToString());int lookedUpItemID = group.LookupId;string lookedUpItemTitle = group.LookupValue;

Tuesday, November 25, 2008How to copy attachments from one list item to another The microsoft support article for WSS 2 shows us how to download attachments from a list item. Basically, the attachments for a list item are stored as SPFile objects under a hidden folder in the list where those attachments are (a folder called "Attachments") - where each list item that has an attachment has its own folder - with the ID of the item being the folder's name.

Here is a code sample for a function to copy attachments from one item to another.

private void CopyAttachments(SPListItem sourceItem, SPListItem targetItem){

Page 23: Share Point Customization Tricks

try { //get the folder with the attachments for the source item SPFolder sourceItemAttachmentsFolder = sourceItem.Web.Folders["Lists"].SubFolders[sourceItem.ParentList.Title].SubFolders["Attachments"].SubFolders[sourceItem.ID.ToString()]; //Loop over the attachments, and add them to the target item foreach (SPFile file in sourceItemAttachmentsFolder.Files) { byte[] binFile = file.OpenBinary(); targetItem.Attachments.AddNow(file.Name, binFile); } } catch { } finally { sourceItem.Web.Dispose(); }}

Get a user from a list item:

To get a user we use the SPFieldUserValue class, which accepts a SPWeb and a string value as parameters. The string value is the value from the list that contains the ID and the account name. Once we have that, we can use the SPFieldUserValue to get information about the user.

Example:

 using (SPSite site = new SPSite("http://portal"))            {                using (SPWeb web = site.OpenWeb())                {                    SPList list = web.Lists["Example For Users"];                    SPListItem item = list.Items[0];                     SPFieldUserValue userValue = new SPFieldUserValue(web, item["User Name"].ToString());                    if (userValue.User.LoginName == web.CurrentUser.LoginName)                    {                        //do something!                    }                }            }

Page 24: Share Point Customization Tricks

Adding a value to a user field

This is the same, but in reverse. We use the same class (SPFieldUserValue ) and give it the values we want for the user.

using (SPSite site = new SPSite("http://portal"))            {                using (SPWeb web = site.OpenWeb())                {                    SPList list = web.Lists["Example For Users"];                    SPListItem item = list.Items[0];                     SPFieldUserValue userValue = new SPFieldUserValue(web, web.CurrentUser.ID, web.CurrentUser.LoginName);                    item["User Name"] = userValue;                    item.Update();                }            }Wednesday, August 29, 2007Web Services on SharePoint - making F5 Work I was getting many questions on best practices to write custom web services for sharepoint, and I wanted to write an article about it for some time now. Also, I just had a chance to fiddle around with making F5 (run from visual studio into debug mode) work for a web service I am testing on a sharepoint site. This involved a few tricks, so I am documenting them:

Note - only do this on your development box!

Note - code lines marked in red means that you will need to change the values to your environment values.

I hold that the best practice is not to use the web service as a web application template (that is the default with visual studio) because when deploying to sharepoint, you'r web service usualy needs to sit in the layouts folder, and you do not want to deploy your code files there. You also don't want to use the visual studio publishing mechanism that uses the frontpage server extensions.The alternative is creating a web service that is deployed as an asmx file to the layouts folder, pointing to a DLL that is deployed to the GAC. That makes it safe and secure, and easier to deploy and track versions.

Step 1 - Create a Web Service (DLL) Project

To create the web service, use Visual Studio 2005, and click "File-New-Project" and select ASP.NET Web Service Application.

If you don't have that project type installed, you may need to change the installed features of Visual Studio on your machine. The good think about this project type is that it creates a web service as a DLL and an asmx and not as a web site.

Page 25: Share Point Customization Tricks

After the project is created, change the file names, namespace and assembly names as needed (make sure the namespace of the webservice attribute is changed - you don't want "http://tempuri.org/" as your namespace...) and most importantly - sign the assembly as strong name (right click the project, properties, signing tab, sign the assembly).

Now we have to find out the key that was given to the assembly when it was signed. To do that you must first build the web service (I use ctrl-shft-B, or right click the project and select build) and then either drag and drop the DLL to the assembly folder, right click and get the key:

Or you can run a command line from the visual studio SDK (start-programs-visual studio 2005-visual studio tools-Visual Studio 2005 Command Prompt) and typesn -T "c:\temp\WebService1\WebService1\bin\WebService1.dll"

Once we have the public key token, we can change the web service's asmx file to use the DLL that will be deployed to the gac. Right click the service1.asmx file and choose "View Markup". You need to change the markup to point to the DLL that will be in the GAC, so this is the format you need to use:

<%@ WebService Language="C#" Class="WebService1.Service1, WebService1, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=db33ac6baa259170" %>

Expalantion:1.

The "WebService1.Service1" part is the "namespace dot classname" of your code. To get that, you will need to open your .cs file, and copy the namespace you are using, add a dot after it, and add the class name.

2. The "WebService1" (after the comma) is the name of the DLL that you may have set in the project properties under the "application" tab (the "assembly name")

3. The public key token is the key we got earlier.

Note - I am not sure if this is needed, but I also registered my web service as a safe control in the web.config, before I used any sharepoint code. It's worth checking if this is required or not, and I will update if I have time to test.

Step 2 - Setting up the Build Events

While in the project's properties, switch to the "Build Events" tab. Paste the following in the "post-build event command line" box:

"c:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe" /i "$(TargetPath)" /f

copy "$(ProjectDir)\*.asmx" "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS"

"C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\RecycleAppPools.vbs"

"c:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\disco" http://localhost/_layouts/service1.asmx /o:"C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS"

Explanation:

Page 26: Share Point Customization Tricks

1.The first line puts the DLL in the GAC.

2.The second line copies the web service asmx file to the layouts folder. You should make sure your projects do not create same names for asmx files, or they will overwrite eachother!

3.The third line recycles the application pools. I am doing this with a vbs file that I have written, and placed in the 12 hive's "\bin" folder for my comfort. Here are the contents of the file:

Set locator = CreateObject("WbemScripting.SWbemLocator")

Set Service = locator.connectserver(strServer, "root/MicrosoftIISv2")

Set APCollection = Service.InstancesOf("IISApplicationPool")

For Each APInstance In APCollection

APInstance.Recycle

Next

echo "Recycle Complete."

4.The last line build a discovery file for the web service in the layouts folder. if you installed your visual studio 2005 in a different location, you will need to change the folder path to the disco.exe file, and if you changed the name of the asmx (or if you have more than one) you will need to modify that as well. You will also want to change the url to point to a sharepoint site on your machine if you are not using the "localhost" header. In my case, I use the header "portal", so I change is to "http://portal".

Step 3- Change the F5 behavior

To change what happens when you press F5, switch to the "Web" tab, and change the start url to the url to the web service (I use http://portal/_layouts/service1.asmx), then change the "use IIS web server" and change the project url to the rool sharepoint url (I use "http://portal") and tick the "override application root URL and type the same url as the project url:

Last Step - set up your web.config to allow debugging

If you want F5 to work, and have visual studio debug the web service when you press it, the sharepoint web.config should be changed to allow debugging. To do that, you will need to open the web.config file for the virtual server you are using (in my case "http://portal" - which means the web.config is under "c:\Inetpub\wwwroot\wss\VirtualDirectories\portal80\web.config") and find the "<compilation>" tag, and set the attribute "debug" to true:Wednesday, August 01, 2007Modifying Search to Add a Send Link By Email link

My customer wanted a "send link by email" next to each search result item. "Easy", I thought and went

Page 27: Share Point Customization Tricks

ahead to edit the xslt for the search results. But I found out a problem with links that had spaces in them - the link in outlook would appear broken. To solve this, I had to write some simple javascript, and the process is described below.

Problem:If you want a mailto link (href="mailto") that has in the body a link to a file, you may get a link like this:

href="mailto:body=http://server/site/library/this is my file.doc"

This is a problem, because the file name contains spaces. The email will open with a broken link in it's body:

Solution:

Luckily, SharePoint has a javascript functions that solves that for us. They are "escapeProperly" and "navigateMailToLink". What I did is create a function of my own in the page:

function SendEmailWithLink(link){ var link = "mailto:?body=" + escapeProperly(link); navigateMailToLink(link); return false;}

And my link is:

href="#nowhere" onclick="javascript:SendEmailWithLink('');"

This article would'nt be complete if I didn't explain why I did this - this if for the search results xslt - the idea was to add a "send link by email" button next to each search result. The solution - change the xslt to include the script above, and a button like this:

<a title="E-mail a Link" href="#nowhere"> <xsl:attribute name="onclick"> javascript:SendEmailWithLink('<xsl:value-of select="$url"></xsl:value-of>'); </xsl:attribute> <img border="0" src="/_layouts/images/ICMSG.GIF"/> </a>

We also added other actions (I will try to get them published) and came up with the following for each result item:- - - 2 0 0 7

-------------------------------------------------------------------------------------------------------------------------------

Page 28: Share Point Customization Tricks

Developing a SharePoint 2007 Feature...  a step by step tutorial.

I have worked with SharePoint for a while now, mostly mostly writing code for integration scenarios, where data needs to be "pulled" or "pushed" into SharePoint involving other enterprise software applications. SharePoint 2007 Features are basically a mechanism to extend SharePoint in any way you need. Mike Ammerlaan wrote a brief and concise technical article describing features:  I will try to describe how to develop a SharePoint 2007 Feature from zero. In this case our feature will handle the event that SharePoint usually handles when a file gets added to a Document Library. When a user uploads a new document to a Document Library, we want to run some custom code. In our example we will simply be creating a text file on the desktop containing data from the file that fired such event. Obviously you would want to make it something meaningful, like pass that data to an external workflow application or do womething with that document, but this is just an example.  1. Setting up our project Launch Visual Studio 2005 and create a new Class Library project. File > New Project > Class Library

 Name it SharePointEventHandler and let Visual Studio create the project files for you in the Solution Explorer.: Add a reference to the SharePoint Services API assembly. Right-click in your solutions explorer on the reference folder and select Add reference

 The list of available .NET assemblies shows up

Page 29: Share Point Customization Tricks

 Scroll almost all the way to the bottom and select Windows SharePoint (r) Services, Version 12.0.0.0 Go back to the Solution Explorer and rename you class1.cs file to ItemEventreceiver.cs

 2. Writing our class with our custom codeWe will be using the WSS API and we will be writing a text file, so we need to write these two directives using System.IO;using Microsoft.SharePoint;Rename your class name to ItemEventReceiver and inherit from SPItemEventReceiver as shown below:

Page 30: Share Point Customization Tricks

 Declare a StreamWriter object:

 Now we will write the method we want to override so we can run our own custom code. In this case, the event we want to trap is the ItemAdded event (after someone adds an item).

The ItemAdded method is the one that will be called and the properties parameter contains detailed information about the file that fired this event.Our intent is that a text file is written to our desktop and we will write to it with data coming from the Properties parameter.Finish your class as shown below.ItemEventReceiver.cs codeusing System; using System.Collections.Generic; using System.Text;

using System.IO; using Microsoft.SharePoint;

Page 31: Share Point Customization Tricks

namespace SharePointEventHandler {   public class ItemEventReceiver : SPItemEventReceiver   {     private StreamWriter SW;

    public override void ItemAdded(SPItemEventProperties properties)     {       base.ItemAdded(properties);             try       {        //Set this path below to suit your needs...        SW=File.CreateText(@"[...]\Desktop\eventoutput.txt");

        SW.WriteLine("CurrentUserId: "  + properties.CurrentUserId.ToString());        SW.WriteLine("BeforeUrl: "         + properties.BeforeUrl.ToString());        SW.WriteLine("SiteId: "              + properties.SiteId.ToString());        SW.WriteLine("ListId: "               + properties.ListId.ToString());        SW.WriteLine("ListItem: "           + properties.ListItem.ToString());        SW.WriteLine("ListTitle: "            + properties.ListTitle.ToString());        SW.WriteLine("ReceiverData: "   + properties.ReceiverData.ToString());        SW.WriteLine("WebUrl: "           + properties.ToString());

        SW.Close();       }             catch (Exception ex)        {          properties.Cancel = true;         properties.ErrorMessage = ex.Message;         throw ex;        }        finally        {          this.SW.Dispose();        }       }    } } * Note that the catch block contains two lines that will have no effect, because this would happen after the file was added, so we cannot cancel it anymore nor display an error message. These two lines would be used if we were trapping the ItemAdding event, which fires (asynchroneously) before the item is added. 3. Signing and Installing our assembly into the GACThe main piece of our feature is our class and once compiled, it needs to be installed in the GAC. In order for it to be able to be installed in the GAC, it also needs to be strong named. Several steps to take, but in VS2005 it is actually hardly any effort at all.

Page 32: Share Point Customization Tricks

In your Solutions Epxlorer, double click on Properties (My Project in VB) and then select Signing. From the combobox, select New.

 This will launch a dialog as shown below

 Type in SharePointEventHandler for your Key File name and uncheck the protection feature. Click OK.This automatically signs our assembly when we compile. What we still need to do is register our assembly into the GAC and we do that with Post-build events. In the same page, on the left hand, look for Build Events (In VB it is under Build and then there is a button called events)In the text area type (exactly as you see it): "C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\GacUtil.exe" -i "$(TargetPath)"

 Click on OK and then build your solution. In your Output window you should see the progress of the build and if correct, you should see a line that says: "Assembly successfully added to the GAC".Now, browse to C:\Windows\Assembly and look for a dll called SharePointEventHandler. Once found, right-click on it and check its properties.

Page 33: Share Point Customization Tricks

 Remember or copy the Public Key Token to a text file, because we will need this later. 4. Define our resource filesSharePoint Features require not just a compiled dll, but also a set of corresponding files. These files are stored in the "12" HIVE  on the SharePoint server. The file structure already exists and we will simply be adding files that are used by our feature to it.Create a folder structure as shown below in your Solutions Explorer:

 In this SharePointEventHandler folder create the following two blank xml files:

Page 34: Share Point Customization Tricks

 Open the feature.xml file and replace any code with the following:<Feature    Id=""    Title="SharePoint EventHandler Feature"    Description="This feature will blah blah blah [..]."      Scope="Web"    Hidden="FALSE"   AlwaysForceInstall="TRUE"   ImageUrl="components.gif" xmlns="http://schemas.microsoft.com/sharepoint/">

   <ElementManifests>      <ElementManifest Location="elements.xml" />   </ElementManifests></Feature> We will need to fill in a valid GUID for the Id (left intentionally blank). In VS2005, click on Tools > Create GUID

 

Page 35: Share Point Customization Tricks

Click on Copy to copy the string and place it in the Id attribute value in your feature.xml file, leaving out the curly brackets!feature.xml code<Feature    Id="50BB0F5F-9FDD-4af8-8F05-F852DE735E30"    Title="SharePoint EventHandler Feature"    Description="This feature will blah blah blah [..]."      Scope="Web"    Hidden="FALSE"   AlwaysForceInstall="TRUE"   ImageUrl="components.gif"    xmlns="http://schemas.microsoft.com/sharepoint/">

   <ElementManifests>      <ElementManifest Location="elements.xml" />   </ElementManifests></Feature>* I used an image (ImageUrl) that already existed for the icon that displays in the feature list in SharePoint. If you want to use your own, simply include the image in the IMAGES foler and point to it.Now, open the elements.xml file and replace any code with the followingelements.xml code<Elements xmlns="http://schemas.microsoft.com/sharepoint/">  <Receivers ListTemplateId="101">    <Receiver>      <Name>SharePointEventHandler</Name>      <Type>ItemAdded</Type>      <SequenceNumber>1000</SequenceNumber>      <Assembly>        SharePointEventHandler,        Version=1.0.0.0,        Culture=Neutral,        PublicKeyToken=c5138f819b90316d      </Assembly>      <Class>SharePointEventHandler.ItemEventReceiver</Class>      <Data />    </Receiver>  </Receivers></Elements>* Note that the details for the Assembly tag came from the properties window that I asked you to write down or remember in the previous step! Also, the Class name refers to the namespace.classname name used in your class.** Note that we specify the ListTemplateId to be 101 for a Document Library. You can specify another value, therefore pointing to other lists such as an Announcements list, Tasks list, etc. Here is a way to see all the other Id's. 5. Installing the SharePoint FeatureWe will now need to move the folders and their files over to the "12" Hive and register the feature with SharePoint. Again we will make us of VS2005 Post-build utility. In your Solutions Explorer, double-click on Project and click on the Build Events SideTab. In your event text box, you should have one single line of code, which we wrote in our previous steps.

Page 36: Share Point Customization Tricks

 below that line, add the following code: cd "$(ProjectDir)" xcopy "12" "%CommonProgramFiles%\Microsoft Shared\web server extensions\12\" /ys

cd "%CommonProgramFiles%\Microsoft Shared\web server extensions\12\BIN" stsadm -o installfeature -name SharePointEventHandler -force

iisreset Your code should look like this:

 Basically what we are doing is compiling our code with a strong name, installing it into the GAC, then we copy the folderstructure into the 12 Hive, then we install our feature and finally reset IIS. Before you build, ensure that SharePoint is working and navigate to the Site Features page. (Home> Site Settings > Site Features) 

 Now, in Visual Studio 2005, build your solution (this may take a few seconds...). Ensure you have the Output (View > Output)  window open when you compile so you can monitor step-by-step what is happening in the background and if you have any errors. Once the build is successful, refresh yoru browser window and it should look like this:

Page 37: Share Point Customization Tricks

 Click on Activate to activate your feature and you are ready to go! 6. Testing our featureOk, let's test our feature... Open up a browser and go to your home page in SharePoint.

 create a new Document Library by clicking on Documents (left hand side) and then select Create.Now, select Document Library.

 Type in a name, for instance, Feature Site Test and select Word Document as the document type (or any other type...).

Page 38: Share Point Customization Tricks

 And there is your Document Library.

 Now, click on New and because we selected the Document type to be Word, it will launch Microsoft Word. Type in anything in this document and close. It will prompt you to save it.

 Select Yes and give it any name and Save.This will add the document to the Document Library and it this event is trapped by SharePoint that now redirects it to our custom code, which creates a text file for us on the desktop (shown below on the desktop).

Page 39: Share Point Customization Tricks

 When we open the text file, we will see it contains specific data about the document that fired this event.

  

SharePoint Site Accessing GloballyPosted by: rahilkhan on: April 15, 2009

In: SharePoint Comment!

Hi AllI’ve recently faced a problem, on accessing my SharePoint web Site.The default website is accessed e.g. at http://sharepoint/. This URL is working fine internally.When we try to access from outside the organization, it’s not accessible. To access the site internally as well outside the organization. We need to follow the Following Steps

1)      Go to Central Administration2)      You will find “OPERATION” Section. Click It.

Page 40: Share Point Customization Tricks

                

3)      Under Operation Tab Go to Global Configuration

  

4)      Under Global Configuration Section you will find Alternate Access Mappings. Click It

Page 41: Share Point Customization Tricks

  

5)     Under Alternate Access Mappings you will find all web application or SharePoint Site Listed

 6)      Click Add Internal URL

Page 42: Share Point Customization Tricks

 a)      Select  a site for  Alternate Access Mapping Collection  Sectionb)      Add Internal URLc)       Select Zone internet for Global Access d)  Click Save

Running Code Blocks In Your SharePoint ASPX Pages.

You may see this error: An error occurred during the processing of /test.aspx. Code blocks are not allowed in this file.Reason:  SharePoint does not allow server side code to execute in aspx pages contained in the SharePoint site. Fix:  Edit the web.config (I.E. C:\Inetpub\wwwroot\wss\VirtualDirectories\80\web.config) file: <PageParserPaths>        <!-- To allow a single file: -->        <PageParserPath VirtualPath="/test.aspx" CompilationMode="Always" AllowServerSideScript="true" />        <!-- To allow global: -->        <PageParserPath VirtualPath="/*" CompilationMode="Always" AllowServerSideScript="true" />        <!-- To allow global within a subsite: -->        <PageParserPath VirtualPath="/websitefoobar/*" CompilationMode="Always" AllowServerSideScript="true" /></PageParserPaths>

SharePoint issues with AllowPartiallyTrustedCallersPROBLEM: If you are trying to deploy a webpart from a Visual Studio solution and get this error... 

Page 43: Share Point Customization Tricks

Unable to add selected web part(s). Assemblies that implement ASP.NET Web Parts and are installed into a partially trusted location, such as the bin directory, must be compiled with the AllowPartiallyTrustedCallers set for import to succeed.   FIX: Add the following to your AssemblyInfo.cs and recompile. using System.Runtime.InteropServices;  [assembly: AllowPartiallyTrustedCallers] 

 SharePoint Convert UTC To Local TimeFor example, the LastItemModifiedDate property of a SPList is not local time, it is UTC.  So just use the SPWeb object to convert it to local time. DateTime myDT = mySPWeb.RegionalSettings.TimeZone.UTCToLocalTime(mySPList.LastItemModifiedDate)

Call Your JavaScript Function When Page (body) Is LoadedIn a SharePoint enviroment, the proper way to execute client side code when the page/body is loaded is to use the following function...  _spBodyOnLoadFunctionNames.push("myBodyLoadedFunctionName");

Configure Search On MOSS 2007 (Microsoft Office SharePoint Server)The following procedures step you through the process of configuring Office SharePoint Server 2007 search services, creating a Web application for the SSP, creating the SSP, and configuring indexing settings.   Start and configure the Search service

1. On the SharePoint Central Administration home page, click the Operations tab on the top navigation bar.

2. On the Operations page, in Topology and Services, click Servers in farm.

3. On the Servers in Farm page, click the server on which you want to configure the search service.

4. Click Start next to Office SharePoint Server Search.5. On the Office SharePoint Server Search Settings page, in the

Query and Indexing section, make sure that the Use this server for indexing content and Use this server for serving search queries check boxes are selected.

6. In the Default Catalog Location section, type a path to a physical folder to store the index files, or use the default location that is specified.

Page 44: Share Point Customization Tricks

7. In the Contact E-Mail Address section, specify a valid e-mail address.

8. In the Service Account section, click Configurable, and in User name and Password, type the user name and password for the user account under which you want the Search service to run. The user account must be a member of the Administrators group on the computer that is running the Search service. If you want to use the principle of least privilege and select a unique user account that does not have administrative rights on your front-end servers or on your back-end database servers, see the Known Issues/Readme for Office SharePoint Server 2007 Beta 2. The user name must be in the format DOMAIN\username.

9. In the Web Front End And Crawling section, do one of the following:

o If you are configuring the search service on a server that provides Web services and renders Web content, click No dedicated Web front-end computer for crawling

o If you are configuring the search service on a server that is a standalone search server that does not provide Web services and render Web content, click Use a dedicated web front end computer for crawling, and then, in Select a web front end computer, click the computer you want to use for crawling.

10. Click Start.Start the Windows SharePoint Services Web Application service You must start the Windows SharePoint Services Web Application service on every computer that you want to act as a Web server and was set up using the Complete option during Setup. This service is started by default on servers that were set up using the Web Front End option. To enhance security, you can leave this service turned off on application servers that do not provide Web content to client computers. Also, you do not need to turn this service on to use SharePoint Central Administration on a server.

1. On the SharePoint Central Administration home page, click the Operations tab on the top navigation bar.

2. On the Operations page, in Topology and Services, click Servers in farm.

3. On the Servers in Farm page, click the server on which you want to start the Windows SharePoint Services Web Application service.

4. Click Start next to Window SharePoint Services Web Application.

Create the Shared Services Provider 1. On the SharePoint Central Administration home page, click the

Application Management tab on the top navigation bar. 2. On the Application Management page, in the Office SharePoint

Server Shared Services section, click Create or configure this farm's shared services.

3. On the Manage this Farm's Shared Services page, click New SSP.  Important: If you have not created a Web application for the SSP administration site, you need to create one before you create the SSP. If you have already created a Web application for the SSP administration site, skip to step 14.

Page 45: Share Point Customization Tricks

4. On the New Shared Services Provider page, click Create a new Web application.

5. On the Create New Web Application page, in the IIS Web Site section, click Create a new IIS web site, and do not modify the default settings in this section.

6. In the Security Configuration section, under Authentication provider, select the appropriate option for your environment, and do not modify the default settings in the remainder of this section.

7. In the Load Balanced URL section, do not modify the default settings.

8. In the Application Pool section, click Create new application pool.

9. In Application pool name, enter the name of your application pool or use the default name.

10. Click Configurable, and in User name and Password, type the user name and password for the user account under which you want the application pool to run. The user account does not have to be a member of any particular security group. It is recommended that you use the principle of least privilege and select a unique user account that does not have administrative rights on your front-end servers or on your back-end database servers. You can use the user account that you specified as the Office SharePoint Server 2007 service account; however, if that user account is a member of a security group that has administrative rights on your front-end servers or your back-end database servers, you will not be following the principle of least privilege. The user name must be in the format DOMAIN\username.

11. In the Database Name and Authentication section, verify the database information and make sure that Windows Authentication (recommended)is selected.

12. In the Search Server section, do not modify the default settings. 13. Click OK. Upon successful creation of the Web application, the

New Shared Services Provider page appears. 14. In the SSP Name section, in Web Application, select the Web

application that you created for the SSP, and do not modify any of the default settings in this section.

15. In the My Site Location section, do not modify any of the default settings.

16. In the SSP Service Credentials section, in User name and Password, type the user name and password for the user account under which you want the SSP to run. The user account does not have to be a member of any particular security group. It is recommended that you use the principle of least privilege and select a unique user account that does not have administrative rights on your front-end servers or on your back-end database servers. You can use the user account that you specified as the Office SharePoint Server 2007 service account; however, if that user account is a member of a security group that has administrative rights on your front-end servers or your back-end database servers, you will not be following the principle of least

Page 46: Share Point Customization Tricks

privilege. The user name must be in the format DOMAIN\username.

17. In the SSP Database section, you can either accept the default settings (recommended), or specify your own settings for the database server, the database name, or the SQL authentication credentials.

18. In the Search Database section, you can either accept the default settings (recommended), or specify your own settings for the search database server, the database name, or the SQL Server authentication credentials.

19. In the Index Server section, in Index Server, click the server on which you configured the Search service.  Note: If there is no index server listed in the Index Server section, then no server in your farm has been assigned the index server role. To assign the index server role to a server in your farm, follow the instructions in the "Configure the Search service" section earlier in this topic.

20. In the SSL for Web Services section, click No. 21. Click OK. Upon successful creation of the SSP, the Success page

appears. 22. On the Success page, click OK to return to the Manage this Farm's

Core Services page. Configure indexing settings

1. On the SharePoint Central Administration home page, click the Application Management tab on the navigation bar.

2. On the Application Management page, in the Office SharePoint Server Shared Services section, click Create or configure this farm's shared services.

3. On the Manage this Farm's Shared Services page, click SharedServices1.

4. On the Shared Services Administration page, in Search, click Search Settings.

5. On the Configure Search Settings page, in the Crawl Settings section, click Default content access account.

6. In the Default content access account section, in Account, Password, and Confirm Password, type the user name and password for the user account that you want to use to crawl content on your sites. This account must be a domain user account. It is recommended that you use the principle of least privilege and select a unique user account that cannot modify content and does not have administrative rights on your front-end servers or on your back-end database servers. You can use the user account that you specified as the Office SharePoint Server 2007 service account; however, if that user account is a member of a security group that has administrative rights on your front-end servers or your back-end database servers, you will not be following the principle of least privilege. The user account that you specify will be added to the Web application Full Read policy for your farm. The user name must be in the format DOMAIN\username.

7. Click OK. 8. In the Crawl Settings section, click Content sources.

Page 47: Share Point Customization Tricks

9. On the Manage Content Sources page, click Local Office SharePoint Server sites.

10. On the Edit Content Source page, in the Crawl Schedules section, under Full Crawl, click Create schedule.

11. In the Manage Schedules dialog box, configure schedule settings for full crawls of your content, and then click OK.

12. In the Crawl Schedules section, under Incremental Crawl, click Create schedule.

13. In the Manage Schedules dialog box, configure schedule settings for incremental crawls of your content, and then click OK.

14. In the Start Full Crawl section, select the Start full crawl of this content source check box, and then click OK.

How To Iterate SharePoint Attachments Using The API

Looking for a way to iterate a SharePoint list item (SPListItem) for all attachments and render them on your page?  Here is a nice example.... private String x_renderAttachmentData(SPListItem listItem){    String strAttachmentData = String.Empty;     try    {         if (listItem.Attachments.Count > 0)        {             foreach (string fileName in listItem.Attachments)            {                SPFile spFile = listItem.ParentList.ParentWeb.GetFile(listItem.Attachments.UrlPrefix + fileName);                int fileSize = (int)spFile.Length / 1000;                strAttachmentData += "<div class='attachment'>"                                   + "<img src='_layouts/images/" + spFile.IconUrl + "'> "                                   + "<a target='_blank' href='" + URL_ROOT + "/" + spFile.Url + "'>"                                    + spFile.Name + "</a> &nbsp; (" + fileSize + " KB)"                                   + "<div class='hr'></div>Attachment version: " + spFile.UIVersionLabel                                   + "<br/>Created at " + spFile.TimeCreated.ToString() + " by "                                    + spFile.Author.ToString().Substring(spFile.Author.ToString().IndexOf('\\') + 1)                                   + "<br/>Last modified at " + spFile.TimeLastModified.ToString() + " by "                                    + spFile.ModifiedBy.ToString().Substring(spFile.ModifiedBy.ToString().IndexOf('\\') + 1)                                   + "</div><div style='clear:left;'></div>";  // just call me a css genius.                            }        }        return strAttachmentData;     }    catch (Exception exp)    {        // handle exp.    }}  

Page 48: Share Point Customization Tricks

  Output for this function looks like this...   

  Here is the css if you are interested.... .attachment{ color:#999999; font-size:9px; margin-bottom:0px; float:left;}.attachment img{margin-bottom:-2px;}.attachment .hr{ border-top:1px solid #bbbbbb; margin-top:2px;}.attachment a:link,.attachment a:visited,.attachment a:hover{ font-size:14px; line-height:18px;}