Friday, December 26, 2008

Programmatically customize site navigation

The SPWeb object has been enhanced in MOSS 2007 to support the ability to control the navigation of a SharePoint site programmatically!

The SPWeb object has a new property named Navigation that returns a SPNavigation object. This object allows developers to programmatically control the navigation of a SharePoint site.

Here is how you add a menu item to the QuickLaunch navigation menu.

These QuickLaunch examples assume you have created a top level site named quicklaunch.

Once this top level site has been created its URL will look like this: http://komal/quicklaunch
In this example we will add two links to the QuickLaunch menu for the quicklaunch top level site, one link will be internal and one will be external. The internal link will point to the Links list in the QuickLaunch site. The external link will point to the SharePoint Experts web site.

SPSite quickLaunchSite = new SPSite(“http://komal/quicklaunch”);

SPWeb quickLaunchWeb = quickLaunchSite.OpenWeb();

SPNavigationNodeCollection quickLaunchNodes = quickLaunchWeb.Navigation.QuickLaunch;

SPNavigationNode internalMenuItem = new SPNavigationNode(“Links”, “Lists/Links/AllItems.aspx”, false);

quickLaunchNodes.AddAsFirst(internalMenuItem);

SPNavigationNode externalMenuItem = new SPNavigationNode(“SharePoint Data”, “http://SharePointdata.blogspot.com”, true);

quickLaunchNodes.AddAsFirst(externalMenuItem);

quickLaunchWeb.Update();

Here is how you remove a menu item from the QuickLaunch navigation menu.

In this example we will remove the external link to the SharePoint Experts web site.

SPSite quickLaunchSite = new SPSite(“http://komal/quicklaunch”);

SPWeb quickLaunchWeb = quickLaunchSite.OpenWeb();

SPNavigationNodeCollection quickLaunchNodes = quickLaunchWeb.Navigation.QuickLaunch;

quickLaunchNodes.Delete(quickLaunchNodes([0]));

quickLaunchWeb.Update();

Here is how you add grouped menu items to the QuickLaunch navigation menu.

In this example we will create a header link for the group of links and name it Administration. Then we will add two links under the Administration header link. The links will link to the Create and Site Settings pages for the quicklaunch Site Collection.

SPSite quickLaunchSite = new SPSite("http://" + serverTextBox.Text + "/quicklaunch");

SPWeb quickLaunchWeb = quickLaunchSite.OpenWeb();

SPNavigationNodeCollection quickLaunchNodes = quickLaunchWeb.Navigation.QuickLaunch;

SPNavigationNode internalMenuItem = new SPNavigationNode("Administration", "", false);

quickLaunchNodes.AddAsFirst(internalMenuItem);

SPNavigationNode externalSubMenuItem1 = new SPNavigationNode("Site Settings", quickLaunchWeb.Url + "/_layouts/settings.aspx", true);

quickLaunchNodes[0].Children.AddAsFirst(externalSubMenuItem1);

SPNavigationNode externalSubMenuItem2 = new SPNavigationNode("Create", quickLaunchWeb.Url + "/_layouts/create.aspx", true);

quickLaunchNodes[0].Children.AddAsFirst(externalSubMenuItem2);

quickLaunchWeb.Update();

Top Navigation Menu Items

The top navigation menu may also be accessed programmatically. You can create new menu items in the top navigation menu navigation menu and remove them. You can also specify if the link is external to the site.

Here is how you add a menu item to the top navigation menu.

This example assumes you have created a top level site named topnavigation.

Once this Site Collection has been created its URLs will look like this: http://komal/topnavigation

In this example we will add two links to the top navigation menu for the topnavigation top level site, one link will be internal and one will be external. The internal link will point to the Links list in the topnavigation site. The external link will point to the SharePoint Experts web site.

SPSite topNavigationSite = new SPSite(“http://komal/topnavigation”);

SPWeb topNavigationWeb = topNavigationSite.OpenWeb();

SPNavigationNodeCollection topNavigationNodes = topNavigationWeb.Navigation.TopNavigationBar;

SPNavigationNode internalMenuItem = new SPNavigationNode(“Links”, “Lists/Links/AllItems.aspx”, false);

topNavigationNodes.AddAsFirst(internalMenuItem);

SPNavigationNode externalMenuItem = new SPNavigationNode(“SharePoint Data”, “http://SharePointdata.blogspot.com”, true);

topNavigationNodes.AddAsFirst(externalMenuItem);

topNavigationWeb.Update();



Wednesday, December 10, 2008

GetListItem using sharepoint webservice

public System.Data.DataSet GetListItem(string UserName, string Password, string Domain, string SiteURL, string ListName, string nodeQuery, Guid SiteGuid)

{

DataSet dsList = new DataSet();

try

{

ListData.Lists list = new ListData.Lists();

list.Url = SiteURL + "/_vti_bin/lists.asmx";

list.Credentials = new System.Net.NetworkCredential(UserName, Password, Domain);

list.PreAuthenticate = true;

System.Xml.XmlDocument doc = new System.Xml.XmlDocument();

System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();

System.Xml.XmlNode ndQuery = xmlDoc.CreateNode(System.Xml.XmlNodeType.Element, "Query", "");

//ndQuery.InnerXml = "";

ndQuery.InnerXml =nodeQuery;

System.Xml.XmlNode ndViewFields = xmlDoc.CreateNode(System.Xml.XmlNodeType.Element, "ViewFields", "");

System.Xml.XmlNode ndQueryOptions = xmlDoc.CreateNode(System.Xml.XmlNodeType.Element, "QueryOptions", "");

System.Xml.XmlNode items = list.GetListItems(ListName, string.Empty, ndQuery, ndViewFields, "", ndQueryOptions, SiteGuid.ToString());

System.IO.StringReader sr = new System.IO.StringReader(items.OuterXml.ToString());

dsList.ReadXml(sr);

return dsList;

}

catch (Exception)

{

}

return dsList;

}

Get SitID/WebID using sharepoint webservice

public Guid GetSiteID(string UserName, string Password, string Domain, string SiteURL)
{

Guid SiteGuid = Guid.Empty;

try

{

SiteData.SiteData site = new TP.WebService.SiteData.SiteData();

site.Url = SiteURL + "/_vti_bin/sitedata.asmx";

site.Credentials = new System.Net.NetworkCredential(UserName, Password, Domain);

site.PreAuthenticate = true;

SiteData._sWebMetadata webMetaData;

SiteData._sWebWithTime[] arrWebWithTime;

SiteData._sListWithTime[] arrListWithTime;

SiteData._sFPUrl[] arrUrls;

string roles; string[] roleUsers; string[] roleGroups;

uint i = site.GetWeb(out webMetaData, out arrWebWithTime, out arrListWithTime, out arrUrls, out roles, out roleUsers, out roleGroups);

SiteGuid = new Guid(webMetaData.WebID);

}

catch (Exception)

{

}

return SiteGuid;

}

Using Sharepoint Webservice to add/update/delete list Item

Using Sharepoint webservice, i have insert/update/delete list item through lists.asmx.
Using this code,just pass necessary parameter to run this code.

For Insert Item Query:

string caml="<Method ID=\"1\" Cmd=\"New\">" + "<Field Name=\"ID\">New</Field>" + "<Field Name=\"Title\">" + TextBox1.Text.ToString() + "</Field>" + "</Method>";

For Update Item Query:

string caml="<Method ID=\"1\" Cmd=\"New\">" + "<Field Name=\"ID\">1</Field>" + "<Field Name=\"Title\">" + TextBox1.Text.ToString() + "</Field> + "</Method>";

For Delete Item Query :

string caml="<Method ID=\"1\" Cmd=\"New\">" + "<Field Name=\"ID\">1</Field></Method>";

TP.WebService.ListOperation listItemAdd = new TP.WebService.ListOperation();

listItemAdd.InsertUpdateDeleteListItem("komal", "admin", komal, "http://komal:1222", caml, "test1");


public bool InsertUpdateDeleteListItem(string UserName, string Password, string Domain, string SiteURL,string CAML,string ListName)
{
try
{

ListData.Lists list = new ListData.Lists();
list.Url = SiteURL +"/_vti_bin/lists.asmx";
list.Credentials = new System.Net.NetworkCredential(UserName,Password,Domain);
System.Xml.XmlDocument xmlDoc;
System.Xml.XmlElement elBatch;
System.Xml.XmlNode ndReturn;
xmlDoc = new System.Xml.XmlDocument();
elBatch = xmlDoc.CreateElement("Batch");
elBatch = xmlDoc.CreateElement("Batch");
elBatch.SetAttribute("OnError", "Continue");
string strBatch = CAML;
elBatch.InnerXml = strBatch;
ndReturn = list.UpdateListItems(ListName, elBatch);
return true;

}

catch (Exception)
{
return false;
}
return true;
}

Friday, December 5, 2008

SharePoint Custom Action Identifiers

http://johnholliday.net/resources/customactions.html

http://blogs.msdn.com/dipper/archive/2006/10/05/How-to-Remove-or-hiding-items-in-List-toolbar-in-Sharepoint-Server-2007.aspx

http://asadewa.wordpress.com/2008/02/23/removing-single-file-upload-menu-from-document-library-toolbar-moss-2007/

Hide "View All Site Content" link for anonymous users in SharePoint WSS 3.0

This solution requires you to install Microsoft Office SharePoint Designer.
  1. Go to "Site Actions" ==> "Site Settings"
  2. Under Galleries, click on "Master Pages"
  3. Select default.master and select "Edit in Microsoft Office SharePoint Designer".
  4. In "Design" view locate "View All Site Content" on the left-hand-site navigation bar and click on it.
  5. Go to "Code" view. You will see the following code highlighted:

<Sharepoint:SPSecurityTrimmedControl runat="server" PermissionsString="ViewFormPages">
<div class="ms-quicklaunchheader">
<SharePoint:SPLinkButton id="idNavLinkViewAll" runat="server" NavigateUrl="~site/_layouts/viewlsts.aspx" Text="<%$Resources:wss,quiklnch_allcontent%>" AccessKey="<%$Resources:wss,quiklnch_allcontent_AK%>"/>
</div>
</SharePoint:SPSecurityTrimmedControl>

  1. Change the PermissionString attribute value of the Sharepoint:SPSecurityTrimmedControl XML element from ViewFormPages to BrowseDirectories.
  2. Save the default.master. If you login as an anonymous user you will not see the "View All Site Content" link. However when authenticated you will see this option.
NOTE: The "BrowseDirectories" permission is common to both the "Members" and "Owners" group permission levels, but is not set for the "Limited Access" (anonymous users) permission level. See a complete list of the SPBasePermissions Enumeration here.

Friday, November 28, 2008

CustomGroup and CustomAction in central admin application page using featurepage

In central admin, there is option to add new group and action in "Operation" page like :Topology".

Here is the xml file that can added new custom group in the central administration.

You can installed as new feature for that and activated features in site feature.

feature.xml

<Feature Id="56FD5FEC-4FE9-4970-B1B6-20580B2ECD1B"   Title="Test Group Page"
Description="Test Group Page."   Version="1.0.0.0"      Scope="Web"    Hidden="false"
DefaultResourceFile="core" xmlns="http://schemas.microsoft.com/sharepoint/">
                <ElementManifests >
                                <ElementManifest Location="element.xml" />
                </ElementManifests>
</Feature>

 
element.xml
 

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
       <CustomActionGroup Id="{6C3A6045-5F34-4203-80E7-C9DD90801835}" Title="Test Group"     Location="Microsoft.SharePoint.Administration.Operations"  Sequence="100" />
                <CustomAction   Id="{EA6E9E68-32C6-47f2-9CF3-07D7A496623D}"   Title="Test Page"                 Location="Microsoft.SharePoint.Administration.Operations"
                GroupId="{6C3A6045-5F34-4203-80E7-C9DD90801835}"
                RequireSiteAdministrator="TRUE"
                Sequence="10">

       <UrlAction Url="/_controltemplates/ApplicationPage.aspx"/>
               </CustomAction>
</Elements>

 Links :



Sunday, November 23, 2008

Using the Contact Selector in Infopath 2007

How to Deploy SharePoint WebParts

There are several ways to skin the Webparts deployment cat, each with a few pluses and minuses.

Method 1 - manual

  • Copy assembly DLL to either
    - /bin directory for a given IIS virtual server (e.g., c:\inetpub\wwwroot\bin)
    - Global Assembly Cache (e.g., c:\windows\assembly)

  • Copy DWP file to C:\Inetpub\wwwroot\wpcatalog

  • Copy resources to
    - For GAC-registered parts, C:\Program Files\Common Files\Microsoft Shared\web server extensions\wpresources
    - For Web Parts in the /bin directory, C:\Inetpub\wwwroot\wpresources

  • Adjust web.config
    - Register as SafeControl
    - Select Code Access Security settings


Method 2: CAB File

  • CAB file should contain
    -Assembly DLL
    -DWP file(s)
    -Manifest.XML
    -Resource files (if needed)
  • CAB won't contain
    - Code Access Security settings

  • Server-side object model has methods for deploying such a CAB file

  • Deploy with STSADM.EXE
    Located in C:\Program Files\Common Files\Microsoft Shared\web server extensions0\BIN
    Add it to your path
    Stsadm -o addwppack -filename filename [-globalinstall] [-force]

New Version of the Caml Query Builder Tool

New version of her CAML Query Builder Tool! Version 3.1.0.0 has some great new features:
  • Query fields by ID
  • GetListItemChanges (method of the Lists.asmx web service)
  • GetListItemChangesSinceToken (method of the Lists.asmx web service)
  • extra options of the QueryOptions part
  • support for data type ModStat
Download here and check her blog post for the full details.

Adding Breadcrumb Navigation to Application Pages in SharePoint Central Administration

Last week I have found one good articles that can useful for make breadcrumb in central administration.

http://weblogs.asp.net/jan/archive/2008/10/10/adding-breadcrumb-navigation-to-application-pages-in-sharepoint-central-administration.aspx

Current Page URL in the UrlAction of a SharePoint Feature

With the introduction of the feature framework in SharePoint 2007, developers have some great opportunities to customize and enhance nearly everything in SharePoint.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<CustomAction
Id="{6FCB0F81-2105-4d9f-96BF-C48A19B8E439}"
Title="My Link"
Location="Microsoft.SharePoint.StandardMenu"
GroupId="SettingsMenu">
<UrlAction Url="_layouts/mypage.aspx"/>
</CustomAction>
</Elements>

When activated, the feature will add a menu item to the Settings menu of any SharePoint list or document library. The menu item will have the title My Link, when clicked the user will navigate to the page mypage.aspx in the _layouts folder

<UrlAction Url="_layouts/mypage.aspx?listid={ListId}"/>

The {ListId} URL token will be automatically replaced with the ID of the list, in which the menu item is shown. In the mypage.aspx, you can retrieve the value of the listid parameter by making use of the QueryString. Once you've got the ID, the object model can be used to get a reference to the SPList instance of that list. According to the documentation on MSDN, the following URL tokens can be used:

  • ~site - Web site (SPWeb) relative link.
  • ~sitecollection - site collection (SPSite) relative link.
  • In addition, you can use the following tokens within a URL:
    • {ItemId} - Integer ID that represents the item within a list.
    • {ItemUrl} - URL of the item being acted upon. Only work for documents in libraries. [Not functional in Beta 2]
    • {ListId} - GUID that represents the list.
    • {SiteUrl} - URL of the Web site (SPWeb).
    • {RecurrenceId} - Recurrence index. This token is not supported for use in the context menus of list items.

Thursday, November 20, 2008

Enabling anonymous access in SharePoint 2007

First, you need to enable anonymous on the IIS web site (called a Web Application in SharePoint land). This can be done by:

  • Launching Internet Information Services Manager from the Start -> Administration Tools menu
  • Select the web site, right click and select Properties
  • Click on the Directory Security tab
  • Click on Edit in the Authentication and access control section

Instead we’ll do it SharePoint style using the Central Administration section:

  • First get to your portal. Then under “My Links” look for “Central Administration” and select it.
  • In the Central Administration site select “Application Management” either in the Quick Launch or across the top tabs
  • Select “Authentication Providers” in the “Application Security” section
  • Click on the “Default” zone (or whatever zone you want to enable anonymous access for)
  • Under “Anonymous Access” click the check box to enable it and click “Save”

NOTE: Make sure the “Web Application” in the menu at the top right is your portal/site and not the admin site.

You can confirm that anonymous access is enabled by going back into the IIS console and checking the Directory Security properties.

Now the second part is to enable anonymous access in the site.

  • Return to your sites home page and navigate to the site settings page. In MOSS, this is under Site ActionsSite SettingsModify All Site Settings. In WSS it’s under Site ActionsSite Settings.
  • Under the “Users and Permissions” section click on “Advanced permissions”
  • On the “Settings” drop down menu (on the toolbar) select “Anonymous Access”
  • Select the option you want anonymous users to have (full access or documents and lists only)

Now users without logging in will get whatever option you allowed them.

A couple of notes about anonymous access:

  • You will need to set up the 2nd part for all sites unless you have permission inheritance turned on
  • If you don’t see the “Anonymous Access” menu option in the “Settings” menu, it might not be turned on in Central Admin/IIS. You can manually navigate to “_layouts/setanon.aspx” if you want, but the options will be grayed out if it hasn’t been enabled in IIS
  • You must do both setups to enable anonymous access for users, one in IIS and the other in each site

MOSS Architecture: Model, SSP, Portal

MOSS adopts a 3-tier model with:

1. Web servers at the front: web servers which can be network balanced to achieve addl performance and fault tolerance
2. Application servers in the middle: servers collection that provide shared services to portals and sites (SSP)
3. Database servers at the back where data and config is stored and can be clustered

The prominent services provided by the Application Servers include:
  • Search
  • Index
  • Audience compilation
  • User profiles database
  • My Sites
  • Business Data Catalogue
  • Excel Services
Any of the above services can exist on any number of servers within the SSP.

Portal:

It is now called "Collaboration Portal", not "Portal" as in earlier version of SharePoint and it is just another site collection that is hosted on a IIS site(Web Application).Portals don't contain any application services such as Search, My Site etc. Now, everything has to come thru SSP. This means that we just need a web server to host a portal and a place to include the content database.

Different portals can live on their own hardware completely isolated from any other hardware other than the fact that it consumes services from a centrally managed SSP. Alternatively, you can put some of your portals on shared hardware and some on dedicated.

All three tiers (web, application, database) of the SharePoint model can be hosted on a single machine or scaled out to a huge collection of servers to meet the requirements.

Most organisations will want some level of fault tolerance and separation between server roles.

Medium-Farm Configuration:

Typically these kind of organisations will have at least 2 web servers running your portals and sites, at least one application server hosting all services (maybe a second for fault tolerance) and one database cluster.

Large-Farm Configuration:

Larger organisations may want to have separate web servers for each of their portals, sites and my sites. They may also go for multiple application servers as part of the SSP.

Tables within MOSS 2007

  • AllDocs: holds information about all the documents (and all list items) for each document library and list
  • AllLists: holds information about lists for each site
  • AlllistData: holds information about all the list items for each list
  • AllUserData: holds all the metadata which user provides in a document library
  • GroupMembership: holds information about all the SharePoint group members
  • Groups: holds information about all the SharePoint groups within each site collection
  • ImmedSubscriptions: holds information about all the immediate subscriptions (alerts) for each user
  • RoleAssignment: holds information about all the users or SharePoint groups that are assigned to roles
  • Roles: holds information about all the SharePoint roles or permission levels for each site
  • SchedSubscriptions: holds information about all the scheduled subscriptions (alerts) for each user
  • Sites: holds information about all the site collections relevant to this content database
  • UserInfo: holds information about all the users within each site collection
  • Webs: holds information about all the specific sites (webs) in each site collection

Understanding RunWithElevatedPrivileges

What happens when you use RunWithElevatedPrivileges ?

Without RunWithElevatedPrivileges delegate the Sharepoint identity will be the same as of the current user identity and you are able to do whatever your own permissions allow you to do.

With RunWithElevatedPrivilages delegate the Sharepoint set the identity to Sharepoint\System. The Sharepoint\System identity doesn't have anything to do with a windows identity so you shouldn't be tempted to look for this windows account. The Sharepoint\Sytem is a built-in identity of Sharepoint and it has full permissions in Sharepoint. Also RunWithElevatedPrivilages elevates the windows privilages which means that if you are running the elevated code from a web application the applicaion is basically using the identity of the account running the webApp pool.

Incase of winforms/console application, code runs with your credentials (or if using 'runas', it would use whatever credentials you told it to use). There is no impersonation going on here like with the web application, so a call a to RunWithElevatedPrivileges will effectively do nothing because there is no impersonation to temporarily halt. You can see this is the case if you were to execute this code snippet in a console application:

SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(siteUrl))
{
using (SPWeb web = site.OpenWeb(webUrl))
{
System.Console.WriteLine(web.CurrentUser.LoginName);
System.Console.WriteLine(System.Security.Principal.WindowsIdentity.GetCurrent().Name);
System.Console.ReadKey();
}
}
});


Note here that web.CurrentUser.LoginName is coming from the WSS identity. If you 'runas' the web application's app pool identity, it would get correlated to SharePoint\System and thats what you would see on the first line of output.

Wednesday, November 19, 2008

Hide Quick Launch using CSS

Add content editor webpart and insert this css in it.

<style>
.ms-navframe
{
display:none;
}
</style>

Monday, November 17, 2008

The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.

The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Runtime.InteropServices.COMException: The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:

[COMException (0x8102006d): The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.]
Microsoft.SharePoint.Library.SPRequestInternalClass.UpdateRoleAssignment(String bstrUrl, Guid& pguidScopeId, Int32 lPrincipalID, Object& pvarArrIdRolesToAdd, Object& pvarArrIdRolesToRemove) +0
Microsoft.SharePoint.Library.SPRequest.UpdateRoleAssignment(String bstrUrl, Guid& pguidScopeId, Int32 lPrincipalID, Object& pvarArrIdRolesToAdd, Object& pvarArrIdRolesToRemove) +119
[SPException: The security validation for this page is invalid. Click Back in your Web browser, refresh the page, and try your operation again.]
OfficialMail.WebParts.TestWebPart.btn_Click(Object sender, EventArgs e) +94
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +105
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +107
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5102

Solutions :
Central Administration > Application Management > Web Application General Settings ->Select web application

In Web Page Security Validation , change security validation is off.

Thursday, November 6, 2008

some useful links....

Go through this link that have more useful sharepoint tutorials link that useful for sharepoint developer.

http://sharepoint-exchange.blogspot.com/2008_02_01_archive.html

MOSS 2007 User and Profiles import from Active Directory


Its very normal to have a scenario in which the user profile information in stored in directory service like Active Directory. Since personalization in sharepoint largely depends upon user profiles it becomes imperative to not only import the user information in AD into sharepoint as user profiles but also to run incremental imports to sync up user profiles with new information added into the Active directory.

As you know sharepoint integrates with Active directory and a user profile record gets created in sharepoint when an AD authenticated user first accesses a site. Assumption here is that the user already has adequate permissions on the site. As noted above incremental imports facilitate synchronizing user information stored in AD with the profile created in sharepoint.

The following steps need to be followed to configure import of user profiles from Active Directory -

Scenario-1 - All users are in the current domain.


1. Go to User Profile and Properties under Shared Services Administration.

2. Click on configure profile import link. Select current domain as the profile datasource.

3. Make sure default access account is specified and is valid.

4. Run full import or incremental report.


Scenario-2 - Users are scattered into multiple domains or other data sources.


1. Go to User Profile and Properties under shared services administration.

2. Click on Import New Connection. Add a new connection for each of the data sources where you users are located. Delete any unwanted connections that might already be there.

3. Configure the import as mentioned above and make sure that Custom source is selected.

4. Run the full import or incremental import.

Saturday, October 25, 2008

Copy Document Library file into local server using event handler

public override void ItemAdded(SPItemEventProperties properties)
{
try
{
//Copy Document Library file into local server using event handler
base.ItemAdded(properties);
DisableEventFiring();

SPWeb web = properties.OpenWeb();
web.AllowUnsafeUpdates = true;
SPList ilist = web.Lists[properties.ListId];

SPFolder folder = web.GetFolder(properties.ListTitle.ToString());

foreach (SPFile x in folder.Files)
{
if (properties.ListItemId == x.Item.ID)
{
string strpath = @"D:/Trushar/" + folder.Name.ToString() + "/" + x.Name.ToString();
//FileStream fs = new FileStream(@"D:/Trushar/MyDoc/Test1.jpg", FileMode.Create);
FileStream fs = new FileStream(strpath, FileMode.Create);
BinaryWriter binaryWriter = new BinaryWriter(fs);
byte[] fileData = (byte[])x.OpenBinary();

binaryWriter.Write(fileData);
binaryWriter.Close();
break;
}
}

EnableEventFiring();

}
catch (Exception ex )
{


}




}

Friday, October 24, 2008

How to register your custom events in MOSS 2007

You can register your custom MOSS event handlers using a few techniques. I have always been a fan of a simple Console application which will do the trick. The pre-requisites are:
1) Ensure that the assembly implementing the custom event handlers in strongly typed 
2) Ensure that your custom event handlers strongly typed assembly has been registered in the GAC of the server (or on each server on a web farm).

