This blog is moved to
http://amalhashim.wordpress.com
Showing posts with label Sharepoint. Show all posts
Showing posts with label Sharepoint. Show all posts

Friday, October 22, 2010

MOSS | Using WSPBuilder for Creating a List Instance

In this post I am going to explain how we can make use of WSPBuilder for creating a List instance.
First we need to install SharePoint Solution Generator. You can download the same from here
http://download.microsoft.com/download/4/0/b/40b62080-6295-4d63-b396-d779fb9b4449/VSeWSSv12.exe
Now follow the steps for generating List Definition. Here I am going to create a List Definition of a List named “Configurations”
Start SharePoint solution generator
image
Select List Definition and click on Next button
image
Specify the Site Url where the list is present and click Next
image
Select the List and click Next
image
Provide a project name and path, then click Next
image
Click Finish
 image
Before clicking Exit, click “Click here to open the generated solution” and click Exit
image
You can see the “Configurations” folder. Let it be opened. Now open visual studio and create a WSPBuilder project
image
Once the project is created, add a new blank feature
image
Now, copy the folder “Configurations” and paste it under the feature folder as shown below
image
Open the ListDefinition.xml file and copy the following content
image
Once the content is copied, paste it in the elements.xml file as shown below and delete the file "ListDefinition.xml" from visual studion project
image
You can also see ListInstance, make a similar entry in your elements.xml file. Also replace the FeatureId with the FeatureId specified in the feature.xml file
Now build the wsp, deploy it and activate the feature. This will add the list to the site.
Hope this was helpful!!!

Thursday, October 21, 2010

MOSS | Using People Editor Control


People editor can be used whenever we want the user to select user, AD groups or SharePoint groups. For using the control, 1st we need to register the assembly as shown below
<%@ register tagprefix="SharePointWebControls" namespace="Microsoft.SharePoint.WebControls"
assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
Once this is done, we can use the following tag for placing the control
<SharePointWebControls:PeopleEditor ID="ppeUser" runat="server" Rows="1" 
CheckButtonImageName = "/_layouts/Images/user.png" 
BrowseButtonImageName = "/_layouts/Images/addressbook.png"                                   
PlaceButtonsUnderEntityEditor="false" MultiSelect="false" AutoPostBack="true"/>

In C#, the following code demonstrate the usage

this.ppeUser.CommaSeparatedAccounts;

Using the above code we can get information user has selected/entered in the people editor control.

public static void UpdatePeoplePicker(string login, PeopleEditor editor)
{
ArrayList list = new ArrayList();
PickerEntity entity = new PickerEntity();
entity.Key = login;
entity = editor.ValidateEntity(entity);
list.Add(entity);
editor.UpdateEntities(list);
}

The above code can be used to update the People Editor control using code.


We can restrict the selection of the People Editor using the SelectionSet property. It accepts the following values

User – In case the selection to be restricted only for users
AD – In case the selection to be restricted only for AD groups
SPGroup – In case the selection to be restricted only for SharePoint Groups

Hope this was helpful!!!

Monday, August 30, 2010

Custom Application MasterPage | Sharepoint 2007

Recently I have involved in branding one of our clients sharepoint portal. As part of the branding process we needed to modify the application.master file, so even the layout pages  will have the same look and feel. As part of the investigation, we come up with the best approach for doing this.

1. Create a custom master page, with all the placeholders which are available in the original application.master file. Its better to take a copy of the application.master file and add the styles/images etc as you wish

2. Create a custom HttpModule which will set the new custom master page if the current page is having the master page “application.master”. We preferred HttpModule on top of HttpHandler because HttpModule can be deployed only to the web applications we wants, while HttpHandler will hit across all web applications.

Below is the code i have created for the http module.

using System;
using System.Web;
using System.Web.UI;
using Microsoft.SharePoint;

namespace Company.HttpModules
{
/// <summary>
///
All the layout pages will be using application.master
/// inorder to make the application consistent. we have created a custom application master page
/// this module will check whether the current request is having the master page as application.master
/// then change it to our custom page
/// </summary>
public class ApplicationMasterModule : IHttpModule
{
public void Init(HttpApplication context)
{
if (context == null)
throw new ArgumentNullException("context");

context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
}

void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
Page page = HttpContext.Current.CurrentHandler as Page;
if (page != null)
{
page.PreInit += new EventHandler(page_PreInit);
}
}

void page_PreInit(object sender, EventArgs e)
{
Page page = sender as Page;
if (page != null)
{
if (page.MasterPageFile != null)
{
if (page.MasterPageFile.Contains("application.master"))
{


using (SPSite connectSite = new SPSite(SPContext.Current.Site.Url))
{
using (SPWeb currentWeb = connectSite.RootWeb)
{
string url = currentWeb.ServerRelativeUrl + "/_catalogs/masterpage/our_custom_app.master";
page.MasterPageFile = url;
}
}
}
}
}
}

public void Dispose()
{
}
}
}



