Tag Archive for SharePoint

Sneaking past the SharePoint Usage Log

I’m writing a piece of code that regularly polls a MOSS server and checks several files. This can happen quite a few times a day, and this totally skews my Usage Reports for my sites.

Does anyone know of a way to tell MOSS to ignore calls made by a specific user, a specific IP (my code runs on a dedicated server), a specific UserAgent or whatever?

Any signs of life for the SharePoint Extensions for Visual Studio?

Has anything been released – or, in fact, talked about – since August’s release of the v1.1 CTP?

Haven’t done any web-part development in a while and wanted to get back in the game. I last used the v1.0 extensions, and was surprised that nothing much has changed in that field except for the CTP release, and even that can’t be downloaded – I just get a broken link.

Dynamically creating a Sharepoint Web-Service proxy instance

In my current code, I find myself accessing many Sharepoint web services. In one run of code I can access 5-6 different web services on dozens of different sites, not necessarily even on the same server. Given that I find myself writing a lot of boilerplate code looking like this:

using (SiteData siteDataWS = new SiteData())
{
   siteDataWS.Credentials = CredentialsCache.DefaultNetworkCredentials;
   siteDataWS.Url = currentSite.ToString() + “/_vti_bin/SiteData.asmx”;

   // Do something with the WS.
}

Seeing as this is quite wearisome, I’ve decided to go an genericize it. Given also that the name of the ASMX file for all Sharepoint services is the same as the name of the class to be instantiated, it gets even shorter:

1:  public static WSType CreateWebService (Uri siteUrl) where WSType : SoapHttpClientProtocol, new()
2: {
3:    WSType webService = new WSType();
4:    webService.Credentials = CredentialCache.DefaultNetworkCredentials;

5:    string webServiceName = typeof(WSType).Name;
6:    webService.Url = string.Format(“{0}/_vti_bin/{1}.asmx”, siteUrl, webServiceName);

7:    return webService;
8: }

Line 1: Define a generic method that receives the type of Web Service and returns an instance of it. Note the generic constraints – the type must be a Web Service Proxy (SoapHttpClientProtocol) and must be instantiable. The last one is necessary for line 3 to compile.

Line 5: Get the name of the type – for our example above it would be “SiteData” – and build the URL based on the site URL and the web service name.

Now I can transform the above snippet to this:

using (SiteData siteDataWS = WebServiceHelper.CreateWebService(currentSite))
{
   // Do something with the WS.
}

Drastic change? No, not really. But it keeps things clean.

Some more glaring omissions in the Sharepoint 2007 SDK and Web Services

I downloaded the new Sharepoint 2007 SDK today, published last week though it’s dated from April 2007. There appears to be no change history for this version of the SDK.

I was hoping for more information on new Web Service methods available in 2007 – hoping that the lack of 2007-specific functionality was more of a documentation error than an actual oversight. It seems this is not the case.

I’ve written about the lack of item-level permissions in the WSSv3 web services before, but I’ve found some other serious problems.

Documentation-wise, the new ChangeLog methods (GetChanges() in various web services) remain almost entirely undocumented.

The Permissions web service, like the previous problem, seems entirely unmigrated to WSSv3 and remains identical to the WSSv2 version. The painful point for me right now is that AddPermissions accepts a 32bit integer for the PermissionMask parameter matching a value in the 32bit SPRights enum – even though WSSv3 marks that enum as Obsolete, replacing it with the 64bit SPBasePermissions enum. This means I cannot set permissions to any of the extended values via web services, only via the object model.

In short, I am quite disappointed with WSSv3’s web service support, and even more with the documentation. I get more information from the WSDL at http://myServer/_vti_bin/sitedata.asmx?op=GetChanges than I do from the documentation, and that’s a shame.

No Per-item permissions in WSSv3’s Web Services?!

How did I miss this until now? It’s great that WSSv3 and MOSS give us granular permissions, and it’s great that I can access those permissions via an SPListItem’s RoleAssignments collection – but is there really no way of getting this information in a web service?

