Showing posts with label SharePoint. Show all posts
Showing posts with label SharePoint. Show all posts

Thursday, December 22, 2011

SharePoint Batch Deleting List Items Programatically

While working on a custom SharePoint solution, I had a requirement to delete multiple list items one time rather than deleting one by one.
Example: Delete only the items from a list which doesn't have value for a custom column.

When i think of the solution i couldn't make new SPListItemCollection object out of the items which needs to be deleted, which is possible in regular c# application development.
However in SharePoint we can do the batch delete of list items using CAML script.
The CAML script needs to be generated for the items which needs to be deleted as below.

Get the list items:
SPListItemCollection items = spList.Items;
Generate CAML Script:
StringBuilder methodBuilder = new StringBuilder();

string batchFormat = "" +
"{0}"; //{0}-methodFormat

string methodFormat = "" + //{0}-Unique Value for each Item
"{1}" + //{1}-List Guid
"{2}" + //{2}-List ItemID
"Delete" +
"";

// Build the CAML delete command script.
foreach (SPListItem item in items)
{
    //get the custom column value
    string customColumnValue = string.Empty;
    if (null != item["CustomColumnName"])
        customColumnValue = item["CustomColumnName"].ToString();
    
    //check whether custom column is empty
    if (string.IsNullOrEmpty(customColumnValue))
    {
        methodBuilder.AppendFormat(methodFormat, item.ID, item.ParentList.ID, item.ID);
    }
}

//batch delete script.  
string batchDeleteScript = string.Format(batchFormat, methodBuilder.ToString());
Execute CAML Script:
spWeb.ProcessBatchData(batchDeleteScript);
Similarly batch updating script can also be generated. Look at the detailed post here for code.

Tuesday, December 20, 2011

SharePoint Check Memory Leaks in Custom Solution Development

In any SharePoint custom solution development, it is very important to make sure there are no memory leaks in the code. If there are any memory leaks the performance will be down and might face unnecessary issues at run-time.
While developing the code every developer ensures that SPSite and SPWeb objects are disposed either way (using clause or dispose method). But in a bigger solutions there are always chances for missing them in manual verification.

How good if there is a tool available to verify whether our solution (code) has any memory leaks, which can be checked in seconds of time. Yes there is a tool for the same. You can download it from SPDisposeChecker.

Even you can make this Tool as part of your visual studio Tools. Follow the simple 3 steps.

SharePoint Read Resource File Programatically

SharePoint custom solution development might requires some dynamic or configuration values. Generally the high level configurations can be stored in web.config(Ex: external connection string). But if there are more number of configurations required (Es: List columns, Content type names etc.,) we cannot store them in .config file as it is not safe.

So here the resource file comes into picture. Resource file is XML-Based file which holds the data in key-value pair. Resource file is generally used to store huge configurations for re-usability & consistency and Localization.

Resource file (.resx) should be added to 12\Resources directory in the solution as a new item.
The name format is SampleResourceFile.en-US.resx

Usage:
If the solution provides provisioning of lists or libraries with multiple columns programatically using either code or xml, All the column names can be stored in Resource file as a Key-Value pair.

Read Resource File: XML
The resource value for a key can be read in XML as below.
Read Resource File: C# Code
The resource value for a key can be read in c# as below.
string customColumnNameKey = SPUtility.GetLocalizedString("$Resources:CustomColumnNameKey", SampleResourceFile, (uint)CultureInfo.CurrentCulture.LCID); //LCIT is current local languare
To read the resource file programatically, a common wrapper class can be created to read the resource file throughout the solution by passing the key.
public class Resources
{
    /// Resource File Name.
    /// Filename can be configured in web.configured or can be used as constant.
    private const string RESOURCE_FILE_NAME = "SampleResourceFile";

    /// Method to get the singleton instance.
    public static string GetValue(string key)
    {
        return SPUtility.GetLocalizedString("$Resources:" + key, RESOURCE_FILE_NAME, (uint)CultureInfo.CurrentCulture.LCID);
    }
}

string customColumnName = Resources.GetValue("CustomColumnNameKey");

Tuesday, August 23, 2011

How To Repair SUSPECT Database

Sometimes we see a SharePoint error "Cannot connect to the configuration database". One of the reasons for this could be the Respective DataBase is set to SUSPECT mode.

Reasons for database SUSPECT state:
1. Database corruption.
2. Not enough space for the SQL Server to recover the database during startup.
3. Insufficient memory or disk space.
4. Unexpected SQL Server Shutdown, Power failure or a Hardware failure.