Now comes the important aspect of deployment. Its better to create the master page as well as http module to be deployed as a feature. See the feature.xml



<?xml version="1.0" encoding="utf-8"?>
<
Feature Id="b1531032-19b5-4fb1-87a6-6892b280c90d"
Title="Custom Application Master Page"
Description="Custom Application Master Page"
Version="12.0.0.0"
Hidden="FALSE"
Scope="Site"
DefaultResourceFile="core"
ReceiverAssembly="Company.MasterPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6c27a5016ad8e167"
ReceiverClass="Company.MasterPages.CustomAppMasterPage"
xmlns="http://schemas.microsoft.com/sharepoint/">
<
ElementManifests>
<
ElementManifest Location="elements.xml"/>
<
ElementFile Location="our_custom_app.master" />
</
ElementManifests>
</
Feature>



and elements.xml file



<?xml version="1.0" encoding="utf-8" ?>
<
Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<
Module Name="CustomApplicationMasterPage"
Url="_catalogs/masterpage"
Path=""
RootWebOnly="False">
<
File Url="our_custom_app.master"
Type="GhostableInLibrary" IgnoreIfAlreadyExists="FALSE">
<
Property Name="ContentType"
Value="$Resources:cmscore,contenttype_-9masterpage_name;" />
<
Property Name="PublishingPreviewImage"
Value="" />
<
Property Name="Description"
Value="Custom Application Master Page"/>
</
File>
</
Module>
</
Elements>



See the Feature Receiver assembly which will add the web.config entries so the HttpModule will work without manually modifying the web configuration file



using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Globalization;
using System.Diagnostics;

namespace Company.UIUpdates
{
/// <summary>
///
On Feature Activation => Add HttpModule Entry in Web.Config file
/// On Feature DeActivation => Remove the HttpModule Entry from Web.Config file
/// </summary>
class CustomAppMasterPage : SPFeatureReceiver
{
static SPWebConfigModification CreateModification(string Name, string XPath, string Value)
{
SPWebConfigModification modification = new SPWebConfigModification(Name, XPath);
modification.Owner = "Custom Application Master Page.wsp";
modification.Sequence = 0;
modification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
modification.Value = Value;
return modification;
}

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
try
{
using (SPSite site = properties.Feature.Parent as SPSite)
{
SPWebApplication webApp = site.WebApplication;
string name = "add[@name='ApplicationMasterModule']";
string path = "configuration/system.web/httpModules";
string value = @"<add name=""ApplicationMasterModule"" type=""Company.HttpModules.ApplicationMasterModule,Company.HttpModules, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f2391931b556f037"" />";
if (webApp != null)
{
SPWebConfigModification modification = CreateModification(name, path, value);
webApp.WebConfigModifications.Add(modification);
webApp.Update();
SPWebService.ContentService.ApplyWebConfigModifications();
SPWebService.ContentService.WebApplications[webApp.Id].Update();
//Applies the web config settings in all the web application in the farm
SPWebService.ContentService.WebApplications[webApp.Id].WebService.ApplyWebConfigModifications();
}
}
}
catch (Exception ex)
{
WriteMessageToEventLog(ex.ToString());
}
}

static private void WriteMessageToEventLog(string message)
{
string EVENT_SOURCE = "CustomAppMasterPage Feature Receiver";
SPSecurity.RunWithElevatedPrivileges(delegate()
{
if (!EventLog.SourceExists(EVENT_SOURCE))
{
EventLog.CreateEventSource(EVENT_SOURCE, "Application");
}

EventLog.WriteEntry(EVENT_SOURCE, message);
});
}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
try
{
using (SPSite site = properties.Feature.Parent as SPSite)
{
SPWebApplication webApp = site.WebApplication;
string name = "add[@name='ApplicationMasterModule']";
string path = "configuration/system.web/httpModules";
string value = @"<add name=""ApplicationMasterModule"" type=""Company.HttpModules.ApplicationMasterModule,Company.HttpModules, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f2391931b556f037"" />";
if (webApp != null)
{
SPWebConfigModification modification = CreateModification(name, path, value);
webApp.WebConfigModifications.Remove(modification);
webApp.Update();
SPWebService.ContentService.ApplyWebConfigModifications();
SPWebService.ContentService.WebApplications[webApp.Id].Update();
//Applies the web config settings in all the web application in the farm
SPWebService.ContentService.WebApplications[webApp.Id].WebService.ApplyWebConfigModifications();
}
}
}
catch (Exception ex)
{
WriteMessageToEventLog(ex.ToString());
}
}