Once you have checked the pre-requisites you can write a Console application to do your job. An example is as below:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;

namespace trusharWebsite.Website.RegisterEventHandlers
{
// Console application to register custom event handlers on a specific list called "Comments" on the website
class Program
{
static void Main(string[] args)
{
SPSite curSite = new SPSite("http://trushar/trusharBlog");
SPWeb curWeb = curSite.OpenWeb();

SPList commentsList = curWeb.Lists["Comments"];

string asmName = "trusharWebsite.WebSite.EventHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=342fb345e6f432a";
string className = "trusharWebsite.WebSite.EventHandler.AddmyItemHandler";

commentsList.EventReceivers.Add(SPEventReceiverType.ItemAdding, asmName, className);
commentsList.EventReceivers.Add(SPEventReceiverType.ItemUpdating, asmName, className);
}
}
}

Thursday, October 23, 2008

Update WSS 3.0 User Profile Programmatically

In WSS 3.0, there is a special list ‘User Information List’ for user’s profile information. When a user is added to the Sharepoint site, a list item is automatically created in this list. To update the user’s information in ‘User Information List’, for instance, to update the user’s photo, I am using following code and it works fine:

 

SPList list = web.Lists["User Information List"];

SPUser u = web.SiteUsers[“domain\\user1”];

