Wednesday, October 13, 2010

Creating Custom Web Part ToolPane

To create a custom toolpane is pretty simple, it's quite simple if you think about. All you need is an extra class that will create your toolpane.

I created a web part that had a custom toolpane that was used to display list in a site with checkboxes.

This toolpane allows users to select which list they wish to use on the site. Please see code below, and if you know of any better ways to do this please let me know:

WEB PART CODE EXAMPLE

using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using SMC.ClassLibrary;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;


namespace OM.FILTER.JQUERY
{
[Guid("67e99305-67bc-444d-9f9d-0c3c53d3dfe8")]
[CLSCompliant(false)]
public class FilterJQuery : Microsoft.SharePoint.WebPartPages.WebPart
{

public FilterJQuery()
{

}

protected override void CreateChildControls()
{
base.CreateChildControls();
}

public override ToolPart[] GetToolParts()
{
List _toolParts = null;

SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite _spSite = new SPSite("url"))
{
using (SPWeb _spWeb = _spSite.OpenWeb())
{
CustomToolPart _customPart = new CustomToolPart("url");
_customPart.Title = "All Lists";

_toolParts = new List(base.GetToolParts());
_toolParts.Insert(0, _customPart);
}
}
});

return _toolParts.ToArray();
}


[CLSCompliant(false)]
[WebBrowsable(false),
Personalizable(PersonalizationScope.Shared),
Category("Custom Settings")]
public string _collectionSelected
{
get;
set;
}
}
}

TOOL PANE CODE EXAMPLE

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using System.Web.UI.WebControls;
using System.Data;
using SMC.ClassLibrary;

namespace OM.FILTER.JQUERY
{
class CustomToolPart : Microsoft.SharePoint.WebPartPages.ToolPart
{
private CheckBoxList _spLists = new CheckBoxList();

private CheckBoxList chkBox
{
get { return _spLists; }
set { _spLists = value; }
}


private String _SiteURL;

public CustomToolPart(String _webURL)
{
this._SiteURL = _webURL;
}

protected override void CreateChildControls()
{
base.CreateChildControls();

BindToolPart();
}

private void BindToolPart()
{
chkBox.DataSource = Helper.GetAllListTitles(_SiteURL);
chkBox.DataTextField = "Title";
chkBox.DataValueField = "ID";
chkBox.DataBind();

FilterJQuery _jQuery = (FilterJQuery)this.ParentToolPane.SelectedWebPart;

if (_jQuery._collectionSelected != null)
{
List arrayList = Helper.SplitString(_jQuery._collectionSelected);

foreach (ListItem _item in chkBox.Items)
{
for (int i = 0; i < arrayList.Count; i++)
{
if (_item.Value == arrayList[i])
{
_item.Selected = true;
}
}
}
}
this.Controls.Add(chkBox);
}

public override void ApplyChanges()
{
base.ApplyChanges();

FilterJQuery parentWebPart = (FilterJQuery)this.ParentToolPane.SelectedWebPart;

string _iList = "";

foreach (ListItem _item in chkBox.Items)
{
if (_item.Selected)
{
_iList += _item.Value + ";";
}
}
parentWebPart._collectionSelected = _iList;

chkBox.EnableViewState = true;
EnableViewState = true;
this.SaveViewState();
this.SaveControlState();
}
}
}

Hope this helped you out as it sure helped me out a whole lot, let me know if you have any questions and I will try and respond to it asap.

Monday, October 4, 2010

Impersonating the Sharepoint System Account

Impersonating the SharePoint System Account is pretty simple. All you need is an the SPWeb object and you ready to go.

Here is how to do it.

using (SPWeb web = properties.OpenWeb())
{
var adminUser = web.AllUsers[@"SHAREPOINT\SYSTEM"];
var adminToken = adminUser.UserToken;

using (SPWeb site = new SPSite(web.Url, adminToken).OpenWeb())
{
/* Now running in the context of the system account */
}
}

And there it is, you can now run your code as the SharePoint System Account.

Storing Feature Values in Feature.XML file

Ever created a feature and wanted to deploy it on multiple servers without hard coding certain values?

It's kind of easy, you can use the feature.xml, namely the properties section to save values that you might want to change in future and then access them through code later, or even change them if need be.

In your feature.xml file, create a properties section, and add property tags for the relevant properties as shown below:




If you want to access this property you created you can do so by using the following code:

string _property = properties.Feature.Properties["SiteURL"].Value;

And that's it, how to access values stored in the feature.xml file.

Friday, October 1, 2010

FxCop Code Analysis

If ever you are deploying a solution, if it be a personal solution, private, or for a client. It helps you make sure that your solution conforms to Patterns and Practices as well as .NET Guidelines.

I recently found this out the hard way when one of my solutions did not pass the checks that FxCop performed.

In any event, this is a great tool for you to pick up any errors that testing might not, and to help you make sure that your solution adheres to best practices of Microsoft, and .NET Framework guidelines.

Documentation can be found here

Available for Download here

This tool has helped me immensely and I now see the error of my ways. I hope that you do to.

Wednesday, September 8, 2010

Access Denied - SharePoint Crawl Schedules

