Friday, June 11, 2010

Shared Service Provider Creation Provisioning Failed

When you create Shared Service Provider, you can get the following error: Shared Service Provider Provisioning Failed: user can't be found. Shortly when you create SSP, the job will create a site collection for administration site of SSP and the job make the users who are site collection administrators of central administration as site collection administrators for the site collection of SSP. but when the site collection administrators of central administration are wrong, the job will failed. So to fix it, just do the following:
1. Go to central administration site collection and set the site collection administrators correctly.
2. Execute the following command: stsadm -o execadmsvcjobs .


Sunday, February 28, 2010

Login failed for user 'Domain\UserName'. [CLIENT: IP address] with SharePoint Farm | Deleting SSP Shared Service Provider

Of course when you get this error in SQL server, you thought that there is a process which is trying to connect with SQL Server with wrong user name or password. But with SharePoint Environment and when you delete SSP and its associated database, you will get this error and the reason is: when you delete SSP, SharePoint does not delete the JOB which is responsible for deleting expired sessions so this job is working each minutes and try to connect to SSP database, therefore you should delete this job manually after deleting SSP.

Tuesday, February 23, 2010

How to delete or truncate large table

In this post I’ll explain how to empty large table. One of our customers had a table with 450GB of size. And we tried all ways to empty this table, but no one has solved the problem.

We tried to truncate the table, but truncate operation took more than 10 hours and didn’t solve the problem. And when we used WHERE statement in any query on this table, SQL server executes the query without stopping.

The only way that I could to empty the table in 1 second was as the following:

set rowcount 1;

truncate table TABLE_NAME;

And of course after truncating the table, just go and shrink the database.


Friday, October 9, 2009

Custom Paging in SharePoint List

To do custom paging in SharePoint list, just we should calculate the position of last item (ListItemCollectionPosition) and pass it to the query. The steps to do paging are as following:

1. Get the previous page last SPList Item. And then generate the paging filter string as following:

SPList assetList = web.Lists[listName];

SPQuery query = new SPQuery();

query.Query = camel;

query.RowLimit = (uint)(pageItemCount * (pageIndex - 1));

assetDetailsItems = assetList.GetItems(query);

int previousPageLastItemPosition = assetDetailsItems.Count - 1;

StringBuilder columnBuilder = new StringBuilder();

if (columnNames != null)

{

foreach (string column in columnNames)

{

string columnValue = (assetDetailsItems[previousPageLastItemPosition][column] == null) ? string.Empty : assetDetailsItems[previousPageLastItemPosition][column].ToString();

columnBuilder.Append("&p_" + column + "=" + columnValue);

}

}

2. Create SPListItemCollectionPosition object based on columns details which retieved in step 1.

SPListItemCollectionPosition objSPListColPos = new SPListItemCollectionPosition("Paged=TRUE"

+ columnBuilder.ToString());

query.ListItemCollectionPosition = objSPListColPos;

3. Pass the SPQuery to the GetItems function, which will fetch items starting from the position that we created in step 2.

assetList.GetItems(query);

The following function does the paging for you, and in each calling, it will calculate first the total items count and then generate the last position for the page index parameter and finally get the items by using GetItems Function.

public static DataTable GetItems(string webSite, string listName, string camel,string viewFields, string[] columnNames, int pageIndex, int pageItemCount,out int ItemsCount)