.SPListItem it = list.Items.GetItemById(u.ID);

 

it[“Picture”] =”http://sharepointApp/sites/wss/photos/abc.jpg”;

it.Update();

 Also, you are able to add a custom field to user profile like this:

 SPList list = web.Lists["User Information List"];

if (!list.Fields.ContainsField("Favorites"))
{
         list.Fields.Add("Favorites", SPFieldType.Text, false);
         list.Update();
}

Saturday, October 18, 2008

Adding your own Administration Pages to Site Settings or Central Administration

You can make your custom SharePoint Applications look more like a part of the SharePoint environment by adding any Administration Tasks (ie. settings pages) that you might require into the Admin Console or Site Settings areas.

For this you need a Feature and a definition of the new menu item to be added and where it links to.

<?xml version="1.0" encoding="utf-8"?>
<Feature Id="34251A34-3B03-4149-94A3-A04C5F99E251"
Title="My Administration Link"
Description="Link to administration page."
Version="12.0.0.0"
Scope="Web"
Hidden="FALSE"
DefaultResourceFile="core"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="elements.xml" />
</ElementManifests>
</Feature>

Element.xml file is as below :

<?xml version="1.0" encoding="utf-8"?>
<Elements
xmlns="http://schemas.microsoft.com/sharepoint/">
<CustomAction
Id="ManageMySettings"
GroupId="SiteCollectionAdmin"
Location="Microsoft.SharePoint.SiteSettings"
RequireSiteAdministrator="TRUE"
Sequence="45"
Title="Manage My Settings">
<UrlAction
Url="_layouts/MyAppSettings.aspx" />
</CustomAction>
</Elements>