The Permissions web service remains unchanged from WSSv2, GetPermissionCollection() receiving a List GUID and returning permissions for that list. Nothing for specific documents. Interestingly enough, the method also receives an objectType string, which could ostensibly allow us to pass other types of objects and get permissions data for them – but this apparently never made the cut for WSSv3 RTM.

This, for me, is a major roadblock. I am limited to accessing the built-in web-services only. I don’t have access to the Sharepoint server(s), and can’t write my own web-services to expose this data via the object model.

Has anyone ran into this and found a more imaginative workaround for this really painful oversight?

Retrieving all properties for a Sharepoint list

When we call the GetListItems or GetListItemChanges methods in Sharepoint’s Lists Web Service, we pass an XmlNode parameter specifying which fields we want to return, in this format:


  

Now, if we leave this field as null, we get a certain set of properties back – Name, Last Modified and so forth. Basic, commonly used properties. However, if we want to return ALL properties, and we don’t want to explicitly state them, we need to pass an XmlNode with an empty-but-valid ViewFields XML:

XmlDocument doc = new XmlDocument();
XmlNode viewFields = doc.CreateElement(“ViewFields”);
XmlNode results = wsLists.GetListItemChanges(myListGuid, viewFields, since, null);

Now I get a whole handful of properties to read to my heart’s delight.

All info via Karthikeyan‘s blog.

Customizing MOSS Page Title

Another odd client request that came in a while ago.

When we browse our Sharepoint site, IE’s title reads “Home – My Site Name – Windows Internet Explorer”. We can’t find any way to remove the “Home” string, regardless of how we change the site’s name. This is critical for our ISO review tomorrow!

Now, I’m no ISO reviewer, but it seems a bit excessive even for the strictest ISO test. But hey, I’m just your friendly neighborhood technical solutions provider.

The first step to changing it is to understand where this string is stored. Easiest way to do that is to open the default.aspx page with Sharepoint Designer. We can see it contains a content block that replaces the master page’s Title content placeholder.

This is the master page bit (line 14 on my unedited default.master):

<asp:ContentPlaceHolder id=PlaceHolderPageTitle runat="server"/>

And this is the replacement in default.aspx:


  

We can see that the title is made up of two parts, the localized “Home” string (in red) and the current site’s name (in blue) taken from the site’s properties. We have two options here – we can either find the resource string and change it, or remove it from the ASPX altogether (along with the connecting dash) and have a clean page title. The second option is pretty straightforward, so we’ll focus on the first:

text=”<%$Resources:wss,multipages_homelink_text%>” 

We can see that the actual text is retrieved from some Resource Manager. The format of the $Resources token is as follows:

$Resources:filename,localizedString

So what we need is the string “multipages_homelink_text” under the file wss.resx. Finding it, however, took me a while. I found the file under 12CONFIGResources (under the base 12 folder) rather than the more obvious 12RESOURCES. This folder contained wss.resx, and also wss.en-US.resx and wss.he-IL.resx, the two languages I had installed. Seemed fitting. Editing the multipages_homelink_text value in them, however, didn’t seem to change anything. So I expanded the scope again.

Seems that resx files in the 12 directory are only template files, copied to each specific Virtual Server when its created. From there on, the virtual server has its own copy of the resx files, residing under C:inetpubwwwrootwssVirtualDirectoriesApp_GlobalResources. There I found another copy of the wss.resx file, and changing the value there instantly updated the site, no IISRESET necessary. Joy!

Sharepoint Extensions for Visual Studio – released!

Finally, we have a full, RTM version of the Visual Studio extensions!
The download page says March 15th, but I haven’t seen anyone mention it around yet – could it be just me that missed the boat?
I got it from Mark Bower’s blog, but haven’t seen it mentioned anywhere else.

On one hand, this is great – the last version was from November ’06, and crashed often. Deployment seemed to work only for empty web-part projects and the Solution Generator crashed when trying to dump a whole site.