{

SPListItemCollection assetDetailsItems = null;

using (SPSite site = new SPSite(webSite))

{

using (SPWeb web = site.OpenWeb())

{

// Get the list

SPList assetList = web.Lists[listName];

SPQuery query = new SPQuery();

query.Query = camel;

if (!string.IsNullOrEmpty(viewFields))

{

query.ViewAttributes = "Scope='RecursiveAll'";

query.ViewFields = viewFields;

}

// first calculate the totla items count

assetDetailsItems = assetList.GetItems(query);

ItemsCount = assetDetailsItems.Count;

// Retrieve the items for the last page. E.g.: If request is for 5th page and item count/page=10 then row limit will retrieve 40 items and 40th item will be used to get the column details which will be used for pagination.

query = new SPQuery();

query.Query = camel;

if (!string.IsNullOrEmpty(viewFields))

{

query.ViewAttributes = "Scope='RecursiveAll'";

query.ViewFields = viewFields;

}

query.RowLimit = (uint)(pageItemCount * (pageIndex - 1));

assetDetailsItems = assetList.GetItems(query);

// Get the previous page last item position. Use this item to retrieve the column details which will be used for pagination.

int previousPageLastItemPosition = assetDetailsItems.Count - 1;

// generate the last position

StringBuilder columnBuilder = new StringBuilder();

if (columnNames != null)

{

foreach (string column in columnNames)

{

// Make sure that if the field value is mandatory and if you are passing it as NULL then SPList.GetItems will throw exception.

string columnValue = (assetDetailsItems[previousPageLastItemPosition][column] == null) ? string.Empty : assetDetailsItems[previousPageLastItemPosition][column].ToString();

// Check if the value is null or empty

columnBuilder.Append("&p_" + column + "=" + columnValue);

}

}

query = new SPQuery();

query.Query = camel;

if (!string.IsNullOrEmpty(viewFields))

{

query.ViewAttributes = "Scope='RecursiveAll'";

query.ViewFields = viewFields;

}

// Create Paging Information which will be used for retrieving paging based items

SPListItemCollectionPosition objSPListColPos = new SPListItemCollectionPosition("Paged=TRUE"

+ columnBuilder.ToString());

query.RowLimit = uint.Parse(pageItemCount.ToString());

// check if the page index = 1,that mean no need for list position

if (pageIndex != 1)

query.ListItemCollectionPosition = objSPListColPos;

// Execute the CAML query.

assetDetailsItems = assetList.GetItems(query);

}

}

return assetDetailsItems.GetDataTable();

}

