Archive for the ‘Sharepoint’ Category

Install Active Directory onto a Sharepoint VM AFTER having setup Sharepoint

Wednesday, October 14th, 2009

**Note: this post it limited in scope to the Single Sharepoint VM environment, anything more complicated is frankly beyond my feeble server administration skills.

If you try to install AD and DNS onto a Sharepoint VM after having already installed Sharepoint you run into a range of problems. The first time I tried to fix the problem I fried my environment and had to revert to a snapshot.

First, install AD and DNS as you normally would. Here’s a link to the guide I used.

At this point if you try to hit your Central Administration site or any other Sharepoint site, you’ll get a Service Unavailable message on any page you hit.

I tried the following to bring up something, anything Sharepoint:

  • Hitting my server via the computer name (http://phoenix:5555)
  • Hitting my server via the IP address (192.168.0.2:5555)
  • Hitting my server via localhost (http://localhost:5555)
  • Hitting my server via the fully qualified domain name (http://phoenix.kmtests.local:5555/)

None of these works, and if I wasn’t getting the Service Unavailable message, I was getting one that said:

Under Construction

The site you are trying to view does not currently have a default page. It may be in the process of being upgraded and configured.

Looking at the server logs, you see two errors:

Application Log Screenshot

Application Log Screenshot

System Log screenshot

System Log screenshot

Aha! Adding a domain to the mix changes all the user accounts so that your old accounts need to be reconfigured. This is easily done by going into IIS Manager and updating the Identities of all of the app pools to reflect the new, domain enabled accounts.

i.e. servername\MossServiceAcct becomes domainName\MossServiceAcct

sharedServiceProfileBefore

sharedServiceProfileAfter

Having reconfigured the app pools, trying to hit the server again give you a message that says

The current identity (domainName\MossServiceAcct) does not have write access to ‘c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files’.

You can resolve this easily by navigating to that location and by granting write access to the folder in question (you will need to do this for each unique service account which hits the Temporary ASP.NET Files folder).

Central Admin will loads, but hold on cowboy/girl, you won’t be able to get to any of the pages on the Operations or Application Management tabs.

Some or all identity references could not be translated.   at System.Security.Principal.NTAccount.Translate(IdentityReferenceCollection sourceAccounts, Type targetType, Boolean forceSuccess)

Will it never end?

Ultimately I followed the process outlined on two specific web pages (retyping them would be silly)

Following Joel’s tips I got 100% of the way, but the other page a good reference anyways. I found that there were so many passwords to re-enter that I missed a couple (specifically the stsadm -o editssp command) but got there in the end.

Good luck, it’s a painful process, but a possible one. Just be careful and meticulous and you should be okay.

Fixing the Sharepoint RSS Proxy issue in a VMWare environment

Tuesday, June 9th, 2009

I found this to be a total pain to figure out how to fix, but once done, the solution is actually very simple.

My setup:

Most people doing Sharepoint development will be doing so in a proper networked environment (setup by a proper network admin).   In which case this article is unlikely to apply to you and this article, can probably point you in the right direction (hint: you need to set your web.config proxy settings).

I am running a Sharepoint development environment at my house, using VMWare, with a minimal win2k3 setup.  I’m not a server admin and I’m conscious hits to performance so the environment is very lightweight.  No Domain Controller, no Active Directory.  I’m a developer not a sysadmin.

The problem:

Unfortunately, Sharepoint cares not for my developing ways and when I tried adding an RSS webpart to a Sharepoint page got the following on-screen error:

An unexpected error occured processing your request. Check the logs for details and correct the problem.

Crapola.  First I thought dodgy rss.

Nope.

Then I thought, the IIS account doesn’t have web access.

Nope.

So then I looked at the million and one “Sharepoint rss proxy” articles on Google  to no avail.  They all want you to make changes to the defaultProxy entry in your Sharepoint’s web.config.

Nope.

The cause:

For some reason, if you don’t have a proxy setup, Sharepoint throws it’s toys out the pram and won’t work.  It won’t even try to make a network call (I checked using WireShark).  Even when I tried to tell the defaultProxy entry to bypass all addresses, it ignored me.

The solution:

Setup your own proxy.  It’s actually very simple (trust me I hate server admin stuff)

  • disable Windows firewall (should have a firewall on your host anyways)
  • I then followed the instructions on support.microsoft.com as best I could under the “Installing the Routing and Remote Access Service” heading.
  • Then magically my rss webparts worked

Also important is to make sure you use a proper RSSViewer part instead of a RSSAggregatorWebPart (added manually).  The only difference I can see is in the configuration xml, but the latter continued to break even after my changes.

Hopefully this doesn’t up some insane hole in my firewall.

Hope that helps.

Export a Dataview as part of a Site Template

Tuesday, October 21st, 2008

Out of the box, if you use a list-bound dataview as part of a Sharepoint Site Template, you’ll get a grumpy message when creating a new site

“Unable to display this Web Part. To troubleshoot the problem, open this Web page in a Windows SharePoint Services-compatible HTML editor such as Microsoft Office SharePoint Designer. If the problem persists, contact your Web server administrator.”

How helpful.

The issue is the dataview has a hard-coded reference to the list guid on the original site. To resolve this, simply wrap curly braces “{” and “}” around all instances of the guid. This tells Sharepoint to refer to the newly created list when deploying the site template.

Granted this seems like a bug, but it works.

There should be 6 or 7 references to the listID in any dataview. Just hunt through the code and you should find it fairly easily.

AJAX-Enabled Web-Parts: solving the problem of changing Client IDs

Tuesday, September 16th, 2008

AJAX-Enabled Web-Parts: solving the problem of changing Client IDs

One of the most challenging aspects of building SharePoint-enabled web parts is using JavaScript to interact with specific controls. As a consequence of how SharePoint renders controls with id’s in Sharepoint WebParts, it’s near impossible to write clean JavaScript.

From a maintenance perspective I HATE using server-side code to render JavaScript. It’s inelegant and reeks of a lack of forethought. Yuck yuck yuck. It’s like sweeping dust under the rug.

Wherever possible, webpart-specific javascript should be held within a single .js file (stored in the 12Hive). The problem is that Sharepoint alters a control’s ID during the page rendering process.

So, a label with the ID “label1” might become “ctl00_label1”. The naming process is entirely unpredictable.

This makes interacting with a specific DIV, INPUT or any other html element very difficult because you can’t predict the rendered IDs during development. This is especially problematic if you’re looking to host several instances of a webpart on a single page.

One really terrible way of dealing with this is to render the html yourself by adding literal controls ala

	LiteralControl l = new LiteralControl();
	l.text = “
blah
”;
	this.Controls.Add(l);

This is a terrible approach which is severely limiting and unnecessary.

To tackle the problem I’ve devised the following solution which revolves around creating a Javascript class to accompany the web part:

  • create properties to store the dynamically generated IDs of every html component to wish to interact with
  • create pointers to every html component you wish to interact with
  • create an init function. As input you pass the clientID of the webpart AND the id’s of every component you wish to interact with.
  • this function will store the id’s using the properties
  • this function will also attach the pointers to their respective objects
  • this function should also attach any eventhandlers
  • create any supporting functions (i.e. webservice calls, webservice receivers)

This approach embraces the absence of reliable identification info. It is also sympathetic to having multiple copies of a webpart on the same page.

Here’s what the javascript might look like

function UpdatingLabelWebPart()
{
	var me = this;	//required to reference the object at runtime
	this.clientID = null;	//ids
	this.labelID = null;
	this.buttonID = null;
	this.label = null;	//controls
	this.button = null;
	this.register = function (clientID, labelID, buttonID)
	{
		me.clientID = clientID;		//init the id
		me.labelID = labelID;
		me.buttonID = buttonID;
		me.attachToButton();
	}
	this.attachToButton = function()
	{
		//if the controls haven't loaded yet
		if (document.getElementById(me.buttonID) == null || document.getElementById(me.labelID) == null)
		{
			setTimeout(me.attachToButton, 50);
		}
		else
		{
			//register the controls
			me.label = document.getElementById(me.labelID);
			me.button = document.getElementById(me.buttonID);
			//attach any events
			button.AttachEvent("click", me.buttonClicked);
		}
	}
	this.buttonClicked = function(sender, args)
	{
		me.label.innerHTML = "Hello World";
	}
}

Then in your webpart you write a teeny tiny bit of javascript which you register as a clientscriptblock.

String myScriptBlock = String.Format(@"
					var tmp = new UpdatingLabelWebPart();
					tmp.register('{0}','{1}','{2}');
				    ", this.clientID
				    , this.label1.clientID
				    , this.button1.clientID);
Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "UpdatingLabelWebPartJS",myScriptBlock, true);
Page.ClientScript.RegisterClientScriptInclude(GetType(), GetType().ToString(), "_layouts/1033/myJS/UpdatingLabelWebPart.js");

This approach lets you have multiple instances of the same AJAX-enabled webpart and saves you the hassle of having to write annoying javascript (having to write me.label is hardly a chore).

SharePoint 2007 and WSS 3.0 Dispose Patterns by Example

Monday, May 26th, 2008
Just came across a very helpful post on Roger Lamb’s Blog which provides a number of examples on how to properly dispose of objects within the Sharepoint object model. One specific piece which was very useful was:

Changing how a web part displays while in edit mode

Tuesday, May 20th, 2008
There are a number of circumstances where you might want a web part to display differently depending upon the display mode of the page.

For example:

  • you might want to provide detailed instructions to the user while in edit mode (or connections mode, etc.);
  • the scriptaculous & prototype libraries conflict with Sharepoint javascript while in edit mode, causing a range of javascript errors;
  • you might want to provide a more rich user interface than Editor parts allow.

To do so, is quite simple in concept, just identify the display mode, and chuck an “if” statement in there. However, it did take me a while to find the right code and I thought it was worth posting about, especially because it can help you give users a more professional & polished interface.

First, where I looked for the display mode. There’s a WebPartManager class which exists, and has a display mode, but it’s tricky to find an instance.

If while inside CreateChildControls or OnPreRender you try:

WebPartDisplayMode currentMode = this.WebPartManager.DisplayMode;

you will get a null pointer exception, because this.WebPartManager == null. I don’t understand why, but it does.

What you need to do is execute the static GetCurrentWebPartManager function on your current page object (found this from a post by Rich from DevAndDesign.com).

WebPartManager wpm = WebPartManager.GetCurrentWebPartManager(this.Page);

if (!wpm.DisplayMode.AllowPageDesign)
{
this.Controls.Add(new Literal(“browse mode”));
}
else
{
this.Controls.Add(new Literal(“not browse mode”));
}

This relies on the boolean AllowPageDesign property. If true, the page is in edit mode (that includes the edit, connect, design & catalog modes). It’s definitely a bit silly that this.WebPartManager doesn’t work, especially because it’s such a simple property to implement. Maybe somebody can fill me in on the history?

Dataview web parts in your master page cause errors on subsites

Thursday, May 15th, 2008

If you’ve had this problem, then two things to make you feel better:

  1. The solution is very easy
  2. The cause of the problem is stupid stupid stupid. You can bang your head against the keyboard, there’s no way you could have known.

This post, meanders a bit, so if you want the solution, jump to the bottom.

Still here? Sucker.

So, what are the prerequisites to causing this problem:

  • you have a dataview web part inserted into a master page;
  • the dataview refers to data in a list; and
  • the list is scoped at the root web of the site collection.

I think that’s it.

Symptoms

The web part will display correctly anywhere in your root web, but nowhere else. I’m calling it a “web” here because it maps to how Sharepoint’s API. If it helps for you to think about it as a single “Site” in WSS2.0 fashion, go nuts. When you visit subsites, you see the following error:

“Unable to display this Web Part. To troubleshoot the problem, open this Web page in a Windows SharePoint Services-compatible HTML editor such as Microsoft Office SharePoint Designer. If the problem persists, contact your Web server administrator.”

How helpful, especially if you’re an administrator or developer. As if they’d have a magic wand to fix the problem. The error might as well say:

“You’re screwed. Unless you’re a clever developer, give up, swear at Sharepoint and call tech support. Not many people at your company are going to be able to help you.”

Which is silly, because once we come to the cause, the error is completely within the realms of detection. To the developer who wrote that line of code… 10 minutes on the naughty step.

The problem is seemingly unresolveable. If you try to add the dataview directly to a page in a subsite, it works fine, but master page? Sharepoint tells you to go whistle.

Cause

The cause? Sharepoint doesn’t know which “web” the list comes from.

The Dataview web part can take parameters, including, parameters which tell pages where to find a list. In Sharepoint Designer, when you edit a master page, it fails to insert a parameter telling pages the list lives in the root.

Bad Sharepoint Designer! Bad!

The problem compounded because taking a dataview created on a subsite and dumping the code into the masterpage doesn’t work either (which makes it very tricky to solve).

To figure this out, I took the following steps in Sharepoint Designer:

  • Created a dataview in the master page (worked at top level and nowhere else)
  • Created the dataview with the exact same settings on a page in a subsite
  • Copied the code snippets into a text-editor and compared them side-by-side

A side-by-side comparison revealed several things…

Web part parameters in the master

Web part parameters in a page

First, the datasource control (a child of the dataview web part) is referred to with a different namespace in the master page than in the page itself. This is why you can’t copy dataview code from a regular page into a master page. Maybe there’s a good reason for having done this, but I think the masterpage programmer forgot to speak to the regular page programmer. However, that isn’t the root cause, but something to be aware of.

Second, THERE’S ANOTHER PARAMETER. OMG!!! Froth, swear, stomp, swear, slam your keyboard. Feel better?

Knowing a parameter exists and knowing the syntax are two different things. Before finding the actual code, I was pretty confident the problem was down to subsites not knowing where the list was.

The worst thing is that the url of the web is actually part of the dataview web part, down at the very bottom of the code. Why doesn’t this flow through to the datasource? Naughty step!

Web part parameters

Solution

It’s simple enough to copy the parameter from the subsite dataview into the masterpage dataview.

<WebPartPages:DataFormParameter Name=”WebURL” ParameterKey=”WebURL” PropertyName=”ParameterValues” DefaultValue=”/”/>

I don’t believe the approach is necessary if you’re referring to a list in a subsite (the parameter should be inserted automatically).

Hope that helps!

Getting your controls to appear in Sharepoint Designer Toolbox

Monday, April 28th, 2008

The guy over at thekid.me.uk has posted a v. handy little note about how to get your a servers control into the toolbox in Sharepoint Designer.

Apart from registering your control within the SafeControls part of the web.config), the secret sauce is to add :

[ToolboxData("<{0}:ControlName runat=server />")]

to your class (just above the class declaration)

and

[assembly: TagPrefix("yournamespace", "selected prefix")]

What then happens when you drag the control into designer is that it inserts

<prefix:ControlName runat=server /> into the page.

Personalizable attribute of web part properties

Sunday, April 27th, 2008

Why does everything Sharepoint require a trip to Google? Oh well.

If you’re trying to make a web part property editable you need two attributes, Personalizable and WebBrowsable.

You need the WebBrowsable property in order to see the property via the web interface in Sharepoint.

You need the Personalizable propetry to be able to edit it.

However, Personalizable sounds like it’s tied to an individual user (and not all users). Like many things Sharepoint it depends.

Quick answer:

Personalizable(PersonalizationScope.Shared): Single value for all users
Personalizable(PersonalizationScope.User):
Different value for all users

I’m not sure which is default, but according to this it’s the User Scope. Read the msdn article for a more detailed breakdown.

Credit goes to Marco Bellinaso, as I found the reference to the PersonalizationScope on his blog.

Relative URLs in Sharepoint Web Parts

Monday, April 21st, 2008

If you’re using STSDev for web part development, it becomes very simple to deploy files into the 12Hive (which in some circumstances is preferable to using embedded resources). As a consequence, it becomes tricky to create hyperlinks to resource files because:

  • you can’t guarantee the web part is sitting in root of the site collection (which would make for simple hyperlinks ala “_layouts/styles/myPart/myCSS.css”)
  • you can’t know that your site collection is located at the root of the web server (which would make for simply hyperlinks ala “_layouts/styles/myPart/myCSS.css”

So, to create simple relative urls from code (as opposed to using the <% $SPURL:~sitecollection/_layouts/styles/myPart/myCss.css %> approach) I used something I found on Ari Bakker’s website.

Deep underneath the SPContext object is a property called ServerRelativeUrl which is attached to the Site(SPWeb) and Site collection(SPSite) objects.

These can be used by the web part to refer to resource files deployed along with it. So, something like the following should work anywhere inside a site collection:

string cssLocation = SPContext.Current.Site.ServerRelativeUrl + “_layouts/styles/myPart/myCSS.css”;