public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{

}

public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{

}
}
}


As part of the WSP, we included the following



1. Custom Master Page



2. Http Module dll which will go into GAC



3. Feature Receiver



Hope this helps. Feel free to contact me if you have any queries.

Wednesday, February 24, 2010

Creating a Timer job in MOSS

First we need to have a class derived from SPJobDefinition

Below is the skeleton of that class.
namespace TimerNameSpace
{
#region Using
using System;
using System.Collections.Generic;  
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;  
using Microsoft.SharePoint.Utilities;
#endregion Using

/// <summary>
/// Timer service
/// </summary>
public class MyTimerService : SPJobDefinition
{
#region Constructor

/// <summary>
/// Initializes a new instance of the TimerService class
/// </summary>
public MyTimerService()
: base()
{
}

/// <summary>
/// Initializes a new instance of the MyTimerService class
/// </summary>
/// <param name="jobName">Job Title for the timer service</param>
/// <param name="webApp">Web appication for which this service will run</param>
public MyTimerService(string jobName, SPWebApplication webApp)
: base(jobName, webApp, null, SPJobLockType.ContentDatabase)
{
this.Title = "My Timer";
}
#endregion Constructor

#region Execute

/// <summary>
/// Overriden Execute method
/// </summary>
/// <param name="targetInstanceId">guid of the target object</param>
public override void Execute(Guid targetInstanceId)
{
try
{
/// Here the timer logic goes
}
catch (Exception ex)
{
//Log exception
}
}

#endregion Execute      
}
}
One this class is ready. Next thing we need to look into is creating a Feature. This feature will internally schedule the timer as a Job and runs it. Below is the snapshot of this class.

namespace TimerNameSpace
{
#region Namespace Inclusions
using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;  
#endregion Namespace Inclusions

/// <summary>
/// Class is feature receiver for feature to install approval timer service
/// </summary>
public class MyTimerFeature : SPFeatureReceiver
{
/// <summary>
/// Notifications job name
/// </summary>
public string MyTimerFeatureName = "MyTimerServiceFeature";

/// <summary>
/// Occurs after a Feature is installed.
/// </summary>
/// <param name="properties">An  object that represents the properties of the event.</param>
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
}

/// <summary>
/// Occurs when a Feature is uninstalled.
/// </summary>
/// <param name="properties">An object that represents the properties of the event.</param>
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
}

/// <summary>
/// Occurs after a Feature is activated.
/// </summary>
/// <param name="properties">An object that represents the properties of the event.</param>
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
// register the the current web
SPWeb web = (SPWeb)properties.Feature.Parent;

SPSite site = web.Site;

// make sure the job isn't already registered
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
{
if (job.Name == this.MyTimerFeatureName)
{
job.Delete();
break;
}
}

MyTimerService myJob = new MyTimerService(this.MyTimerFeatureName, site.WebApplication);

SPMinuteSchedule schedule = new SPMinuteSchedule();
schedule.BeginSecond = 0;
schedule.EndSecond = 5;
schedule.Interval = 2;

myJob.Schedule = schedule;
myJob.Update();
}

/// <summary>
/// Occurs when a Feature is deactivated.
/// </summary>
/// <param name="properties">An object that represents the properties of the event.</param>
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
// current web
SPWeb web = (SPWeb)properties.Feature.Parent;

SPSite site = web.Site;

// delete the job
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
{
if (job.Name == this.MyTimerFeatureName)
{
job.Delete();
break;
}
}
}
}
}
Similar to SPMinuteSchedule, there is Hourl Schedule also. Use the one as per your requirement.
Once this much is done, we need to create Feature.xml file for the feature we have built and paste it under the Features Folder (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\FEATURES). Create a folder named MyTimerFeature and under this folder create Feature.xml with the following content.