Follow the below steps to repair the SUSPECT database:
1. Identify all the databases which are in SUSPECT mode
USE master
GO
SELECT NAME,STATE_DESC FROM SYS.DATABASES 
WHERE STATE_DESC='SUSPECT'
GO
Note:Check the latest log for the database which is marked as suspect.
SQL Server -> Management -> SQL Server Logs

2. Get the database first into EMERGENCY mode to repair it
USE master
GO 
ALTER DATABASE "databasename" SET EMERGENCY
GO
Note: The EMERGENCY database is one way which means read-only.

3. Repair the Database in emergency mode
DBCC checkdb('databasename')
ALTER DATABASE "databasename" SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DBCC CheckDB ('databasename', REPAIR_ALLOW_DATA_LOSS)
ALTER DATABASE "databasename" SET MULTI_USER

Thursday, August 11, 2011

SharePoint Feature Activation Dependency

Scinario:
While provisiong two dependent(one on the other) content/solutions through different features, it is that one of the features might need the resources of other while gettting activated. In this scinario the first feature should be activated before the second, to avoid the dependency issues.

Example:
Feature 1. Custom Content Type
Feature 2. Page with Custom Content Type (dependent on custom content type)

To make sure the same through feature provisioning instead manually, we have feature activation dependency attribute which can be specified in feature.xml file. Which doesn't allow to get activated unless until the dependency feature(s) is activated.




Note: Multiple dependencies can be specified for one feature.

SharePoint PageViewer WebPart Resize Issue

SharePoint OTB PageViewer works fine to display a static web page. But it has a Resizing issue when the source web page has some links which redirects to some other target pages (of more dimentions than source page) within the PageViewer webpart.

Issue/Scinario:
1. A custom search page of height 500x300 is added to pageviewer.
2. The results page with 2 results resize to 300x200.
Now say the result item link redirects to new web page of dimensions 600x500. As pageviewer doesn't support resizing the new page will be shown in 300x200 dimensions.

Solution:
A Content Editor WebPart instead PageViewer WebPart can be used with below iframe and source script to address the resize issue.

Limitations:
The content editor webpart height and width should be set to fixed values(for best page view).




Wednesday, August 10, 2011

SharePoint Copy Survey from One Server to Another

Migrating the survey list from one location(server) to another location(server) is very simple, if we go for list template. But this process doesn't work if the requirement demands for the existing responses along with survey details.

Though it copies all the survey details and responses details, the responded user(created by and modified by) and datetime (created and modified) details are replaced with current user (who is creating the survey with the template) and current datetime details.

To copy the survey as is (all questions and responses) i found a nice codeplex tool SharePoint Content Deployment Wizard. The post has the detailed documentation on what it can do and how can be used.

This also works with limitations:
The settings of the source Survey should be set as follows before copying.
Go to Survey list -> Survey Settings
1. Allow multiple responses (Yes)(Advanced Settings)
2. Edit access: Specify which responses users can edit
All responses (Yes)(Title, Description and Navigation)
After copying the survey, the settings can be again changed to earlier state.

It also helps in copying the following as well.
- site collections
- webs
- lists
- folders
- list items (including files)

Tuesday, August 9, 2011

SharePoint ListItem New, Edit and Display forms Dynamic URLs

Getting the SharePoint List Item form URLs(New, Edit ad Display) dynamically respect to the context instead of hard-coding.

SPListItem listItem = SPList.GetItemById(itemID);

// New form full url
string newFormFullUrl = string.Format("{0}{1}?ID={2}", listItem.Web.Url, listItem.ParentList.Forms[PAGETYPE.PAGE_NEWFORM].ServerRelativeUrl, listItem.ID);

// Edit form full url
string editFormFullUrl = string.Format("{0}{1}?ID={2}", listItem.Web.Url, listItem.ParentList.Forms[PAGETYPE.PAGE_EDITFORM].ServerRelativeUrl, listItem.ID);

// Display form full url
string displayFormFullUrl = string.Format("{0}{1}?ID={2}", listItem.Web.Url, listItem.ParentList.Forms[PAGETYPE.PAGE_DISPLAYFORM].ServerRelativeUrl, listItem.ID);

//Relative Url
string newFormRelativeUrl = string.Format("{0}?ID={1}", listItem.ParentList.Forms[PAGETYPE.PAGE_NEWFORM].ServerRelativeUrl, listItem.ID);

Monday, March 14, 2011

