Archive for June, 2010

Web Part Page Maintenance

Tuesday, June 29th, 2010

In order to access the Web Part Page Maintenance section of a site, add ?contents=1 to the end of the site url.

So http://mysite/sites/mine/?contents=1
There you will be able to remove offending web parts.

Webpart issue: The given assembly name or codebase is invalid

Wednesday, June 9th, 2010

One gigantic issue that I ran into once was creating a web part, adding it as part of solution/feature, putting it on a site and then getting the error “the given assembly name or codebase is invalid”. Well, what I had done was incorrectly set the Assembly name. After changing and redeploying the solution, did it work? Nope.

I continued to redeploy, reset IIS, reboot the machine, several times over. After giving up and rewriting another project, thinking there was some funky bad mojo going on, I saw that the web part I had created was still available in the webpart gallery. Then it hit me, the webpartname.webpart, once added to a site, needs to be deleted even if you redeploy as a solution. Crazy.

Moving web part pages between sites/farms

Tuesday, June 8th, 2010

When you move a web part page from one site to another, and you do so using the explorer view and copy and paste, you lose the content, expected, but more important, and unexpected, you lose the TitleBarWebPart from the WEb Part Maintenance page. Once this is gone I have not found a way to get it back.

If you want to keep the title intact, save the library as a template and include content and move the entire library over.

Changing time of NEW icon on libraries

Thursday, June 3rd, 2010

stsadm -o setproperty -pn days-to-show-new-icon -pv 2

2 = days

Adding worksapce template to project server 2007

Thursday, June 3rd, 2010

Run the following command on CMD

stsadm -o addtemplate -f “<template path>\AAMC Workspace Template V9.stp” -t “AAMC Workspace Template V9”

Then go into server settings -> workspace provision and choose the new template

Beginning files for any Feature

Thursday, June 3rd, 2010

There are a few files. Feature.xml, elements.xml and in the event of just an eventreceiver, just a main.cs and worker.cs files

Feature.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<Feature  Id=”A GUID IS PUT IN HERE”
Title=”…”
Description=”…”
Version=”12.0.0.0″
Hidden=”FALSE”
Scope=”Site” //can be site/web/farm
DefaultResourceFile=”core”
ReceiverAssembly=”KMS_ER_Itemadding_DetailsLists, Version=1.0.0.0, Culture=neutral, PublicKeyToken=91d8ff9e64e6b4a3″
ReceiverClass=”NAMESPACE.CLASS”

xmlns=”http://schemas.microsoft.com/sharepoint/”>
<ElementManifests>
<ElementManifest Location=”elements.xml”/>
</ElementManifests>
</Feature>

Elements.xml

<?xml version=”1.0″ encoding=”utf-8″ ?>
<Elements xmlns=”http://schemas.microsoft.com/sharepoint/”>
//can be blank
</Elements>

main.cs

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

namespace KMS_ER_Itemadding_DetailsLists.FeatureCode
{
class KMS_ER_ItemAdding_DetailLists_Main : SPFeatureReceiver
{
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
//can do anything you want here. Whatever the feature calls for. This piece of code adds to an event receiver

SPList plotList = newsubsite.Lists[“Details”];
string assName = Assembly.GetExecutingAssembly().FullName;
plotList.EventReceivers.Add(SPEventReceiverType.ItemAdding, assName,
“NAMESPACE.WORKER”);
newsubsite.Dispose();

}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
// and to delete it
SPList plotList = newsubsite.Lists[“Details”];

foreach (SPEventReceiverDefinition item in plotList.EventReceivers)
{
if (item.Assembly == Assembly.GetExecutingAssembly().FullName)
{
item.Delete();
break;
}
} }

public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
}

public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
}
}
}

worker.cs

The worker.cs is the logic behind the event receiver. Whatever you just added has to do some logic to determine if it will allow the event to continue or do some other work when it does continue. This one below only allows for one item to be added to a list named Details.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using System.Diagnostics;
namespace NAMESPACE
{
class Worker : SPItemEventReceiver
{
public override void ItemAdding(SPItemEventProperties properties)
{
using (SPWeb t_site = properties.OpenWeb())
{
SPList t_aList = t_site.Lists[“Details”];
foreach (SPListItem t_listitems in t_aList.Items)
{
properties.Cancel = true;
properties.ErrorMessage = “Only one item in this list is allowed!”;
}
}
}
}
}

Adding a custom theme through a feature

Thursday, June 3rd, 2010

This feature is a farm level feature. It is very simple to do. It is comprised of the theme, including all images and CSS, feature.xml and elements.xml and a .cs file that does the dynamic adding to SPTHEMES.xml, which is necessary for the theme to show up.

FEATURE.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<Feature xmlns=”http://schemas.microsoft.com/sharepoint/”
Id=”GUID”
Title=”Custom Belltown”
Description=”Custom Belltown Theme”
Scope=”Farm”
Version=”1.0.0.0″
ImageUrl=””
ReceiverAssembly=”NEW_BELLTOWN_THEME, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=54d93db7bee0a736″
ReceiverClass =”NEW_BELLTOWN_THEME.FeatureCode.CustomTheme”>

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