<?xml version="1.0" encoding="utf-8" ?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
Creator="Amal Hashim"
Id="{76D2F200-5CA0-4882-B64F-9FC6208C1234}"
Title="MyTimerFeature"
Description="My Timer."
Scope="Web"
Hidden="FALSE"
Version="1.0.0.0"
ReceiverAssembly="MyTimer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=12344ab009fa4028"
ReceiverClass="TimerNameSpace.MyTimerFeature">
</Feature>
You can activate the feature using the Stsadm command as shown below.
stsadm -o installfeature -name MyTimerFeature

For checking whether the timer has activated successfully or not, you can go to the central admin page
Central Administration –> Operations –> Timer Job Status

Monday, November 9, 2009

Sharepoint List Webservice, access data from folders

Recently, for my project I was trying to do the same thing, but unfortunately there was no material available in the net. The only help I got was from MSDN Sharepoint Development forum. So I thought of documenting this, so if anyone who is looking for this can be find it useful.

First of all, if you want to get data recursively, then use the following code.

System.Xml.XmlElement queryOptions = xmlDoc.CreateElement("QueryOptions");
queryOptions.InnerXml = "<ViewAttributes Scope=\"Recursive\" />";

Now for getting data from a particular folder inside a list, use the following code

string url = "http://server/sites/site/list/folder";
queryOptions.InnerXml = "<Folder>" + url + "</Folder><ViewAttributes Scope=\"Recursive\" />";

The remaining portion of accessing the webservice is already documented in the following post.

Sharepoint List Webservice

 

Monday, November 2, 2009

Sharepoint and Silverlight - 1

As part of setting up the environment we must be careful to do the following points

Point #1

Changing the MIME type in IIS to support Silverlight application. This can be done as follows

1. Open run window from Start Menu

2. Enter inetmgr and click OK

3. This will bring up the Internet Information Services Manager. From the folder structure on the left side, select the site which is your Sharepoint application.

4. Now from the right pane select "Mime Types" and "Open Feature"

5. In Mime Type View, Click Add, add the file extension, and type .xap as the file extension and "application/x-silverlight-2" as the Mime type.

Point #2

In the web.config of your Sharepoint application, add the required configurations.

Point #3

Make sure the System.Web.Silverlight.dll is in the GAC

Installing Sharepoint Extensions for VS 2008 in XP/Vista

The extensions installer can be downloaded from the following location

Download

Once you have downloaded. You need to modify the registry, for doing that follow the below steps

1. Open run window from Start Menu

2. Enter Regedit and Click OK

3. Open the following location

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\

Now create a new Key named “12.0”

Under 12.0 create a new String “Sharepoint” and give the value “Installed”

4. Now run the installer you have downloaded from the link above.

Sharepoint Top-Level Object Model

Amal Hashim

Building and Deploying a Web Part

In this article am going to explain how we can develop a simple web part and deploy it in Sharepoint.

There are two way we can build a web part.

1. Using Sharepoint extensions for Visual studio.
2. Developing a Class library and manually deploying it in Sharepoint.

Sharepoint extensions for visual studio can be downloaded from the following location

Download

Once you have installed the extension, from Visual Studio->File->New Project->Share Point->Web Part

This will provide a template with all setting ready for building a web part. Once you have done with the web part, you can deploy it directly from Visual Studio. For doing that open the properties dialog by right click the project from solution explorer, go to the debug tab and enter the sharepoint web application URL and save the settings. You can use the same right click context menu for deploying the web part directly to sharepoint server by clicking the deploy menu item.

Manual development and deployment steps

  1. From visual studio File->New Project->C#->Class Library

  2. Right click and Add Reference of System.Web

  3. Rename Class.cs to NewWebPart.cs

  4. Open NewWebPart.cs and add the following code

  5. using System;
    using System.Collections.Generic;
    using System.Text;

    namespace NewWebPart
    {
    public class NewWebPart: System.Web.UI.WebControls.WebParts.WebPart
    {
    protected override void RenderContents(System.Web.UI.HtmlTextWriter writer)
    {
    writer.Write("Hello World!!!");
    }
    }
    }

  6. Right click project->Properties->Signing, and sign the assembly with a key

  7. Now build the project

  8. Open visual studio command prompt and use the following command

  9. gacutil /i C:\bin\NewWebPart.dll
    Replace C:\bin\NewWebPart.dll with the location of NewWebPart.dll in your machine

  10. Open your sharepoint web application's web.config file and add the following entry

  11. <SafeControl Assembly="NewWebPart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=902d73ff104745c3" Namespace="NewWebPart" TypeName="NewWebPart" Safe="True" />

    Replace 902d73ff104745c3 with the token of assembly. You can find it by opening c:\windows\assembly

  12. Open Site Setting from Site Actions menu

  13. Click on Web Parts

  14. Click New

  15. Select NewWebPart.NewWebPart and Click Populate Gallery

    Now you can add web part on your site by editing the page.

    That's it!!!