SharePoint Write Custom Error to Log file (ULS Error Logging)

Most of the requirements in sharepoint applications needs custom development i.e., web parts, workflows, event recievers, timer jobs etc.,
And we might need to write the exception/error details to log somewhere(list or text file in the file sytem).

As all the sharpoint error details are logged in 12 hive Log files, even we can write our custom error details to the same log file by using the ULS logging.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
//Reference of Microsoft.Office.Server.dll needs to be added
Microsoft.Office.Server.Diagnostics.PortalLog.LogString("My Custom Error - Message:{0} || Stack Trace:{1}", ex.Message, ex.StackTrace);
});
Note: the logging code statement should be run under RunWithElevatedPrivileges, if the code is executable by end user.

Tuesday, March 8, 2011

SharePoint PictureLibrary Thumbnail Url Vs Picture Url

I had hard time to get the complete Url of the picture as well thumbnail directly (using any property) inserad of managing with server relative/absolute url, thumbanil folder /t and the picture name.

But we have full control through SPObject Model(SPBuiltInField class) to get the picture/thumbnail Url directly.
SPList spList = web.Lists["ImagesLibrary"];
SPListItem item = spList.Items.GetItemById(itemID);

//Thumbnail Url
string thumbnailUrl = item[SPBuiltInFieldId.EncodedAbsThumbnailUrl].ToString();

//Picture Url
string pictureUrl = item[SPBuiltInFieldId.EncodedAbsUrl].ToString();
The above Urls are the full Urls of the thumbnail and picture respectively.

To get the absolute, relative Urls of the picture the Url can be managed as below.
Uri uri = new Uri(thumbnailUrl);
string relativePath = uri.AbsolutePath;

Thursday, February 24, 2011

Webpart to render New Form dynamically for a list item

To generate/render a new form in a webpart dynamically to create/add a list item. Where the field name, type of each field will be fetched and rendered respectively. It holds the full control on all the properties of a column.
//Create the table object that we are going to add the rows and cells to for our data entry form
Table tbl = new Table();
tbl.CellPadding = 0;
tbl.CellSpacing = 0;

// Get the site that this web part is running on.
SPWeb spWeb = SPContext.Current.Web;

// Get the list we are going to work with
SPList spList = spWeb.Lists["MyList"];

// Loop through the fields
foreach (SPField spField in spList.Fields)
{
// See if this field is not hidden
if (!spField.Hidden && !spField.ReadOnlyField && spField.Type != SPFieldType.Attachments)
{
// Create the label field
FieldLabel fieldLabel = new FieldLabel();
fieldLabel.ControlMode = SPControlMode.New;
fieldLabel.ListId = spList.ID;
fieldLabel.FieldName = spField.InternalName;

// Create the form field
FormField formField = new FormField();
formField.ControlMode = SPControlMode.New;
formField.ListId = spList.ID;
formField.FieldName = spField.InternalName;

// Add the table row
TableRow tblRow = new TableRow();
tbl.Rows.Add(tblRow);

// Add the cells
TableCell tblLabelCell = new TableCell();
tblRow.Cells.Add(tblLabelCell);
TableCell tblControlCell = new TableCell();
tblRow.Cells.Add(tblControlCell);

// Add the control to the table cells
tblLabelCell.Controls.Add(fieldLabel);
tblControlCell.Controls.Add(formField);

// Set the css class of the cell for the SharePoint styles
tblLabelCell.CssClass = "ms-formlabel";
tblControlCell.CssClass = "ms-formbody";
}
}

// Create the save button
SaveButton btnSave = new SaveButton();
btnSave.ControlMode = SPControlMode.New;
btnSave.ListId = spList.ID;

// Create the row for the save button
TableRow tblButtonRow = new TableRow();
// Create the cell for the save button
TableCell tblButtonCell = new TableCell();

tblButtonCell.ColumnSpan = 2;
tblButtonRow.Cells.Add(tblButtonCell);
tbl.Rows.Add(tblButtonRow);

// Add the table to the web part controls collection
this.Controls.Add(tbl);

Friday, July 16, 2010

SharePoint overriding the Core.css styling for specific site

The standard default core.css file is located in …\12\TEMPLATE\LAYOUTS\1033\STYLES. This STYLES folder is a virtually mapped via the /_layouts virtual directory that is mapped to each and every site in SharePoint.  So, the core.css file is accessible to every site by simply using the URL of “/_layouts/1033/styles/core.css”.  For every page that SharePoint renders, it renders a link to the core.css using this path. 

