June 2004 - Posts

To all of you who missed it: please join us next time! To those who were there: see you next time! Thank you Jelle for making all the practical arrangements. Can you make an “I Was There” button to brag about attending the first .be-geek-dinner?

The avid readers (if I have any of course) of my blog may have noticed that in the last 10 days there wasn’t a single new blog post on this site (I think the longest time ever since my honeymoon!). Well, there’s a reason for that: the last two weeks passed like a real whirlwind. Today I had a presentation on a seminar about Host Integration Server 2004 organised by my employer and Microsoft at a very nice location: Technopolis (if you life in the proximity of Belgium, you should really visit it!). I think the audience was quite impressed by the demo we gave of the project we’re working on right now. Kudos to my project team (especially Tom, William and Hans): you did a great job preparing the bits so I hadn’t any problems (the demo gods were with me)! And my apologies go to Tom because I called him my “demo monkey” on stage. :-)

Further more on the road ahead of my personal life, there are some thrilling challenges waiting which I’ve been planning in the past weeks. More on that real soon! To be continued…

In one of my previous posts about CAS issues when using SharePoint and the SmartPart, Maxim Karpov wrote some comments pointing to another solution. He mentioned he's working on an article that explains this matter in more depth. Today he has finished the article: Code Access Security (CAS) – "Guilty until proven Innocent" (Partially Trusted Code). Recommended!

A few people have reported some problems with the Workflow Lite for SharePoint RC1. When you're using the COPY action for example, the workflow engine reports the following exception in the event log:
Unable to instantiate event handler (assembly "Leadit.SharePoint.Workflow, Version=0.2.0.0, Culture=neutral, PublicKeyToken=3948f234bbbabe18", class "Leadit.SharePoint.Workflow.EventHandler"), or report event for "..." in "...". Could not execute the COPY action.(System.ArgumentException: Value does not fall within the expected range.

It turns out to be that it's not a bug, but a problem with the XML namespaces in the configuration file that was included in the setup package as an example. So everybody who's having that problem, check out my (corrected) previous post for an example config file. An updated version of the setup package will be uploaded tonight, I think RC1b is a nice name. :-) Anyway, I'm sorry for the inconvenience and I thank everyone for helping to solve the problem (especially Jessica J., who now owes me a beer!).

Security is hot these days, and that’s a good thing. But from the developer’s point of view, security can be a bitch sometimes. Code Access Security (CAS for short) is a wonderful and very useful concept, but developers need to know keep CAS in mind if they want their code to run. If you want to learn more about CAS in general, I definitely recommend Maxim Karpov’s article as a starter.

When you’re building SharePoint webparts (and when you’re doing ASP.NET in general), CAS really comes into play because in most scenario’s your code won’t have Full Trust. This means that it can’t do just anything, everything needs to be explicitly granted. For more information about CAS in combination with SharePoint, check out this article on MSDN.

When you’re using the SmartPart for SharePoint (also see my previous post) you’re in a special scenario with three involved parties: SharePoint, the SmartPart and your code. Let’s say you want to create a somewhat advanced user control (to show in the SmartPart) that connects to a web service (or a database), you’ll run into some problems. If you’ve already tried to do that when using the SmartPart, you’ll find the following exception in the Event Log:
Request for the permission of type System.Net.WebPermission, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 failed.

Why do we get that exception? By default, all the code that’s executed in the \BIN folder of the SharePoint site, uses a reduced set of permissions, specified in the web.config file (e.g. WSS_Minimal or WSS_Medium). The permission to connect to a web service (WebPermission) or to connect to a database, is not granted by default. That’s why the code won’t run. To solve this issue, one would think “let’s add that permission for the webpart”. But remember we’re using the SmartPart webpart, so adding permissions won’t help us because the user control code still has does not get the needed permissions. An easy, but drastic solution is to deploy the code to the Global Assembly Cache (GAC). Every assembly in the GAC, runs in Full Trust. Installing the SmartPart in the GAC is easy, during the installation the question is asked whether you want the assembly to be installed in the GAC or not. Deploying the user control’s assembly to the GAC is also quite easy (if your assembly has a strong name of course): drag-and-drop the .dll file to c:\windows\assembly. But there’s only one issue to solve: you’ll notice that once you’ve deployed the user control’s assembly to the GAC (and deleted it from the \BIN folder of course), you’ll get an exception (unable to load). So it seems that the SmartPart does not look in the GAC to load the user control’s assembly. To fix this (last!) problem, you need make some modifications to the web.config file of the SharePoint site: in the “compilation” section you need to add the user control’s assembly:
<compilation batch="false" debug="false">
  <assemblies>
    <add assembly="DropDownNavigationVB, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3948f234bbbabe18" />
    </assemblies>
</compilation>