elements.xml //in this case it’s actually an empty file

Add the theme to 12/template/themes/custombelltown/<ALL ASSETS>

customtheme.cs

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using System.Reflection;
using System.Xml.Linq;
using System.IO;
using System.Linq;

namespace NEW_BELLTOWN_THEME.FeatureCode
{
class CustomTheme : SPFeatureReceiver
{
private enum ModificationType { Add, Remove }

public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
ModifySPTheme(ModificationType.Add);

// if necessary, loop through all sites and set theme
}

public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
ModifySPTheme(ModificationType.Remove);

// if necessary, loop through all sites and reset theme
}

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
// do nothing
}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
// do nothing
}

private void ModifySPTheme(ModificationType type)
{
XDocument doc = null;
XNamespace ns = “http://tempuri.org/SPThemes.xsd”;

// path to the SPTHEMES.XML file
string spthemePath = Path.Combine(SPUtility.GetGenericSetupPath(@”TEMPLATE\LAYOUTS\1033″), “SPTHEMES.XML”);
string contents = string.Empty;

// read the contents of the SPTHEMES.XML file
using (StreamReader streamReader = new StreamReader(spthemePath))
{
contents = streamReader.ReadToEnd();
streamReader.Close();
}

using (StringReader stringReader = new StringReader(contents.Trim()))
{
// create a new XDocument from the contents of the file
doc = XDocument.Load(stringReader);

// retrieve all elements with a TemplateID of ‘VISTA’.  At most, there should only be one
var element = from b in doc.Element(ns + “SPThemes”).Elements(ns + “Templates”)
where b.Element(ns + “TemplateID”).Value == “CustomBelltown”
select b;

// determine if the VISTA theme element already exists
bool exists = (element != null && element.Count() > 0);

if (type == ModificationType.Add)
{
if (!exists)
{
// create an XElement that defines our custom VISTA theme
XElement xml =
new XElement(ns + “Templates”,
new XElement(ns + “TemplateID”, “CustomBelltown”),
new XElement(ns + “DisplayName”, “Custom Belltown”),
new XElement(ns + “Description”, “A custom belltown theme”),
new XElement(ns + “Thumbnail”, “images/thbelltown.gif”),
new XElement(ns + “Preview”, “images/thbelltown.gif”));

// add the element to the file and save
doc.Element(ns + “SPThemes”).Add(xml);
doc.Save(spthemePath);
}
}
else
{
if (exists)
{
// if the element exists, remove it and save
element.Remove();
doc.Save(spthemePath);
}
}

stringReader.Close();
}
}

}
}

Changing properties of default.aspx through feature

Thursday, June 3rd, 2010

We had a request once to change the width of columns on default.aspx on sites in SharePoint. Though we tried to do this in CSS, there just weren’t any ID tags on the columns, so we couldn’t. For SharePoint designer this is easy to do but we wanted to remove that as making changes with SPD in production is not allowed, and shouldn’t be allowed.

First, we created a feature. In the project we created folders 12/TEMPLATE/FEATURES/DEFAULTMOD/

Added Feature.xml and elements.xml

FEATURE.xml

<?xml version=”1.0″ encoding=”utf-8″ ?>
<Feature
Id=”GUID”
Title=” MAIN SITE Custom Default file”
Description=”This Feature contains a custom default page for the home page”
Version=”1.0.0.0″
Scope=”Web”
Hidden=”FALSE”
DefaultResourceFile=”core”
ReceiverAssembly=”AAMC_IT_DesignerChanges, Version=1.0.0.0, Culture=neutral, PublicKeyToken=32fc1a05b011eb37″
ReceiverClass=”DesignerChanges.Modifications”
xmlns=”http://schemas.microsoft.com/sharepoint/”>
<ElementManifests>
<ElementManifest Location=”elements.xml” />
<ElementFile Location=”customDefault.aspx” />
</ElementManifests>
</Feature>

Elements.xml

<?xml version=”1.0″ encoding=”utf-8″?>
<Elements xmlns=”http://schemas.microsoft.com/sharepoint/”>
<Module Name=”Modifications” Url=”” RootWebOnly=”FALSE”>
<File Path=”customDefault.aspx” Url=”customDefault.aspx” IgnoreIfAlreadyExists=”TRUE” />
</Module>
</Elements>

customDefault.aspx was just changing the middle two columns from the microsoft default of  70/30 to 50/50

Next we created the code that did the swapping out. Notice that when you deactive the feature, the file is just deleted, you can change that and get fancy to back it up as well. You could also do something terribly clever and add the webparts between the files being moved around. We didn’t have that much time and this was for a new site, so we just did a straight swap out.

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