However, for any site that has been configured to use a custom core.css style sheet via the CustomizeCss method on the SPWeb class, the URL rendered in each page references a core.css file located in a different location.  This is accomplished in C# by the following code where web is an instance of the SPWeb class for the web site of your choice.

web.CustomizeCss(“core.css”);
web.Update();

The CustomizeCss(“core.css”) statement tells SharePoint to use a custom copy of the SharePoint core.css file.  Once this CustomizeCss method is executed, a copy of the core.css file found in the …\12\TEMPLATE\LAYOUTS\1033\STYLES folder is copied to the folder (access this by Sharepoint Designer) named "_styles" on the applied site.  

Modifying this core.css file will affect only the current site. 

Reverting this site back to using the original global (un-customized) copy of the core.css file can be accomplished just a easy using the following code.

web.RevertCss(“core.css”);
web.Update();

Executing the RevertCss method does not remove the custom core.css file on the web site’s “/_styles” folder.  It simply tells the site to no longer use it and to use the original core.css found in the C:\…\12\TEMPLATE\LAYOUTS\1033\STYLES folder; which is the same folder as the as the “/_layouts/1033/styles” folder.

So we now know how to use the CustomizeCss and the RevertCss methods on the SPWeb class to provide an easy way to point the site to a new custom style sheet file.

SharePoint libraries Types and Values

Following is a description for the available types (available in the WSS SDK)

Value Description
100 Generic list
101 Document library
102 Survey
103 Links list
104 Announcements list
105 Contacts list
106 Events list
107 Tasks list
108 Discussion board
109 Picture library
110 Data sources
111 Site template gallery
113 Web Part gallery
114 List template gallery
115 XML Form library
120 Custom grid for a list
200 Meeting Series list
201 Meeting Agenda list
202 Meeting Attendees list
204 Meeting Decisions list
207 Meeting Objectives list
210 Meeting text box
211 Meeting Things To Bring list
212 Meeting Workspace Pages list
300 Portal Sites list.
1100 Issue tracking
2002 Personal document library
2003 Private document library

BaseType

0 — Custom List
1 — Document Library
2 — Not used
3 — Discussion Forum
4 — Surveys
5 — Issues List

so, if you are developing custom picture library set Type="109" and BaseType="1" (because picture library mainly based on document library)

Wednesday, May 5, 2010

SharePoint Document Library Open Excel File in Browser

The excel file uploaded to the document library (Excel) by default will be opened in the Microsoft Office Excel Application. To open any newly added excel file in browser, following configuration is required.

Open Library --> Settings --> Document Library Settings --> Advanced Settings (under general settings) --> Browser-Enabled Documents section --> Display as web page --> hit OK button






Then the excel file which needs to be open in browser must be published to the library rather than uploading directly. To publish the excel file follow the below steps.