On the other hand, there are still many basic scenarios not covered by the tools – we can’t export a Publishing site into a site definition, or any list with a Lookup field. This is a huge drawback.  I hope they release a newer version soon, or perhaps a set of MOSS extensions (rather than WSS) that supports these scenarios.

Regardless, congrats to the team for releasing it for us, and keep up the good work.

Get it here:

http://www.microsoft.com/downloads/details.aspx?FamilyID=19f21e5e-b715-4f0c-b959-8c6dcbdc1057&DisplayLang=en

 

UPDATE: As sral and others reminded me, the main drawback of these extensions is that most of the functionality can only be used when running Visual Studio on the Sharepoint server itself. The most noticeable is the Deployment scenario, which is a pain to do manually.

This forces developers to either forego most of the benefits of the tools or start running Server2k3 on their dev machines, which is a hassle.

The alternative is of course to run a virtual machine for all development work, but this isn’t feasible in all situations. I only recently got my development machine upgraded to the point it can run a VM decently, and even now it could do better (2GB RAM, 1.5 of which go to the VM). What did I do earlier? Installed Win2k3 (sometimes on a dual boot) and cursed the slowness.

The current message, which is “You have to buy all your developers a fast machine and a copy of Win2k3” even if you only want to develop for the (freely available) WSS 3.0 is a bit off-putting.

I call for a WSSExpress edition, similiar to the other offerings from Microsoft. It can run on Vista only, I suppose, that wouldn’t be too bad. It’s time to get up off my lazy ass and upgrade. :)

Session Error with Reports Center under MOSS 2007 – Not what you expect

 Ran into a problem with a client today. They installed MOSS 2007 and created a publishing portal, but then decided to erase the Reports Center, since they had no use for it. A few days later, of course, they figured they DID want it after all, and recreated a new site, called Reports, using the Reporting Center template.

However, when trying to access it, they received this error: (click for full-sized image).

 

We have an error parsing the web.config, complaining that the PartitionResolver cannot be used, since we don’t have any session defined as SQLServer or SharedServer. This seems odd, since the very same line that throws the error seems to be defining the session state as SQLServer. It also seemed off since Sharepoint, to the best of my knowledge, didn’t even enable session state.

My first hint towards the solution – the file path. Notice that the source file is c:inetpubwwwrootweb.config. My portal is homed to the default location, c:inetpubwwwrootwssVirtualDirectories80 – so it should be reading the web.config there, not the one at the root. This led me to believe that there was some sort of Managed Path thing going on here.

I verified this by creating a new Report Center site called “ReportCenter”, rather than “Reports”. Sure enough, it worked just fine.

An even quicker test showed that, as I expected, SQL Server 2005 Reporting Services was installed on the same virtual root, and was hogging the /Reports virtual directory to itself.

Strangely enough, I checked out the Managed Paths screen in the Web Application’s Central Administration, but couldn’t find Reports listed. Guess it was still a conflict between the explicitly created folder and Sharepoint’s HTTP module handling the name.

Sharepoint Extensions for Visual Studio 2005

Any news on when a new release of the extensions are due? The state of the current tools is downright abyssmal. Even ignoring the requirement to run VS on the Sharepoint server machine, half the things don’t work or are horribly slow. The Sharepoint Solution Generator doesn’t support the most important sites I want to create a definition of (Portals, Publishing sites) and crashes randomly throughout, the WSP generator scripts take almost 5 minutes for a simple list definition, and the Sharepoint Workflow Designer is simply a mess, hard to understand what’s going on and how to match a correlationToken between tasks and workflows.

I’m doing a short Sharepoint training week here in Belfast, and half the time I’m forced to show them nice tools and explain why they can’t use them yet. :(

Even if the RTM release is still far off and there’s nothing stable enough to release as a beta or CTP, I’d appreciate hearing about any progress made. Does the extension team have a blog that I’ve missed where they release status updates, or haven’t they converted to the new, transparent Microsoft way? :)