namespace DesignerChanges
{
class Modifications : SPFeatureReceiver
{
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
if (properties != null)
{
// get a reference to the web
SPWeb web = properties.Feature.Parent as SPWeb;

// back up the original home page
SPFile defaultPage = web.Files[“default.aspx”];
defaultPage.MoveTo(“default-old.aspx”);

// add components to the new custom default page here, if necessary
// move the new default page to default.aspx
SPFile newDefaultPage = web.Files[“customDefault.aspx”];
newDefaultPage.MoveTo(“default.aspx”);

// update navigation, if necessary, here
}

}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
if (properties != null)
{
SPWeb web = properties.Feature.Parent as SPWeb;

// get a reference to the web

// delete the default page
SPFile defaultPage = web.Files[“default.aspx”];
defaultPage.DeleteAllPersonalizationsAllUsers();
defaultPage.Delete();

// restore the back up
SPFile originalDefaultPage = web.Files[“default-old.aspx”];
originalDefaultPage.MoveTo(“default.aspx”);

}

}

public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
}

public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
}
}
}

BeforeProperties and AfterProperties on SPItemEventReceiver

Thursday, June 3rd, 2010

Originally posted in http://www.synergyonline.com/blog/blog-moss/Lists/Posts/Post.aspx?ID=25

List BeforeProperties AfterProperties properties.ListItem
ItemAdding No value New value Null
ItemAdded No value New value New value
ItemUpdating No value Changed value Original value
ItemUpdated No value Changed value Changed value
ItemDeleting No value No value Original value
ItemDeleted No value No value Null

No value means that column value in the hash table was not available.
New value means that the correct value for the column was available.
Changed value means that the correct updated value was available.
Original value means that the correct original value was available.

Here is the same test against a document library:

Library BeforeProperties AfterProperties properties.ListItem
ItemAdding No value No value Null
ItemAdded No value No value New value
ItemUpdating Original value Changed value Original value
ItemUpdated Original value Changed value Changed value
ItemDeleting No value No value Original value
ItemDeleted No value No value Null

Creating a custom column part 2

Thursday, June 3rd, 2010

Must have TWO cs files, or at least two classes, i like to separate them into separate files. The main CS is really just setting the stage. All the heavy lifting is done in the second class.

MAIN CS

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

namespace KMS_Custom_column_Systems.FeatureCode
{
class KMS_CustomColumn_systems_List_main : SPFieldText
{
public KMS_CustomColumn_systems_List_main(SPFieldCollection fields, string fieldName)
: base(fields, fieldName)
{}

public KMS_CustomColumn_systems_List_main(SPFieldCollection fields, string typeName, string displayName)
: base(fields, typeName, displayName)
{}

public override BaseFieldControl FieldRenderingControl
{
get
{
BaseFieldControl fieldControl = new KMS_CustomColumn_systems_List_worker(this);

fieldControl.FieldName = InternalName;

return fieldControl;
}
}
}
}

WORKER Class

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

namespace KMS_Custom_column_Systems.FeatureCode
{
class KMS_CustomColumn_systems_List_worker : TextField
{
private KMS_CustomColumn_systems_List_main field;
private HtmlTable table;
private DropDownList dropdownlist;

public KMS_CustomColumn_systems_List_worker(KMS_CustomColumn_systems_List_main parentField)
{
this.field = parentField;
this.dropdownlist = new DropDownList();
}

protected override void OnInit(EventArgs e)
{
base.OnInit(e);
}

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

this.table = new HtmlTable();
HtmlTableRow row = new HtmlTableRow();
table.Rows.Add(row);

HtmlTableCell cell = null;

if (this.ControlMode == SPControlMode.Edit || this.ControlMode == SPControlMode.New)
{

cell = new HtmlTableCell();
row.Cells.Add(cell);

// Create a list selector.
this.dropdownlist = new DropDownList();
using (SPWeb rootWeb = SPContext.Current.Site.RootWeb)
{
dropdownlist.Items.Add(“Select One”);
foreach(SPWeb subsite in rootWeb.Webs)
{
if (subsite.Name.ToString() == “systems”)
{
foreach (SPWeb newsubsite in subsite.Webs)
{
dropdownlist.Items.Add(new ListItem(newsubsite.Name, newsubsite.Name.ToString()));
subsite.Dispose();
}
}

}
}

// Get the current value of the field.
String currentValue = (String)this.ItemFieldValue;

if (currentValue != null && currentValue != String.Empty)
{
this.dropdownlist.SelectedValue = currentValue;
}
else if (this.dropdownlist.Items.Count > 0)
{
this.dropdownlist.SelectedIndex = 0;
}

// Add the script which updates the preview image.
this.dropdownlist.Attributes[“onchange”] = “this.options[this.selectedIndex].value;”;
cell.Controls.Add(this.dropdownlist);
row.Cells.Add(cell);
}

cell = new HtmlTableCell();

LiteralControl literalControl = new LiteralControl();

String logo = null;
object logoObject = this.ItemFieldValue;

if (logoObject != null)
{
logo = (String)logoObject;
}

literalControl.Text =  logo;

cell.Controls.Add(literalControl);

row.Cells.Add(cell);

base.Controls.Add(table);
}
public override void UpdateFieldValueInItem()
{
this.EnsureChildControls();

try
{
this.Value = this.dropdownlist.SelectedValue;
this.ItemFieldValue = this.Value;
}
catch (Exception)
{
;
}
}
protected override void Render(HtmlTextWriter output)
{
this.table.RenderControl(output);
}
}
}