Open Excel File --> Office Button --> Publish --> Excel Services
Then a dialog box opens and asks for the file name to save at specific location shown in address bar of that dialog box.
To publish the file in document library type in the URL of the document library URL (http://site/library name) in the address bar and hit ENTER. Now the document should be saved in the library.

Note: Publishing via Excel services unlocks the possibility of making available named cells as parameters to the excel sheet on the web. Named cells can be exposed as parameters by clicking on the "Excel Services Options" box in Microsoft Office Excel 2007, during the publish process. Cells can be named using the DefineName thing on the Formula ribbon/bar. Also, if you wish to limit the publishing to specific sheets, or part of a sheet - you need to use a version of Office that has the ability to publish to Excel services.

After the above settings if the published excel file is tried to open in a web page it gives the following error.
Error : You do not have permissions to open this file on Excel Services.
Make sure that the file in an Excel Services trusted location and that you have access to the file.










To resolve the error/issue few more settings need to be changed/configured in Central Administration. To do so follow the below steps.
1. In SharePoint Central Administration, go to 'Shared Services Administration'
2. Select your shared service. (Default is SharedServices1)
3. In 'Excel Services Settings' section select 'Edit Excel Services settings'.
4. Ensure that File Access method is Process Account. Click OK.
5. Back in 'Excel Services Settings' section and select 'Trusted File Locations'
6. Add a new Trusted file Location:
    URL: Specigy the specific library or the site URL in which the library exists
    Location Type: Windows SharePoint Services
    Trust Children: Children Trusted checkbox should be ON/YES
7. Reset IIS

All the documents published to the library with above settings will be opened in browser when the users clicks on the link of the Excel file in library.

SharePoint Making the Title as required field in Document/Picture library

Scenario:
Document Library has Name as the required field, whereas Title is not. Now making the Title field as required in a Document/Picture Library.

Solution:
Navigate to the Document/Picture Library Settings and enable it by managing content type.

Steps:
1. Go to Document/Picture Library Settings
2. Click on Advanced Settings
3. Select 'Yes' for the option 'Do you want to manage the content types?' and Save
4. Click on 'Document' link under Content Types section
5. You will see all the columns listed
6. Click on 'Title' and now you can make it required field.
7. Save the changes
(OR)
Solution:
By default, the title field doesn’t contain any validation in Document/Picture Library. If it needs to be made as required one, schema.xml of “Document/Picture Library” needs to be customized, which can be found at the following location.
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\Document or Picture Library\DocLib or PicLib
Steps
1. Open the schema.xml from the above location
2. Locate the “Title” field and add the attribute - Required="TRUE" to the tag.

Required="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="Title">
3. Install and activate the feature. Now title field asks for value as it is required.

SharePoint Delete the Title field from Document or Picture Library

“Title” column of a Document/Picture library through object model can’t be deleted and gives an error. This is because the “CanBeDeleted” property of that field has the value “false”. The column will not be deleted even if “AllowDelete” property is set to “true”, after this it gives another error saying that “sealed property can’t be deleted”. To delete the column, schema.xml of “Document/Picture Library” needs to be customized, which can be found at the following location.
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\Document or Picture Library\DocLib or PicLib
1. Open the schema.xml from the above location
2. Locate the “Title” field and change the sealed attribute value as Sealed="TRUE" to the tag.
Sealed="TRUE" SourceID="http://schemas.microsoft.com/sharepoint/v3" StaticName="Title" ColName="nvarchar7"/>

Code for deleting the Title Field:-
using(SPSite siteCollection = new SPSite ("Web Application"))
{
   using(SPWeb parentWeb = siteCollection.OpenWeb())
   {
      SPList oList = parentWeb.Lists["Document/Picture Library Name"];
      SPField oField = oList.Fields["Title"]; //Column name
      oField.AllowDeletion = true;
      oField.Delete();
   }
}

SharePoint Activate/Enable site's mobile view

Scinario: If the mobile view (default) for each site/sub site is not activated, it gives 404 error when the site is accessed in mobile view (http://Site URL/m).

Solution: Activate MobilityRedirect feature (it is not activated by default) through the command line as it is hidden.

stsadm -o activatefeature -name MobilityRedirect -url http://Site URL/

To test if it is activated browse to http://Site URL/m/
If it is working it will redirect you to a page of mobile view, otherwise it will gives a 404 error.

SharePoint Mobile view of the site/sub site

The mobile view of the SharePoint site/sub site can be accessed by adding 'm' after the site/sub site in the url.
1. The mobile home page has a short URL with an "m" folder appended to the end of the regular URL (for example, http://Site URL/m/) that redirects the request to the mobile view's default.aspx page
2. The default.aspx page then redirects the user to the actual home page (http://site or sub site/_layouts/mobile), according to the current site definition type
3. To access this, 'mobile view' needs to be activated for site/sub site. For activation details follow the link.

SharePoint List’s Person or Group field value as c# SPUser objet

Casting the list's Person or Group field value into SPUser object.
using(SPSite spSite = new SPSite("site URL"))
{
   using(SPWeb spWeb = spSite.OpenWeb())
   { 
      SPList spList = spWeb.Lists["List Name"];
      SPListItem spListItem = spList.GetItemByID(itemID);
      string currentValue = spListItem["Person or Group field name"].ToString();
     SPFieldUser userField = (SPFieldUser)spWeb.Lists["List Name"].Fields.GetField("Person or Group field name");
     SPFieldUserValue fieldValue = (SPFieldUserValue)userField.GetFieldValue(currentValue);
     SPUser user = fieldValue.User;

                                          OR

     SPFieldUserValue spFieldUserValue = new SPFieldUserValue(web ,  Convert.ToString(projectItem["Person or Group field name"]));
     SPUser user =  spFieldUserValue.User;
   }
}

SharePoint Change the search button image

To change the search button static(default)  image, attributes
GoImageUrl="image relative path" GoImageUrlRTL="image relative path" needs to be changed.

To change the button hover image, attributes
GoImageActiveUrl="image relative path" GoImageActiveUrlRTL="image relative path" needs to be changed.

*image relative path - /images/search.gif