This elements.xml file adds a link to the Site Settings Page (by setting the Location attribute), under the Site Collection Admin area (specified by the Group ID) and requiring Site Administrator Access to get to. The UrlAction element specifies where the link goes (in this case to an aspx page in _layouts).

I can also insert links into the Central Admin area if needed just by specifying a different CustomAction:

<?xml version="1.0" encoding="utf-8"?>
<Elements
xmlns="http://schemas.microsoft.com/sharepoint/">
<CustomActionGroup
Id="Mine"
Location="Microsoft.SharePoint.Administration.ApplicationManagement"
Title="My Applications"
Sequence="100" />
<CustomAction
Id="MyAppSettings"
GroupId="Mine"
Location="Microsoft.SharePoint.Administration.ApplicationManagement"
Sequence="11"
Title="My App Settings">
<UrlAction
Url="/_admin/AppSettings.aspx" />
</CustomAction>
</Elements>



SharePoint 2007 Forms Authentication with sqlserver Membership

Here is the sharepoint 2007 form authentication for sqlserver membership.
I have read this article and it is good for form authentication.

http://weblog.vb-tech.com/nick/archive/2006/06/14/1617.aspx

http://www.andrewconnell.com/blog/articles/HowToConfigPublishingSiteWithDualAuthProvidersAndAnonAccess.aspx