Saturday, October 31, 2009

Using Sharepoint List Webservice

Sharepoint exposes some really useful webservices. One among the most useful is the List Webservices.

We can take the webreference from the following location

http://mossserver/_vti_bin/lists.asmx

Once we have added the webservice, we can use following generic method to call webservice

XmlNode CallWebService(bool isRecursive, ListsService listService,
string listName, string queryObj, string viewID, string viewFieldsInnerXml)
{
try
{
NetworkCredential credential = new NetworkCredential();
credential.UserName = "UserName";
credential.Password = "Password";
credential.Domain = "Domain";
listService.Credentials = credential;

// Instantiate an XmlDocument object
System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();

string viewName = string.Empty;
if (string.Empty != viewID)
{
viewName = viewID;
}
string rowLimit = "150";

System.Xml.XmlElement query = xmlDoc.CreateElement("Query");
System.Xml.XmlElement viewFields = xmlDoc.CreateElement("ViewFields");
System.Xml.XmlElement queryOptions = xmlDoc.CreateElement("QueryOptions");

if (isRecursive)
queryOptions.InnerXml = "<ViewAttributes Scope=\"Recursive\" />";
else
queryOptions.InnerXml = "";

if (string.Empty == queryObj)
{
query.InnerXml = "<Where><Gt><FieldRef Name=\"ID\" />" +
"<Value Type=\"Counter\">0</Value></Gt></Where>";
}
else
{
query.InnerXml = queryObj;
}

// Assign View fields
if (string.Empty != viewFieldsInnerXml)
{
viewFields.InnerXml = viewFieldsInnerXml;
}
else
{
viewFields.InnerXml = "<FieldRef Name=\"Title\" />";
}
System.Xml.XmlNode nodeListItems =
listService.GetListItems(listName, viewName, query,
viewFields, rowLimit, queryOptions, null);

return nodeListItems;
}
catch (Exception ex)
{
throw ex;
}
}

You can use this generic method for getting the list items.

Pass true to “IsRecursive” if you want to get items inside folder.

Example:
string fields = "<FieldRef Name=\"FieldName1\" />
<FieldRef Name=\"FieldName2\" />";
XmlNode nodeListItems = CallWebService(true, l, "Answer Choices",
string.Empty, string.Empty, fields);
foreach (System.Xml.XmlNode listItem in nodeListItems)
{
if (listItem.ChildNodes.Count > 0)
{
foreach (XmlNode node in listItem.ChildNodes)
{
string choice = node.Attributes["ows_Title"]
.Value;
}
}
}

Wednesday, October 28, 2009

Sharepoint Calculated Field - Week Number

The following formula will help us to find the week number for a date value.

=INT(([Date]-DATE(YEAR([Date]),1,1)+(TEXT(WEEKDAY(DATE(YEAR([Date]),1,1)),"d")))/7)+1

Hope this helps :)

Saturday, October 24, 2009

Integrating SSRS + Sharepoint + Report Viewer

Scenario:

We need to display a report based on the data spread across multiple list. In such a case we won't be able to use either List View or Data View. One easier way to solve this problem is to create a custom webservice which will basically call the List Web Services provided by Sharepoint, create the dataset and return it back to the SSRS report.

One problem which we will face is while the deployment in production server. What we can do is in the report viewer control, lets take the rdl file from local instead of server. We can keep the rdl file in sharepoint list only. Thus the rdl file will be secure and can be replaced only by administrators. One drawback of the approach is that, the rdl file will not be available in the Sql Reporting Server. But compared to the ease of deployment, I think we can live with this :)

Wednesday, October 14, 2009

Sharepoint List View - Calculated Columns

In some scenarios, while creating views we might need to filter based on complex queries. In List View, filters are available but they are not powerful. For example, if we want to group the condition based on And and or, that feature is not available.

One workaround for this problem is to add a calculated column in the list and the result of the calculation will say whether that row should be placed in the view or not.

Example query will be as follows:

IF(AND(OR([Col1]="Some Value", [Col2]="Some Value"), AND([Col3]="Some Value", [Col4]="Some Value")), "Show Row", "Dont Show")