[Note: we can increase the performance of the code by storing the last calculated position in view state and don't generate it each time, but in this case we can do paging not by numbers but with next and previous functionality]

Monday, June 22, 2009

How to create Mailbox in Exchange Server 2007 programmatically

If you have exchange server 2007 or you want to upgrade from exchange server 2003 to exchange server 2007. And you want your end user to create his email on exchange from your application or portal. Of course in exchange 2003 we can use CDOEXM to create mailboxes programmatically. But in exchange server 2007 doesn't support CDOEXM. Therefore to do this, we should depend on Power Shell in creating mailboxes.

The prerequisites are just to install power shell on your web server and of course you need to install the Exchange Server Management Tools on the server that will execute the code.
After that you can use this function:

public static IList CreateEmail(string userName, string mail, string domain, string ou, string exDatabase)
{
//create the command
string cmd = string.Format("Enable-Mailbox -Identity '{0}/{1}/{2}' -Alias '{3}' -Database '{4}'", domain, ou, userName, mail, exDatabase);
ExchangeManagementShellWrapper ems = ExchangeManagementShellWrapper.Instance;
ICollection results;
IList IErrors;

results = ems.RunspaceInvoke(cmd, out IErrors);

return IErrors;

}

Of course this function needs user name, mail (the name that you want to be user email), domain, ou (which represents the organization unit path, which this user is existed on), and exchange database. And by using ExchangeManagementShellWrapper you can run this command and get the result.

for source code of ExchangeManagmentShellWrapper, you can download it from internet or anyone who need it,I can send it to him by email.

Monday, June 15, 2009

Custom Field Type in SharePoint: Upload File, Image, Video

Custom Field Type: Upload File, Image, Video


In this post I'll explain how you can create a custom field type, which enables end user to upload files, images and videos to document library and attach these files to pages in one step in edit properties of the page.
I build this custom field type according to these requirements, which were:


- The end user wants to attach a file to page in edit properties form.
- The user doesn't want to go first to document library or image library and upload the file and then go back to edit form page and choose the file, he want to use Upload File Control to choose the file from his device in the edit properties form of the page directly.
- The Admin wants to set the maximum size of files that user will upload.
- The Admin wants to set the allowed extensions for uploaded files.
- The Admin specify where these files will be stored inside the site.


Therefore I build a custom field type with these features:
When you define a site column from Upload File Type, you
- Set the URL of the site that contains the document library that you want to store files in.
- Choose the document library that you want to store files in.
- Set the allowed extensions.
- Set the maximum file size.


The value of this field will be string, which represent the URL of the file. To build this custom field we should create the following:



1. The Editor Control, which appear when you define the site column of this custom field type. In this editor we should save the URL of the site, the document library, allowed extensions and maximum file size as the following:








This user control (Editor) should implements IFieldEditor and should inherit UserControl. So we should implement the InitializeWithField function and OnSaveChange as following:

public void InitializeWithField(SPField field)
{
try
{
fldUploadImageField = (UploadImageField)field;

if (Page.IsPostBack) return;

labelDescription.Text = ResourceManager.GetResource("labelDescription");
labelDocLib.Text = ResourceManager.GetResource("ImagelabelDocLib");
labelWebUrl.Text = ResourceManager.GetResource("labelWebUrl");
labelExtensions.Text = ResourceManager.GetResource("labelExtensions");
labelMaxFileSize.Text = ResourceManager.GetResource("labelMaxFileSize");
txtMaxFileSize.Text = ResourceManager.GetResource("txtMaxFileSize"); // as default value to max size
btnLoadDocLibs.Text = ResourceManager.GetResource("btnLoadDocLibs");

if (field != null)
{
txtExtensions.Text = fldUploadImageField.AllowedExtensions;

txtWebUrl.Text = fldUploadImageField.FieldToInsertLink;

fillDocLibraries(ddlDocLib, txtWebUrl.Text.Trim());

txtMaxFileSize.Text = fldUploadImageField.MaxFileSize;

// set values from field properties
ddlDocLib.SelectedValue = fldUploadImageField.DocumentLibraryName;

}



}
catch (Exception ex)
{
labelError.Text += string.Format("Error in InitializeWithField: {0}
", ex);
}
}

2. Creating Field Class which inherits SPFieldText : this class represents the particular field and should contains a properties which represent URL, document library, files allowed extensions and maximum file size as following:

public string DocumentLibraryName
{
get { return GetCustomProperty("DocumentLibraryName") + ""; }
set { SetCustomProperty("DocumentLibraryName", value); }
}

public string FieldToInsertLink
{
get { return GetCustomProperty("FieldToInsertLink") + ""; }
set { SetCustomProperty("FieldToInsertLink", value); }
}

public string AllowedExtensions
{
get { return GetCustomProperty("AllowedExtensions") + ""; }
set { SetCustomProperty("AllowedExtensions", value); }
}

public string MaxFileSize
{
get { return GetCustomProperty("MaxFileSize") + ""; }
set { SetCustomProperty("MaxFileSize", value); }
}


3. A field Control which should inherits from BaseFileFieldControl:
In this class we should implement the following properties and functions:
o Value Property: which is used to set and get the value of the field.
o CreateChildControls: this function is used when the control is drawn in edit mode of the page or in edit properties form.
This function will draw the control as following:











o RenderFieldForDisplay: which is used when the page is in display mode, in this function if the file type is image, then we should render it as image tag and it'll appear in the page as following:



















And if the file is video, we should render it as object tag and it'll appear as following:





And if the file is document, we should render it as link tag as following:







o Validate: which is used to validate the value of the fields like maximum file size or validate on file extension.

4.Xml file which contains the information that the WSS needs to correctly render the field as following :

Thursday, October 30, 2008

How to generate a template in SharePoint 2007 with solving all problems which will face...

How to generate a template in SharePoint 2007 and fix all problems you will face:

I have a task to create more than 5000 site from a temple, during my work, I faced many problems and I tried to solve them: 1. When we save a site as template, all sub sites don’t included in the template, so we should create a site programmatically and then create sub site inside it also programmatically as following:

private static SPWeb createSite(SPWeb parentWeb, string siteURLRequested, string siteTitle, string siteTemplateName, int Language_ID, bool useUniquePermissions, bool inherentNavigation)

{

if (parentWeb.Webs[siteURLRequested].Exists)

{

parentWeb.Webs.Delete(siteURLRequested);

}

SPWeb newWeb = parentWeb.Webs.Add(siteURLRequested, siteTitle, "", Convert.ToUInt32(Language_ID), siteTemplateName, useUniquePermissions, false);

newWeb.Navigation.UseShared = inherentNavigation;

newWeb.Update();

}

2. When we create a site from a template, we encounter an error that the home page didn’t see its layout: To solve this problem we should create a new default page from empty web part layout. So all default pages in the site and its sub sites should be created from a new layout or empty web part layout.

3. 3. When we have a content query web part in parent site and the web part display data from its sub sites, we will notice in our generated sites this web part don’t display data, because the ListGuid in the web part is wrong .

4. To solve this problem : we should detach the page from page layout then go to the web part and delete the ListGuid Attribute from web part and then our web part will work correctly, also this web part will display the data when we generate the site from template.

4. For the Data Web Part , we should exchange the ListID with ListName in Select Parameter Tag.

After you apply step 2, 3, and 4 , save your site and sub site as template , then generate site from that template and you will notice that your generated site will work correct.