http://weblog.vb-tech.com/nick/

http://www.chandima.net/Blog/archive/2007/02/15/how-to-setup-and-configure-forms-based-user-administration-feature-release-1-0-beta.aspx

http://www.codeproject.com/KB/sharepoint/FBA.aspx

Friday, October 17, 2008

Validating Date field in SharePoint through Javascript

Just put the following code in NewItem.aspx :

function PreSaveAction()
{
var date1 = getTagFromIdentifierAndTitle("INPUT","DateTimeFieldDate","Contract Date");

var date2 = getTagFromIdentifierAndTitle("INPUT","DateTimeFieldDate","Contract End Date");

var arrDate1 = date1.value.split("/");

var useDate1 = new Date(arrDate1[2], arrDate1[1]-1, arrDate1[0]);

var arrDate2 = date2.value.split("/");

var useDate2 = new Date(arrDate2[2], arrDate2[1]-1, arrDate2[0]);

if(useDate1 > useDate2)
{
alert("The end date cannot happen earlier than the start date");

return false; // Cancel the item save process
}

return true; // OK to proceed with the save item }

How to get details error page instead of "An unexpected error has occurred" in MOSS 2007?

Debugging SharePoint can be problematic at times, it does like to hide debugging information from you. Whenever any error occurs in application it just display a page with error message “An unexpected error has occurred” with nothing written to log files, trace or the event log.
To get detail asp.net error page, you just need to do couple of changes in web.config file

SafeMode MaxControls=“200“ CallStack=“false“…
to…
SafeMode MaxControls=“200“ CallStack=“true“…

You will also need to set custom errors to 'Off' .

customErrors mode=“Off“


You will no longer see the “An unexpected error has occurred” error page and instead you get a lovely ’standard ASP.Net error page’ with the stack trace and everything…development has got that little bit easier!!

Saturday, October 11, 2008

STSADM Operation Command

Here is a link for STSADM Operation command that can be useful in the Moss 2007 and wss 3.0.

http://blogs.technet.com/josebda/archive/2008/03/15/complete-reference-of-all-stsadm-operations-with-parameters-in-moss-2007-sp1.aspx

Thursday, October 9, 2008

Renaming a MOSS Server

Here is the step to rename the moss server that is already configure it.

  • Change each alternate access mapping for your MOSS/WSS deployment in Central Administration:
    • Open Central Administration, "Operations" Tab, "Alternate access mappings" link
    • Modify each mapping item to reflect your newly chosen server name
  • Use stsadm.exe to invoke the "renameserver" command option:
    • Open a command prompt window
    • cd "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN"
    • stsadm -o renameserver -newservername -oldservername
    • Reboot the server NOW.
    • After reboot, open command prompt
      • cd C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN
      • stsadm -o updatefarmcredentials -userlogin -password
      • iisreset /noforce
    • Check all application pool identities in IIS, update where the old machine name is still there.
    • If you already have a search index drop this, and rebuild it

    The use of SPContext

    When building custom web parts for Windows SharePoint Services V3. You can use the SPContext object to get for instance the site or web from the current context. But that's not all you can get from SPContext. You can also get the listitem and the webfeatures.

    In WSS V2 you would use SPControl.GetContextSite() or SPControl.GetContextWeb() but that's a lot less flexible and it's slower as well.

    A couple of different uses of SPContext are shown below:

    *************************************************************************

    SPList currentList = SPContext.Current.List;

    SPWeb currentSite = SPContext.Current.Web;

    SPSite currentSiteCollection = SPContext.Current.Site;

    SPWebApplication currentWebApplication = SPContext.Current.Site.WebApplication;

    *************************************************************************

    SPListItem item = (SPListItem)SPContext.Current.Item;

    *************************************************************************

    SPWeb site = SPContext.Current.Site.OpenWeb(guid);

    SPUser user = SPContext.Current.Web.CurrentUser;

    *************************************************************************

    SPSiteDataQuery siteQuery = new SPSiteDataQuery();

    siteQuery.Query = "" +

    "100";

    siteQuery.ViewFields = "";

    DataTable queryResults = SPContext.Current.Web.GetSiteData(siteQuery);

    queryResults.TableName = "queryTable";

    queryResults.WriteXml("C:\\queryTable.xml");

    The last example makes use of the SPSiteDataQuery object. In WSS V3 there are two different query objects. Besides SPSiteDataQuery object there is also the SPQuery object.
    The difference between the two is that SPQuery can only be used for queries within a single folder in a single list. SPSiteDataQuery can be used for cross lists and even cross site queries.

    SharePoint Web Services

    The WSS Web Services are part of the Microsoft.SharePoint.SoapServer namespace. The web services include methods to accessing and customizing SharePoint site content such as lists, site data, forms, meetings, document workspaces, and permissions. The table below shows the WSS web services, including a description of what they can be used for and the reference.

    MOSS 2007 also exposes a series of web services. The MOSS web services allow you to use the Business Data Catalog, document management, Enterprise Search, Excel Services, InfoPath Forms Services, and Web content management (WCM). The table below shows most of the web services, there use and the reference you need to use them.

    If you want to use one of the SharePoint web serrvices in your visual studio project you can simply add a Web Reference using the path of the SharePoint site for which you want to use the Web Service and add the web service reference to it. Your reference will then look something like this http://moss/_vti_bin/[webservicereference].asmx.

    Uploading a File to a SharePoint Site from a Local Folder

    I have read the this tutorial and it is good for add document in the list from local folder.
    http://msdn.microsoft.com/en-us/library/ms868615.aspx

    Thursday, October 2, 2008

    Active Directory Change Password

    protected void Button1_Click(object sender, EventArgs e)

    {
    if (this.txtNewPassword.Text.Length >= 0)
    {

    if (this.txtNewPassword.Text.Equals(this.txtConfirmPassword.Text))
    {
    DirectoryEntry entry;
    char[] sep ={ '\\' };
    string[] strArray = this.Context.User.Identity.Name.Split(sep);
    if (this.isLocalAccount())
    {

    try

    {
    // Connect to Active Directory and get the DirectoryEntry object.
    // Note, ADPath is an Active Directory path pointing to a user.

    entry = new DirectoryEntry("WinNT://" + strArray[0] + "/" + strArray[1], this.Context.User.Identity.Name, this.txtOldPassword.Text, AuthenticationTypes.Secure);
    }

    catch (Exception exception1)

    {

    lblMsg.Text = exception1.Message.ToString();

    return;

    }

    try

    {

    object objectValue = RuntimeHelpers.GetObjectValue(entry.Invoke("ChangePassword", new object[] { this.txtOldPassword.Text, this.txtNewPassword.Text }));

    }

    catch (Exception exception5)

    {



    lblMsg.Text = exception5.Message.ToString();

    return;

    }

    }

    else

    {

    try

    {

    string[] propertiesToLoad = new string[] { "sAMAccountName", "cn" };

    DirectorySearcher searcher = new DirectorySearcher("(sAMAccountName=" + strArray[1] + ")", propertiesToLoad);

    searcher.SearchRoot.Username = this.Context.User.Identity.Name;

    searcher.SearchRoot.Password = this.txtOldPassword.Text;



    // You would have created this which searches AD for the specified user

    // and returns its DirectoryEntry object or path. See here.

    SearchResult result = searcher.FindOne();

    if (result == null)

    {



    lblMsg.Text = "The User was not found in the Active Directory";

    }

    entry = new DirectoryEntry(result.Path, this.Context.User.Identity.Name, this.txtOldPassword.Text);

    // entry.RefreshCache();





    DirectorySearcher search = new DirectorySearcher(entry);

    search.Filter = "sAMAccountName=" + strArray[1].ToString(); ;

    SearchResult result1 = search.FindOne();

    DirectoryEntry user = result1.GetDirectoryEntry();

    string NewPassword = this.txtNewPassword.Text;

    user.Invoke("SetPassword", new object[] { NewPassword });

    lblMsg.Text = "Password has been changed successfully.";





    }

    catch (Exception exception6)

    {



    lblMsg.Text = exception6.Message.ToString();

    return;

    }



    }



    // lblMsg.Text = lblMsg.Text + this.SuccessMessage;

    }

    else

    {



    // lblMsg.Text = lblMsg.Text + this.ErrorMessagePasswordMatch;

    }

    }

    else

    {



    lblMsg.Text = "Password doesn’t match requirements.";

    }





    }

    Add new element in the web.config file using sharepoint

    If you can add new element the web.config file using sharepoint administration SPWebConfigModification Object that have open web.config file and find the appropriate element tag in the web.config file and add new element in the web.config.

    You can use this code in the feature actived.


    try

    {

    SPWebApplication app = null;

    SPWeb web = null;

    SPSiteCollection site = properties.Feature.Parent as SPSiteCollection;

    if (site == null)

    {

    web = properties.Feature.Parent as SPWeb;

    if (web != null)

    app = web.Site.WebApplication;

    }

    else

    app = site.WebApplication;

    SPWebConfigModification modification = new SPWebConfigModification();

    modification.Name = "add [@Assembly='System.DirectoryServices'] [@Version='2.0.0.0'][@Culture='neutral'][@PublicKeyToken='B03F5F7F11D50A3A']";

    modification.Path = "configuration/system.web/compilation/assemblies";

    modification.Value = @"DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A'/> ";

    modification.Owner = Assembly.GetExecutingAssembly().FullName;

    modification.Sequence = 0;

    modification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;

    app.WebConfigModifications.Add(modification);

    SPFarm.Local.Services.GetValue<SPWebService>().ApplyWebConfigModifications();

    }

    catch (Exception ex)

    {


    }


    The example code could be changed easily to remove the configuration change, as in the following example:

    app.WebConfigModifications.Remove(modification);

    Add new feature in personal menu

    Here is a feature.xml and elements.xml that can add new menu in the person menu item.

    <Feature Id="50E6274F-668C-4f5f-AC85-7DE468957230" Title="My site" Description="My site"
    Version="1.0.0.0" Scope="Web" xmlns="http://schemas.microsoft.com/sharepoint/"
    ReceiverAssembly="trushar.trushar, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b44e792107d2d835"
    ReceiverClass="trushar.trushar.trushar"
    >

    <ElementManifests>
    <ElementManifest Location="elements.xml"/>
    </ElementManifests>
    </Feature>


    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <CustomAction Id="PersonalActionsMenu_MyMenu" GroupId="PersonalActions"
    Location="Microsoft.SharePoint.StandardMenu" Sequence="101"
    Title="My Menu"
    Description="My Menu"
    ImageUrl="_layouts/images/menuprofile.gif" >
    <UrlAction Url="~site/_layouts/test.aspx"/>
    </CustomAction>
    </Elements>

    Saturday, September 27, 2008

    URL Action parameters while creating an Custom Feature

    While we have creating custom features for adding new menus in the Edit Context Menu (the menu that pops up when you place the mouse on a list item) you might need to specify the

    You might notice the parameters like {SiteUrl},...here is the list of possible query string parameters and their description

    {ItemUrl} - URL of the item being acted upon. Only work for documents in libraries.

    {SiteUrl} - URL of the Web site (SPWeb).

    {ListId} - GUID that represents the list.

    {RecurrenceId} - Recurrence index. This token is not supported for use in the context menus of list items.

    {ItemId} - Integer ID that represents the item within a list.

    Note: You can also use the following parameters to get the link of current Site / Web without hardcoding it in the XML File

    Windows SharePoint Services supports the following tokens with which to start a relative URL:

    ~site - Web site (SPWeb) relative link.

    ~sitecollection - site collection (SPSite) relative link.

    Eg:

    Friday, September 26, 2008

    Problems with Special Characters in XSLT

    Problem:
    When you use Special Character like '&' and '<' during XSLT transformation, they are not rendered properly.
    Eg. Expected Output:SharePoint data & SharePoint
    Output:SharePoint data & SharePoint

    Reason:
    This is the normal behaviour if you consider the XSLT specification :
    "Normally, the XML output method" (the default method)" escapes '&' and '<' (and some other characters)
    when outputting text nodes" (i.e. when using or nodes). Resolution:
    You can disable this feature by setting the 'disable-output-escaping' attribute to 'yes' in these nodes.

    Solution :
    In your xsl file, replace your:

    <xsl:value-of select="@href">

    To
    <xsl:value-of select="@href" disable-output-escaping="yes">

    This form template is browser-compatible, but it cannot be browser-enabled on the selected site

    You receive the following message when you try to publish a browser-compatible InfoPath 2007 form template to a SharePoint server with or without Forms Services: "This form template is browser-compatible, but it cannot be browser-enabled on the selected site".

    Reason:
    Infopath is compatible to be able to display in browser , but SharePoint is not configured for the same.

    Solution :

    Configure Forms Services to allow users to browser-enable form templates.

    Steps:
    1. Open SharePoint 3.0 Central Administration.
    2. On the Central Administration page, click on the Application Management tab.
    3. On the Application Management page, under InfoPath Forms Services, click Configure InfoPath Forms Services.
    4. On the Configure InfoPath Forms Services page, select the Allow users to browser-enable form templates checkbox.
    5. Close the InfoPath 2007 client application.
    6. Open the InfoPath form template again.
    7. Try publishing the template again.

    SharePoint Stsadm command line parameters

    Configuring Multiple Authentication Providers for SharePoint 2007


    http://blogs.msdn.com/sharepoint/archive/2006/08/16/configuring-multiple-authentication-providers-for-sharepoint-2007.aspx

    Forms Based Authentication in Office SharePoint Server 2007 and Windows SharePoint Services 3.0

    Here is the link for form authentication in wss 3.0/Moss 2007 that can helpful to integration in sharepoint.

    http://blogs.msdn.com/sharepoint/archive/2007/12/17/forms-based-authentication-in-office-sharepoint-server-2007-and-windows-sharepoint-services-3-0-authoritative-technical-articles-published.aspx

    Monday, September 22, 2008

    DateTime in CAML Query

    Caml query not using the time part in datetime. If your are doing a caml query and you see that your time is being ignored in datetime try this:

    <Value Type=”DateTime” IncludeTimeValue=”TRUE”><Today /></Value>

    You have to use IncludeTimeValue=”TRUE”.

    You can use greator or equal like above and less or equal filter with AND operator in CAML above to work with date range.

    If the date value is coming from your variable etc then you need to use SPUtility function and get the string required by CAML for date time variable.

    DateTime CustomDate = DateTime.Now;
    string strCustomDate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(CustomDate);

    This CAML Query below return the items based on MyDate with less than 10 days.
    Basically using a Greator or Equal operatior and providing Today date - 10 days as a filter.

    <Query>
    <Where>
    <Geq>
    <FieldRef Name="MyDate" />
    <Value Type="DateTime">
    <Today OffsetDays="-10" />
    </Value>
    </Geq>
    </Where>
    </Query>

    Saturday, September 20, 2008

    SPListItem.Update() throws error Operation is not valid due to the current state of the object.

    Problem:
    When running SPListItem.Update commands inside SPSecurity.RunWithElevatedPrivileges block in the .net application in the sharepoint virtual directory environment then you get error: Operation is not valid due to the current state of the object.

    When you can add the procedure in the SPSecurity.RunWithElevatedPrivileges block then some time also Call Stack error has occured.
    When you can install your webpart or Usercontrol in the sharepoint page then this type error is not occurred.
    Instead you should instantiate the SPSite or SPWeb there and call Update afterwards.

    Monday, September 15, 2008

    Get Public Key Token(PKT) in VS 2005 for signed assembly

    Here is the easiest way to get public key token in the vs 2005.
    1. In Visual Studio 2005, click Tools -> External Tools...
    2. Click Add and enter the following into the different fields.
    * Title: Get Public Key
    * Command: C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\sn.exe
    * Arguments: -Tp "$(TargetPath)"
    * Uncheck all options, except Use Output window\

    How to Restrict access to MOSS Web Services?

    Here is the methode for restrict access to web services in the MOSS.

    In order to restrict that we can add an entry in web.config file of that Site Collections web application.
    Add the following block

    <location path="_vti_bin">
    <system.web>
    <authorization>
    <allow users="sps\user" />
    <deny users="*" />
    </authorization>
    </system.web>
    </location>






    Thursday, September 11, 2008

    Forms authentication and SharePoint Designer

    The SharePoint designer always works with Windows authentication mode only. So, if you have converted your site to use forms authentication, you will not be able to open in the designer.

    Hence, even if you are going to have an Internet facing site, the best practice would always be to have your default zone site with windows authentication and extend this for the Internet zone.

    Steps to do this is available all around the place, check this for a start.

    http://technet.microsoft.com/en-us/library/cc262668(TechNet.10).aspx

    Wednesday, September 10, 2008

    Maximum Versions Settings on Lists and Document Libraries


    Versioning is a powerful feature of SharePoint-based lists and document libraries.

    In document library and list,every time when change the item then it taks extra sizes so database size is increase.
    Many organizations may wish to limit the amount of major versions that are kept.
    However, this setting is determined by each individual list - but one can easily change this setting via the WSS.
    Here is the programatically you can change the limit of the maximum version through the event handler or in your webpart.

    public void VersionSettingLimit(string siteUrl)
    {

    SPSite site = new SPSite(siteUrl);
    SPWeb web = site.OpenWeb();
    web.AllowUnsafeUpdates = true;
    SPListCollection listColl = web.Lists;
    foreach (SPList list in listColl)
    {
    try
    {
    list.MajorVersionLimit = 2;
    list.Update();
    }
    catch (Exception setVersionException)
    {
    }
    }
    }



    Tuesday, September 9, 2008

    Programmatically uploading an attachment to a list item in WSS3/MOSS 2007

    If you need to upload a file into a SharePoint document library through code following code is helpful.

    SPList list = web.Lists["MyList"];
    if (list != null)
    {
    web.AllowUnsafeUpdates = true;
    SPListItem item = list.Items.Add();
    item["Title"] = "my title";

    if (fileAttachment.PostedFile != null && fileAttachment.HasFile)
    {
    Stream fStream = fileAttachment.PostedFile.InputStream;

    byte[] contents = new byte[fStream.Length];
    fStream.Read(contents, 0, (int)fStream.Length);
    fStream.Close();
    fStream.Dispose();

    SPAttachmentCollection attachments = item.Attachments;
    string fileName = Path.GetFileName(fileAttachment.PostedFile.FileName);
    attachments.Add(fileName, contents);

    }

    item.Update();
    web.AllowUnsafeUpdates = false;

    }