When you try and create or update a crawl schedule, you are prompted for a username and password, but for some strange reason your user credentials doesn't seem to work.

Upon examing the logs, you will find an Access Denied error.

This error occurs when the WSS_WPG group does not have the correct permissions to the c:\windows\tasks folder.

To solve this,
Open up the command prompt, type attrib –s %windir%\tasks, navigate to the c:\windows\tasks folder using windows explorer, right click and select the properties and then the securities tab, grant the WSS_WPG user Read, Write permissions to the folder, now reset IIS, using the following command, IISRESET \NOFORCE, then reset the folder back to the default view using the following command in the command prompt attrib +s %windir%\tasks.

For more info please see Microsoft article http://support.microsoft.com/kb/926959

Tuesday, August 24, 2010

Term Store Management Link missing

Error : "The required feature is not enabled for this column type"

You also do not see the Term Store Management link in site collection settings.

If you are using SharePoint 2010, and you have the Managed Meta Data service application you have to associate the service with your Web Application before you can use it.

Even though you might have followed a step by step guide, something went wrong and you recieve the following errors :

"The required feature is not enabled for this column type"

If you do come accoss this error, no worries, you will just have to activate this feature manually using the STSADM command line utility, found at "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\BIN"

You will have to run the following commands "stsadm -o activatefeature -id 7201d6a4-a5d3-49a1-8c19-19c4bac6e668 -url web application url -force".

I have found the id by looking in the following folder "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\FEATURES\MetaDataNav" and examing the "feature.xml" file.

And also run "stsadm -o activatefeature -id 73EF14B1-13A9-416b-A9B5-ECECA2B0604C -url web application url -force".

I have found the id by looking in the following folder "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\FEATURES\TaxonomyFieldAdded" and examing the "feature.xml" file.

This did the trick for me, hope that it did for you.

Monday, August 23, 2010

Office Web Applications Error

Word Web App cannot open this document due to an unknown error. If the problem persists, try opening the file in Microsoft Word.

Problem : This error usually occurs when you have not configured the service applications after you have installed the office web application package on your SharePoint Farm.

Resolution : Log into your SharePoint Central Administration site, navigate to your service application pages and create a service application for Word, PowerPoint and Excel. Once complete perform a IISRESET (not necessary) and try and re-open your document using Office Web Applications.

I hope this resolution has worked for you as it worked for me.

Monday, August 16, 2010

Execute SharePoint Timer Job using STSADM

Executing SharePoint schdeuled timer jobs is pretty simple.

If you have a scenario where you need all scheduled jobs to be run immediately you can use STSADM.EXE utility to achieve this by using the following command:

STSADM -O -EXECADMSVCJOBS

If you want to run a specific timer job you can use the following command:

STSADM -O RUNTIMERJOB -NAME (NAME OF TIMER JOB) -URL (SITE COLLECTION URL)

If you require any other information on STSADM commands you can check this link for a full list of available commands for STSADM command line utility.

Thursday, August 5, 2010

Managing Hyper V using Windows 7

It's been a while since the last post, hope this one can help someone out there.

In short I have been trying to manage my hyper v machines directly from my windows 7 machine. All you need to do is follow these easy steps.

Down and install microsoft kb update found here.

Once installed navigate to add remove windows features found at control panel, and expand the Remote Server Administration Tools, and select Hyper V Tools, shown below:



Click the ok button and Hyper-V remote adminsitration tool will be installed on the client computer, you are now able to connect to your Windows Server R2 installation running the Hyper-V management console.



Hope that this helped you, it sure helped me.

Tuesday, July 27, 2010

Adding Event Reciever Programmatically

I was wondering one evening how would you programmatically add an event reciever to a SharePoint list programmatically, and then it hit me.

Get the Event Reciever collection for the specific list and just add your own event reciever to that collection, as shown below:

SPEventReceiverDefinitionCollection eventRecievers = spRequestList.EventReceivers;

SPEventReceiverDefinition defFile = spRequestList.EventReceivers.Add();

defFile.Name = "Auto Provisioning - Mark Parker";
defFile.Type = SPEventReceiverType.ItemAdded;
defFile.SequenceNumber = 10000;
defFile.Assembly = "SP2010.MarkParker, Version, Culture, PublicKeyToken=";
defFile.Class = "SP2010.MarkParker.EventReciever";

defFile.Update();
spRequestList.Update();

I have now added the Item added event to the list in question. If you wish to add the any other event recievers to the list simply follow the same method and just change the Type of event.

Hope this helped you

Programmatically Adding SharePoint List

Adding list programmatically is pretty simple, all you need to do is grab the list collection for the current site and add a new list as shown below:

SPListCollection ListCollection = _spweb.Lists;
ListCollection.Add("Name", "Decription", SPListTemplateType.GenericList);

Its that simple you have just added a list called name with the description description to your sharepoint site.

Friday, July 23, 2010

SharePoint People Picker

Have you ever wondered if you can retrieve data like email, job title, etc, from the people picker control in SharePoint using Javascript? In short, yes it can be done and it is pretty simple.

Below is some javascript which accepts a parameter for the the position of the control, and returns the desired value.

