Tuesday, February 9, 2010

Sharepoint Tips And Tricks

Web Services on SharePoint - making F5 Work

I was getting many questions on best practices to write custom web services for sharepoint, and I wanted to write an article about it for some time now. Also, I just had a chance to fiddle around with making F5 (run from visual studio into debug mode) work for a web service I am testing on a sharepoint site. This involved a few tricks, so I am documenting them:

Note - only do this on your development box!

Note - code lines marked in red means that you will need to change the values to your environment values.

I hold that the best practice is not to use the web service as a web application template (that is the default with visual studio) because when deploying to sharepoint, you'r web service usualy needs to sit in the layouts folder, and you do not want to deploy your code files there. You also don't want to use the visual studio publishing mechanism that uses the frontpage server extensions.
The alternative is creating a web service that is deployed as an asmx file to the layouts folder, pointing to a DLL that is deployed to the GAC. That makes it safe and secure, and easier to deploy and track versions.


Step 1 - Create a Web Service (DLL) Project

To create the web service, use Visual Studio 2005, and click "File-New-Project" and select ASP.NET Web Service Application.



If you don't have that project type installed, you may need to change the installed features of Visual Studio on your machine. The good think about this project type is that it creates a web service as a DLL and an asmx and not as a web site.



After the project is created, change the file names, namespace and assembly names as needed (make sure the namespace of the webservice attribute is changed - you don't want "http://tempuri.org/" as your namespace...) and most importantly - sign the assembly as strong name (right click the project, properties, signing tab, sign the assembly).




Now we have to find out the key that was given to the assembly when it was signed. To do that you must first build the web service (I use ctrl-shft-B, or right click the project and select build) and then either drag and drop the DLL to the assembly folder, right click and get the key:



Or you can run a command line from the visual studio SDK (start-programs-visual studio 2005-visual studio tools-Visual Studio 2005 Command Prompt) and type

sn -T "c:\temp\WebService1\WebService1\bin\WebService1.dll"



Once we have the public key token, we can change the web service's asmx file to use the DLL that will be deployed to the gac. Right click the service1.asmx file and choose "View Markup". You need to change the markup to point to the DLL that will be in the GAC, so this is the format you need to use:



<%@ WebService Language="C#" Class="WebService1.Service1, WebService1, Version=1.0.0.0, Culture=Neutral, PublicKeyToken=db33ac6baa259170" %>

Expalantion:

1.


The "WebService1.Service1" part is the "namespace dot classname" of your code. To get that, you will need to open your .cs file, and copy the namespace you are using, add a dot after it, and add the class name.

2. The "WebService1" (after the comma) is the name of the DLL that you may have set in the project properties under the "application" tab (the "assembly name")

3. The public key token is the key we got earlier.





Note - I am not sure if this is needed, but I also registered my web service as a safe control in the web.config, before I used any sharepoint code. It's worth checking if this is required or not, and I will update if I have time to test.


Step 2 - Setting up the Build Events

While in the project's properties, switch to the "Build Events" tab. Paste the following in the "post-build event command line" box:


"c:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe" /i "$(TargetPath)" /f

copy "$(ProjectDir)\*.asmx" "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS"

"C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\bin\RecycleAppPools.vbs"

"c:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\disco" http://localhost/_layouts/service1.asmx /o:"C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS"




Explanation:

1.


The first line puts the DLL in the GAC.

2.


The second line copies the web service asmx file to the layouts folder. You should make sure your projects do not create same names for asmx files, or they will overwrite eachother!

3.


The third line recycles the application pools. I am doing this with a vbs file that I have written, and placed in the 12 hive's "\bin" folder for my comfort. Here are the contents of the file:


Set locator = CreateObject("WbemScripting.SWbemLocator")

Set Service = locator.connectserver(strServer, "root/MicrosoftIISv2")

Set APCollection = Service.InstancesOf("IISApplicationPool")

For Each APInstance In APCollection

APInstance.Recycle

Next

echo "Recycle Complete."

4.


The last line build a discovery file for the web service in the layouts folder. if you installed your visual studio 2005 in a different location, you will need to change the folder path to the disco.exe file, and if you changed the name of the asmx (or if you have more than one) you will need to modify that as well. You will also want to change the url to point to a sharepoint site on your machine if you are not using the "localhost" header. In my case, I use the header "portal", so I change is to "http://portal".




Step 3- Change the F5 behavior

To change what happens when you press F5, switch to the "Web" tab, and change the start url to the url to the web service (I use http://portal/_layouts/service1.asmx), then change the "use IIS web server" and change the project url to the rool sharepoint url (I use "http://portal") and tick the "override application root URL and type the same url as the project url:





Last Step - set up your web.config to allow debugging

If you want F5 to work, and have visual studio debug the web service when you press it, the sharepoint web.config should be changed to allow debugging. To do that, you will need to open the web.config file for the virtual server you are using (in my case "http://portal" - which means the web.config is under "c:\Inetpub\wwwroot\wss\VirtualDirectories\portal80\web.config") and find the "<compilation>" tag, and set the attribute "debug" to true:




This is it!

If you didn't miss anything, you should be able now to press F5 and the web service will launch in the sharepoint context, with debugging in the visual studio! You can set breakpoints and debug the web service.









Passed another exam

Hi all,
I had passed yet another MSCTS 70-631 Windows SharePoint Services 3.0, Configuring. This completes the set, and now I have all four sharepoint exams under my belt.


I have to say that this one was the most difficult one for me, since it had many questions about topics I try not to touch - for example load balancing. I really don't understand why a sharepoint expert needs to know load balancing and what is the difference between multicast and unicast, and how you should configure the network adapters. On the other hand, some of the questions were easy for me because they had more to do with development (for example, if a custom web part gets installed and crashes with an unhandled error - what should the administrator do? The answer was easy for me, because I am a developer - but is it fair for an admin to get asked that?)


So all in all I am happy about this, and I plan to promptly forget everything I know about WSS and MOSS configuration and installation. Heck, people keep asking me questions about this - "Ishai, how do I configure forms authentication?" or "Ishai, I configured anonymous and it doesn't work" - and I am sick of it. My answer from now on will be "I don't know, but I will write you a web part to make it all better!".


Speaking of webparts, I didn't get any complaints about my enhanced content query webpart, so I am moving on and will start thinking of my next open source project. It is still in infancy, but I hope to let you know about it soon.


On an unrelated matter, I will be speaking at the Israeli SharePoint user group next month (19/9) about features and templates (hebrew web site) so if you are in Israel, come over and say hello.


While I am there, there is a Canberra user group without me, and I am still looking for presenters. I will keep you updated if you want to know who will talk. Last month we had Anthony Woodward from my company talk about sharepoint record managment compliance in general and with Australian-specific notes. It was quite interesting. If you want to present, give me a buzz (my contact form is on this blog - look for it!)









What's good and what's missing from WSS Visual Studio Extensions 1.1?


The Windows SharePoint Services 3.0 Tools: Visual Studio 2005 Extensions, Version 1.1 CTP were released, with
"Support for 'Web Solution Package' editing, List Instance item template ,List Event Handler item template,Bug fixes", so I decided to take a quick look at what's in the web part project template.


First, I liked the fact that now by default when you create a web part project you don't get the "Render" event that you used to get in the past. This caused many developers to start writing html in the Render event, and then be puzzled when the events on controls didn't work (see Server side controls and data binding in web parts in this blog).



I am still looking into it, but one thing that I would expect from a webpart project template is a wizard when creating the project that asks:


1. Do you want the web part to support connections? (add stubs for connection interface)

2. Do you want the web part to connect to a specific list? (add properties and functions to connect to a list)

3. Do you want a custom toolpane?



What do you think? what else would you want from a template?








New SDK, with a tool for BDC

Hey!

A new MOSS SDK is available, and it comes with a free tool to create BDC definitions (is this the end of MetaMan? I wonder...).
The new tool is called "Business Data Catalog Definition Editor"

MSDN already have articles on how to use the tool with web services and other systems.


Installing requires you to install SQL server 2005, so don't install on your production server (duh!), and be prepared for some drastic changes to your system when you install on your dev box.



The good news is that it can be installed on windows XP, proving that Microsoft are listening to us developers, and to our gripes about developing on a server...

I tried installing by running the MSI directly, but that didn't work (didn't install the SQL express, and the installation failed when it couldn't find SQL express).










Slides from Tech.Ed Australia 2007 - Templates and Features
Here are the slides I did in my presentation with Milan Gross (his slides are not included here, as they are his to publish):


I start we had the Tech.Ed image:




Next, our names and titles:





Some links and referances:

* http://www.microsoft.com/communities/default.mspx
*

Solution Deployment with SharePoint 2007 [MSDN]
*

SharePoint Solution Installer
Scott Hillier’s Open Source SharePoint 2007 Features
*

How to: Deploy UDFs Using Windows SharePoint Services Solutions [MSDN]









The agenda of the session (Milan covered that):





Here I spoke about the difference between templates (save as template for a list or a site) and definitions (file system xml and aspx files that allow developers and administrators have more control over the sites after deployment)




A quick explanation of how a solution package is built. For example I showed the package of the "print list" feature as it was done by Scott Hillier.



Next I discussed what are DDF files and why we need them (we need them to let makecab.exe know how to build our cab file - using folders), as well as giving some alternatives such as cabarc that allows you to build a cab file with folders in it - no need for a definition file. I also mentioned a tool I never used - WSPBuilder




Now to my part of the demo - I showed how to create a feature for a webpart and how to package it. I used my own Enhanced Content Query WebPart solution package to demonstrate this, and you can download that from codeplex!









After that Milan took over and showed a scenario that used the Solution Generator (part of the WSS extensions for Visual Studio) to create a site definition, with lists that are connected to workflows and have BDC fields and all. It was pretty complex, and I felt we needed more time to really explain it all.


And that was my first presentation. I will let you know about the second one soon.









How to remove farm administrators permissions from a site?
A friend asked me how can we remove farm administrators from having permissions on a specific site. Removing the permissions from the site collection and the site itself just did not work - the users who were farm admins could still browse the site and do whatever they want to it.

The answer was that in central admin, under "applications" there is a link: "Policy for web application" which allows you to set permissions at the web application level. It turns out that the farm admins have full permissions there for the application, and until you remove them from there, they will be able to go into any site in the web application.








Hotfix lets you store WSS data outside of SQL
If you missed this, give the following KB article a read. It is short, and to the point - a new hotfix is out that lets you store WSS data on external storage- out of SQL.

KB938499








My mark @ Tech.Ed

Ok, I am back, and boy, do I have some stories...

On the first day I had a presentation about templates and features with US consultant and trainer Milan Gross. I was not very satisfied with our presentation, and I think we should have kept the scenario simpler.
I showed how I built the wsp solution and features for the Enhanced Content Query Web Part and for the Print List feature.



My next presentation was with Gayan Peiris, who left my company to join Microsoft just a month ago. We did a presentation on upgrade and migration from sharepoint 2003 to 2007.
Now, before people start asking me how to upgrade I have to say that that was Gayan's part of the presentation. My part was warning about the customization upgrade (custom webparts, event handlers etc.), and about what is different in the new version that requires re-thinking on the information architecture.
That Session went very well, if a bit tight on time, and we got good reviews (7.62) even if we didn't get to the top ten.



After our presentation we left with all of tech.ed to Movie World, where I went, for the first time in my life, on a roller coaster - Lethal Weapon. I have been told by people with more expirience that this is the most frightening ride ever, everywhere. I can now believe it.
The only reason I was brave enough to go on the ride was that it was night - I couldn't see the ride. I was sure that a "lethal weapon" ride would be a video game with shooting in it.

Here is a picture of me on the ride:




Here is a movie of what the ride looks like:












MCTS in MOSS configuration

Well, Tech.ED Australia 2007 is over (I will post some details soon) and I am happy to let you know that I took the "Configuring Microsoft Office SharePoint Server 2007" exam (70-630) and passed! I only got 3 questions (out of 51) wrong, so I am pretty happy with myself right now.

Now I only have to do the WSS configuration exam to have the entire set!








Off to teched

So this is it - the moment I have been waiting for and the reason I didnt write anything in the last month. I am flying to the goldcoast tomorrow and will be presenting there this week. I will also be at the meet the experts dinner (as a self proclaimed expert) and at the influencer party (as an MVP).


See you there!


p.s. I released today a technical refresh to the content query web part project. more features, less bugs!








Modifying Search to Add a Send Link By Email link


My customer wanted a "send link by email" next to each search result item. "Easy", I thought and went ahead to edit the xslt for the search results. But I found out a problem with links that had spaces in them - the link in outlook would appear broken. To solve this, I had to write some simple javascript, and the process is described below.



Problem:


If you want a mailto link (href="mailto") that has in the body a link to a file, you may get a link like this:


href="mailto:body=http://server/site/library/this is my file.doc"


This is a problem, because the file name contains spaces. The email will open with a broken link in it's body:




Solution:

Luckily, SharePoint has a javascript functions that solves that for us. They are "escapeProperly" and "navigateMailToLink". What I did is create a function of my own in the page:

function SendEmailWithLink(link)
{
var link = "mailto:?body=" + escapeProperly(link);
navigateMailToLink(link);
return false;
}




And my link is:

href="#nowhere" onclick="javascript:SendEmailWithLink('');"



This article would'nt be complete if I didn't explain why I did this - this if for the search results xslt - the idea was to add a "send link by email" button next to each search result. The solution - change the xslt to include the script above, and a button like this:




javascript:SendEmailWithLink('');









We also added other actions (I will try to get them published) and came up with the following for each result item:













Search query default row limit is 50 rows


Just something that happened to us - we were wondering why all the search queries that one of our developers wrote in a web service were only returning 50 results everytime. The answer was simple - if you don't specify a RowLimit to the query object, the default is 50.


The solution is easy - set the RowLimit property to the number that you want.










Live vs Google

Every now and then someone from Microsoft asks me why I don't use Live Search as my search engine. My answer is always the same - results are awful!


In my opinion Microsoft have a lot to learn before getting us a proper search engine.

GOOGLE

First - try searching for "sharepoint australia" (without the quotes) - in google, the first results is Angus Logan's blog and the second is the APAC conference from two months ago.
The third results is my post about me presenting at teched australia.
The fourth - my user group in Canberra.

LIVE

Now do the same with Live - first result is the APAC conference, next is the site for WISDOM - where they sell sharepoint related products. Next, a broken link to a page in obs.com.au that does not exist any more - another company that works with sharepoint.
Why is it broken? Well, the link under is is also to the same site, but this time the aspx page doesnt have an underscore and it works.

As we go down in the page, we see more and more sites of vendors trying to sell you something, or microsoft's own site. Not a single blog or user group site in sight.



My conclusion - Google results are quality based, while MS results are commercially based. And until they change that - I AM NOT USING LIVE.



Note - this was triggered by an old blog post by Arpan about how he uses Live search because it is better.









Enhanced Content Query Web Part goes Beta 2!


I am proud to announce that the Enhanced Content Query Web Part is now beta 2. The new release includes a WSP deployment file that simplifies deployment - just download the file, and use STSADM to install it - no more messing around with web.config, .dwp or .webpart files, or xslt style sheets!

I even wrote a small batch file to help you install it if you are uncomfortable with the stsadm command line.


You can find the above in the project's web site: http://www.codeplex.com/ECQWP


The new version also comes with default xslt files that get installed in the style library and render the web part like a list (table format):




Now, to get to release candidate, I still need:


* Testers (must have own server)

* Technical Writers (must have own server)


Testers need not contact me - they should just go to the project web site and start entering bugs in the Issue Tracker.


Writers should contact me and I will ask them to write up the installation instructions and usage documentation.










I am presenting - Tech Ed Australia 2007.

It is official - I will be presenting two presentations in Tech Ed Australia 2007:


* OFC304 Microsoft Windows SharePoint Services and Microsoft SharePoint Portal Server 2003 Upgrade and Migration


Do you want to learn about upgrading from Windows SharePoint Services version 2 to version 3, and SharePoint Portal Server 2003 to Office SharePoint Server 2007? In this session you will learn the different upgrade options, as well as how to prepare your SharePoint deployment today for upgrade.
*

OFC402 Templates and Features: The Engine Under the SharePoint Hood - Build and Deploy Your Own!

Microsoft Windows SharePoint Services version 3.0 provides many new capabilities for extending existing sites and building new solutions. This session outlines the high-level concepts of SharePoint templates, features, and extension points; and discusses the best practices for deploying code to a SharePoint farm, including code access security and the new solution deployment capability.



I will also be available for Q&A, and am always happy to answer questions - so come meet me in Tech Ed, and let me know how you liked my presentation!











Tips on xslt dataviews by Mark Kruger!
Take a look at "Free SharePoint DataView Tips" by Mark Kruger. Useful!








Adding table headers and/or footers to a Content Query Web Part Layout


Just found this article by Mike Gehard which shows a good step by step of making a content query web part look like a grid - with column headers and all.



Mike is even using the same ddwrt trick as I am for formatting dates, and I now see that his blog seems to be dedicated to the content query web part!








I recommend you go to Mike's blog and read all about it. The method he is taking is chaning the "ContentQueryMain.xsl" file to pass the lastrow as a parameter to the "CallItemTemplate", and then in "CallItemTemplate" he passes the lastrow to the apply templates itemstyle.


In the "Itemstyle.xsl" file you add html variables for the header and the footer, and use them before the first row and after the last row.

I will try to contact Mike and ask for permission to reprint his article here for redundancy.


Mike - if you are reading this, how about you join the Enhanced Content Query Web Part project?








Using DDWRT in xslt-based web parts


What is DDWRT?
well, its a script that microsoft packaged for it's xslt dataviews, that gives them more xslt power.
I needed to use the ddwrt functions in my content query web part, but I guess that the following approach will work in the search web parts as well.


Why do we need it?

I needed it to format the date I was getting back from the content query. The format I was getting back was ugly to the user (2007-06-27 15:52:00) and I wanted to format it, but I didn't want to write my own function.


So how to use it?

you need to add to your xslt the following namespace where the namespaces are declared (at the top of the xsl file, in the "xsl:stylesheet" tag):

xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"



Then you can use the ddwrt's functions. For example, to format the date I used the following:



Note that in the FormatDate function I used 2 hard coded values - 3081 which is the LCID for Australia (so the date will be formatted to Australian date format) and 5 which specifies the what do I want to display - date, time, date and time ect. I have no idea what values give what, but I do know that 5 gives me the date and the time.








Update to ItemAdding fiasco
This is to let you know that I updated my posts about the event handlers and ItemAdding, after I did some more research and found the correct way to get and set item's properties during ItemAdding. I swear this method did not work during Beta2 when I posted my old posts, and I swear that contacts in Microsoft did tell me it was by design and not possible (I have the emails to show that).
However, it turned out that it is possible, and easy, and I posted an update and a code sample in the old posts:

Bad news - synchronous list events bug (or missing feature)

Synchronous Add List event (ItemAdding) will not give access to item properties








Great MSDN developer article - Development Tools and Techniques for Working with Code
There is a new article in MSDN which enraptured me. It is a magnificent summary of what development in sharepoint is all about, with example on how to do sample tasks.
It is in two parts, and is from my fellow MVP Patrick Tisseghem, (from U2U, Patrick is one of the authors of my favorite sharepoint developer utility - the CAML Query Builder)

Development Tools and Techniques for Working with Code in Windows SharePoint Services 3.0 (Part 1 of 2)


Development Tools and Techniques for Working with Code in Windows SharePoint Services 3.0 (Part 2 of 2)








Call for beta testers! Enhanced Content Query Web Part


This is to call beta testers. I want to kick the ECQWP project to beta2, which requires beta testers to start testing and reporting on Beta 1 (well, 1.3 actually) .

You don't need to write to me or anything - just get a free codeplex account, and use it in the ECQWP project site to add issues (bugs) to be fixed, or ask for enhancements.


Please try to be VERY clear on the problem - preferably with a step by step of what I need to do to get the error you are describing.


While I am at it, if you are a good SharePoint developer and you think you have the ability to solve the bugs, let me know, and I will add you to the project as a developer, and assign bugs for you to fix.

Please note - this is not a practice run. I do not have time to mentor beginners, so don't use this as a free training exercise. Sorry.









Adding custom fields to the Enhanced Content Quey Web Part (Beta 1.2)


I just got around to adding another important feature to the Enhanced Content Query Web Part and I uploaded it to codeplex.

I am sure you read my articles, or articles by other MVPS like Heather about showing custom columns in the content query webpart. This requires (as Heather's article shows) that you export the web part to a file, manually modify the file to add the fields you want, and import it back.

This annoyed me enough to add a property to my ECQWP that will allow you to add those fields without having to export-import.



In this version (1.2) you have two new properties in the propeties pane - Data Fields and Common View Fields. I have yet to find out how Data Fields are used, so you don't need to use that property - it is enough that you set the Common View Fields.

I will refer you to Heather's article to find out the format that the value of this property should be written in - how to get the field's internal name, and how to get the field's type. Just a quick reminder though - the value in that field is a pipe seperated value of fields, where each field is a coma seperated pair of field (internal) name and field type.
For example, a text field with internal name "Comments" will be added like so:

Comments,Text

A choice field with internal name "Client_x0020_Name" will be added like so:

Client_x0020_Name,Choice

and if we want to add both of the above fields, it will look like so:

Comments,Text|Client_x0020_Name,Choice





As always, get the web part, installation instructions and source code from codeplex. Just be sure to download the most recent version.










Enhanced Content Query Web Part upgraded to Beta 1.1

I am happy to announce that the Enhanced Content Query Web Part project has progressed to Beta 1.1, with some very important fixes to major bugs.


The web part now correctly prints out the item ID, has context menus for folders (not just documents) and supports displaying icons for documents.

Be sure to read the documentation (installation instructions) and use the new XSLT that is provided there. The old XSLT will not solve any of the bugs I fixed.










Community Kit for SharePoint 2.0 Pre-Release
You can read about it in the SharePoint team blog - there are some pre-release components from the Community Kit that are ready for download.


The downloads are:

Enhanced Blog Edition Beta 1

Enhanced Wiki Edition Alpha

ChatterBox AJAX Beta

Tag Cloud









Using Javascript to Manipulate a List Form Field


This is something I have been doing for a while (see my nested tasks project - it has been using this trick), and now Rob Howard from Microsoft published a tip on how to use javascript to manipulate a list form field.


The example of use I would like to give is my nested tasks project- we need to set a default value when a user creates a sub task. We have a web part sitting in the "newform.aspx" page, and checks the querystring the page was opened with. If the page was opened with a querystring of "parentID=", then it loads the item that is the parent, gets the values for start date and end date, and then uses javascript to set the "Parent Task", "Start Date" and "End Date" fields.

My javascript also hides the "Parent Task" field control from the user, so he will not edit it manually. This gives us a very user friendly interface.


The same trick can be used to implement some custom validation - for example not allowing the user to enter a start date before the start date of the parent.

No comments:

Post a Comment