All these steps may be a little bit overwhelming, so let’s summarize and create an example. The example will connect to a web service and fetch some weather information (I’ve used this web service from CapeScience).

  • Step 1: install the SmartPart and make sure you deploy it to the GAC.
  • Step 2: create a new ASP.NET web application that will contain our user control, name it for example WeatherInfo. Add a web reference to the GlobalWeather wsdl and name it WeatherServices for example. Add a new Web User Control to the project and name it WeatherInfo and add a Label control to it. Switch to code view, and type following code in the Page_Load method:
    private void Page_Load(object sender, System.EventArgs e)
    {
        WeatherServices.GlobalWeather gw = new WeatherServices.GlobalWeather();
        Label1.Text = "Temperature in Brussels: " + 
               gw.getWeatherReport("EBBR").temperature.ambient.ToString();
    }
    Because we will have to deploy the user control’s assembly to the GAC, we need to give it a strong name. So generate a public/private key pair, and specify it in the AssemblyKeyFileAttribute in the AssemblyInfo file. (more detailed information about this process can be found here) Additionally you can change the version number specified in the AssemblyInfo file to a fixed version number (e.g. 1.0.0.0), otherwise every build a new version number will be generated. Finally, you can build the project.
  • Step 3: deploy the user control’s assembly. To deploy the WeatherInfo.dll file to the GAC, you can just drag-and-drop it to the c:\windows\assembly directory, or you can use the GACUTIL utility. The WeahterInfo.ascx file needs to be copied for example to the \UserControls folder of the SharePoint site (this is not a default folder, so you need to create it yourself).
  • Step 4: Alter the web.config. As mentioned before you need to alter the web.config of the SharePoint site, so the user control’s assembly can be located in the GAC. To do this, find the compilation section, that looks like this:
    <compilation batch="false" debug="false" />
    and change it to:
    <compilation batch="false" debug="false">
      <assemblies>
        <add assembly="WeatherInfo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6185e98411448c6a" />
        </assemblies>
    </compilation>
    I use the Reflector tool to read the public key of my assembly (you can copy-and-paste the full assembly name, so you won’t make any typos).
  • Step 5: load the user control in SharePoint. Finally you can add a SmartPart webpart to a SharePoint site, that will load the WeatherInfo control. Set the User Control property to ~\UserControls\WeatherInfo.ascx and click the OK button. If everything went well, you now should be able to see the temperature in Brussels!

To conclude, I’ll repeat one of the first sentences of this post: security can be a bitch sometimes. :-) But we must think about CAS as a good thing. Even the extra steps considered, that need to be taken to get the WeatherInfo webpart running, I still think creating SharePoint webparts with the help of ASP.NET User Controls is a productive approach. But at the same time I’m wondering about how the GAC deployment step can be avoided. Anyone has an idea?

You can download the WeatherInfo solution from the GotDotNet Workspace. In the next post I’ll dive into how you can easily test-drive webparts when using the SmartPart webpart.

It’s always fun to see how your work can motivate people to do some real cool stuff. My friend, nephew and colleague Tom van de Kerkhof has created a TreeView Navigation Webpart, based on the SmartPart Webpart. Check out his post here. Nice work Tom! If you've create some webparts based on the SmartPart, that you want to share: don't hesitate to let me know!

Everyone who has created a webpart for SharePoint, knows that the “developer experience” is not as good as one would expect. You create the webpart in Visual Studio, based on the Webpart Template, but you can’t design the User Interface by drag-and-dropping controls on the webpart. But luckily you can use the “User Control technique” which gives the advantage that you can use the VS.NET UI designer. Patrick Tisseghem has evangelized this technique a lot, check out his article, his posts and the video. Fons Sonnema has written an article about how you can create and use a generic webpart that can host an ASP.NET User Control. I’ve extended this webpart with some extra functionality; let me introduce you to the SmartPart for SharePoint!

The SmartPart is a generic webpart that can contain an ASP.NET user control. Nothing new you would say, but the SmartPart can give your user control access to the SharePoint object model. So from within the code of the User Control you can do stuff with SharePoint! Another feature is that the user control can expose some properties which the SmartPart picks up, so the user can specify values for these properties in the SharePoint site. To prove you how easy it is, I’ve create a small demo. In this demo I will create a DropDownNavigation webpart in less than 5 minutes (it could be less, but I made some typos). The webpart will show a dropdown list in which the subsites of a SharePoint site are displayed. When a site is selected from the list, the user will be redirected to that site. Here’s the video.

First I create a new ASP.NET Web Application solution in Visual Studio.NET. Then I add a new Web User Control to the project. If you want to use the SharePoint object model, you need to add references to the SmartPart assembly and the SharePoint assembly. Next I add some code. When I’m done, I build the project (actually I try to build it, correct a mistake and build again). To be able to use the user control in SharePoint, I copy the assembly to the \BIN folder of my SharePoint site, and the .ASCX file to a newly created \UserControls folder. Finally I show how you can use the SmartPart webpart in SharePoint to load the newly created User Control.

Together with Fons, I’ve created a GotDotNet Workspace for the SmartPart. Over there you can download an installation package that will install the SmartPart, the source code and an example user control. At this point there isn’t very much documentation, but I will work on that. :-) There are a lot of cool ideas which (I hope) will be added to the SmartPart (for example a connectable SmartPart). I’ve IM-ed with Patrick today and he has another cool idea which he discussed in one of his latest posts: using the User Interface Process block together with web parts. Anyway, some nice ideas are waiting to be implemented!

It's my pleasure to announce another new Belgian blogger! This time it's my good friend Christof Claessens who finally has got his weblog up and running (thanks Scott!). If you're into BizTalk, keep an eye on him: he told me he will be posting some really cool stuff. So Christof, now you've got the audience listing, let's start the show! :-)

Jelle Druyts is organizing a Belgian Geek Dinner on the 25th of June. Sounds like fun to me!

Scott has posted an interesting example: a webservice that accepts any type of XML Document, which will be send to a single BizTalk receive port. Afterwards you can process the XML Document in an orchestration for example. Cool stuff, I can defenitly imagine some scenarios where this would be useful! With this web service you don't need to have a special web service for each type of InfoPath form you want to submit to BizTalk for example.
More Posts Next page »