function getEmailFromPoeplePicker(identifier)
{
var tags = document.getElementsByTagName('DIV');
for (var i = 0; i < tags.length; i++)
{
var tempString = tags[i].id;
if ((tempString.indexOf(identifier) > 0) && (tempString.indexOf('UserField_upLevelDiv') > 0))
{
var pplHTML = tags[i].innerHTML;
var valReturn = pplHTML.indexOf(">Email");
if (valReturn > 0)
{
pplHTML = pplHTML.substr(valReturn + 12);
var ValuePos1 = pplHTML.indexOf(">");
var ValuePos2 = pplHTML.indexOf("");
if (ValuePos1 > 0 && ValuePos2 > ValuePos1)
return (pplHTML.substring(ValuePos1 + 1, ValuePos2));
}
}
}
return null;
}

if you wish to return any other details from the people picker simply modify this line :

pplHTML = pplHTML.substr(valReturn + 12);

Change the substr value of 12 to the following :

29 For the mobile number
12 Gets the Job Title

This is only 3 of many examples of how it can be done, feel free to comment if you have found a better way.

Wednesday, July 21, 2010

Custom Consumer Web Part

Retrieving data from another web part by means of connections is pretty simple. In the code example I will show you how you can create your own consumer web part that will allow you to recieve a row of data from another web part, custom or out of the box.

Code Example :

using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Data;
using System.Text;

namespace MarkAnthonyParker.ConsumsumerWebPart
{
[ToolboxItemAttribute(false)]
public class ConsumsumerWebPart: WebPart
{

private IWebPartRow _provider;
private DataRowView _tableRow;

protected override void RenderContents(HtmlTextWriter writer)
{
if (_tableRow != null)
{
// Add method to use data
}
}

private void GetRowData(object tableRowData)
{
_tableRow = (DataRowView)tableRowData;
}

protected override void OnPreRender(EventArgs e)
{
if (_provider != null)
{
_provider.GetRowData(new RowCallback(GetRowData));
}
}

[ConnectionConsumer("Row")]
public void SetConnectionInterface(IWebPartRow provider)
{
_provider = provider;
}

public class TableConsumerConnectionPoint : ConsumerConnectionPoint
{
public TableConsumerConnectionPoint(System.Reflection.MethodInfo callbackMethod, Type interfaceType, Type controlType, string name,
string id, bool allowMultipleConnections)
: base(callbackMethod, interfaceType, controlType, name, id, allowMultipleConnections)
{
}
}
}
}

This code can be used for both SharePoint 2007 and SharePoint 2010 web parts.

Friday, July 16, 2010

Access denied - Dropping DLL into GAC

When you try and drop a DLL into the GAC in your Windows Server 2008 enviroment you get a error message saying Access Denied, even though you are an administrator on the machine in question.

Simple solution, UAC (User Access Control) is preventing you to do this as Windows thinks there is an attack on the GAC.

To rememdy this simply turn off UAC temporily, restart your computer and redeploy the Assembly into the GAC.

Monday, July 12, 2010

Attempted to use an object that has ceased to exist

Error : Attempted to use an object that has ceased to exist. (Exception from HRESULT: 0x80030102 (STG_E_REVERTED))

This error occurs when you are using the SPContext.Current.Web object and then trying to dispose it.

So, do not dispose of this object or other controls on your page will no longer be able to use it. Thus the error, attempted to use an object that has ceased to exist.

SharePoint will automatically dispose of the SPContext.Current.Web object once your page has completely loaded.

Tuesday, July 6, 2010

Uploading Documents to Document Library Programmatically

Uploading documents to a document library programmatically is pretty simple the code for it can be found below:


String filename = System.IO.Path.GetFileName(filepath);

SPFolder myLib = impersonatedWeb.Folders[documentLibraryName];

FileStream stream = File.Open(path, FileMode.Open);
SPFile file = myLib.Files.Add(filename, stream, true);

myLib.Update();

There you have it, its as that.

SharePoint ReadOnly Columns

Have you ever thought of changing SharePoint read-only columns? The created by, modified by columns, which always seem to be impossible to change, below is the code on how to change those columns:

SPList _pList = impersonatedWeb.Lists[ListName];

_pList.Fields["Created By"].ReadOnlyField = false;
_pList.Update();

//Update the relevant list item

Once you have updated the relevant list items you have to change the field back to Read Only mode, as shown below:

_pList.Fields["Created By"].ReadOnlyField = true;
_pList.Update();

SharePoint Timer Job

I have recently created a SharePoint Timer Job, I have deployed it as a feature and then activated it.

To my dismay I had forgot to insert a line of code. When I changed the code and re-deployed the timer job, the timer job still seemed to be using the same code as before.

After scratching my head for a while and realizing that I done everything short of restarting my server. I decided to restart the timer service. Once I did that everything worked.

Please note, you don’t have to reset “IIS” and you don’t need to restart your server. All you need to do is go to start, administrative tools, services and restart your SharePoint timer service.

If you have a farm installations make sure the new assembly is deployed to all the servers in the farm, and the SharePoint Timer service is restarted on each of the servers.