Jan's Link Blog

Jan Tielens' collection of interesting links, articles, blog posts, etc.

My Links

Blog Stats

News



U2U provides .NET development training, coaching and consultancy services. We are based in Brussels but active in Europe, Middle-East and Africa. If you are interested in our course calendar or want to organize an on-site training, have a look at our Web site - http://www.u2u.net

Archives

Post Categories

Tuesday, September 06, 2005 #

SmartPart Version 1.1: Alive and Kicking

I know I promised the new version of the SmartPart for this weekend, but minutes before I wanted to upload the bits to GotDotNet Workspace I found a small issue. It took me some time to find the bug, but now I’m proud to present to you the SmartPart version 1.1! Before you all start downloading the latest version, here’s an overview of the new features:

Support for Custom ToolParts
If you develop web parts the hard traditional way, you probably know that you can create custom tool parts for your web parts. These tool parts will show up on the right hand side when you click “Modify Shared Web Part” in the same area where you can modify default web part properties like Title, Width, etc. Now you can create User Controls which can provide Custom Toolparts, just like the “real” web parts. If you download the latest release from the GotDotNet site, you will find an example of this technique. It comes down to this: if you implement the SmartPart.IAdvancedUserControl interface, you will have a function that can return an array of toolparts which will be shown by SharePoint.

Access to the underlying web part instance
Now it’s possible to access the web part that hosts your user control. So it will be possible to get or set properties of that web part from your user control. In the latest release you will find an example that can change the web part title from code.

“Hidden” custom properties
In the previous version of the SmartPart, the only way to persist a value was to implement a public property and decorate it with the Browsable attribute. The side effect was that this property would show up in the web part’s tool part so user could access it. In many cases this is the desired behavior, and this is also applicable to the new version of the SmartPart. But suppose that you’d like to persist a value that shouldn’t be available for the user. Now you can easily get or set values for a property that will not be exposed to the user by using the GetCustomProperty and SetCustomProperty functions of the smart part web part instance.

Various minor improvements
Some minor changes are made to the code to improve performance and behavior of the SmartPart.

Backward compatibility
All the interfaces used in the previous version of the SmartPart are left untouched, so theoretically you should be able to upgrade your user controls without having to change anything to your code. If you want to make use of the new version, you have to use the new SmartPart.IAdvancedWebPart interface.

I’m planning to record some short webcasts to illustrate how you can use the SmartPart. The first episode is about the installation, and you can find it over here. Maybe there are some people that want to share their experiences with the SmartPart or talk about the projects in which they have used it. It would be totally cool if we could to some sort of podcast about the SmartPart success stories, if you’re interested, drop me a line and we’ll arrange a Skype session.

posted @ 3:46 AM | Feedback (18)

Friday, September 02, 2005 #

Season 05/06 Started: PDC + SmartPart v1.1

Pfew, it has been a while since my last noticeable blog post. I'm sorry for my avid readers who have visited my blog in vain in the last couple of months. Just to kill some rumours: I don’t have a blog restraint, I haven’t transformed into a Websphere junkie and I’m still alive. :-) Holidays are over and I’m ready for the new Blogging Season!

So what’s coming in the near future? The PDC is real close now, in a little more than one week I’ll be in L.A. to attend my first big Microsoft convention. Stay tuned for some blog reports about SharePoint, Office and other Information Worker related news from the PDC.

What’s better to start the new season by making a nice announcement? Tonight I’ve finished a new version of the SmartPart, it has the following new/improved features:

  • support for custom ToolParts
  • easy access to the underlying web part
  • support for custom properties without exposing them in the property toolpart
  • various minor improvements

Although the code is built and packaged, I haven’t released the new version to the GotDotNet Workspace yet. I want to create some accompanying documentation first. I’m not going to write a lot of documents, but I’m thinking of recording some webcast style videos (easier for me and easier for you). I expect this to be finished this weekend. If you can’t wait and you want to give it a try without documentation, contact me for the bits.

posted @ 4:15 AM | Feedback (8)

Tuesday, July 12, 2005 #

See you @ PDC ’05!

I’ve just registered for the “Microsoft Professional Developers Conference 2005, where the next waves of Microsoft Windows "Longhorn" features and Microsoft Office System developer capabilities will be unveiled”! I’m looking forward to see all the new IW stuff (like the new versions of SharePoint and Office) go public. Keep an eye on the Conference Tracks and Sessions page for the latest news. The PDC is also the place-to-be to finally meet all the geeks, bloggers and fellow MVP’s I know only from the online world. So, see you @ PDC ’05!

posted @ 10:06 AM | Feedback (120)

Sunday, June 26, 2005 #

BizTalk Adapter for SharePoint Version 2

This is good news! There is a new version of the BizTalk Adapter for SharePoint released on the GotDotNet Workspace. It seems that the adapter was launched at TechEd USA, you can view the web cast online over here (including a demo of the BizTalk 2006 Adapter). Here is my little summary:

Features of V2:

  • Side by side install with V1 (no upgrade scenario)
  • Exposes properties in Context (like originating folder etc.)
  • Security Credentials per Endpoint (also accessible through context properties!)
  • Binary file support (!)

BizTalk 2006 WSS Adapter:

  • Includes all features of V2
  • Integrated setup, configuration, and deployment experience
  • Support of Form library, View, and List
  • Integrated Office InfoPath experience

posted @ 4:01 PM | Feedback (41)

Thursday, June 23, 2005 #

Common Security Pitfalls for Web Part Developers

I've wanted to write this post for a long time, the trigger to actually write it was my interview by Chris Kunicki for his Office Zealot podcast last week. During this podcast (which was really fun to do, thanks for having me Chris!) we discussed briefly some security problems web part developers could face. Podcasts are great but they are not suited to communicate code, so here's the accompanying post! When you're developing web parts, security could be one of the biggest problems to deal with. First of all you may face some problems to get your web part deployed and secondly you may have some Code Access Security problems. Let's take a look at both of them!

When you develop web parts using the traditional way (using the Visual Studio.NET Templates), you have to create your web part class and a DWP file before you can deploy your web part. Additionally you must alter the Web.Config of your SharePoint site, and add your web part in the SafeControls section. Once everything is in place, and you want to drag and drop your brand new web part on a page, you may get the message "A Web Part or Web Form Control on this Web Part Page cannot be displayed or imported because it is not registered on this site as safe". If you get this message, either something is wrong in your DWP or something is wrong in your Web.Config. Common mistakes are:

  • Wrong AssemblyName in DWP: if you have a strong named assembly (using a SNK file) your assembly element should contain the complete name (including the version, culture and public key token. An easy way to retrieve that name is the using the Reflector tool.
  • Wrong Assembly in Web.Config: same remark, the Assembly attribute should contain the complete name of your assembly.
  • Wrong TypeName DWP: the type name of your class is prefixed with the namespace. By default your namespace is the same as your Visual Studio project name.

Example of a DWP file:

<?xml version="1.0" encoding="utf-8"?>
<WebPart xmlns="http://schemas.microsoft.com/WebPart/v2" >
 <Title>SmartPart 1.0.0.0</Title>
 <Description>The SmartPart User Control Webpart</Description>
 <Assembly>SmartPart, Version=1.0.0.0, Culture=neutral, 
PublicKeyToken=dd064a5b12b5277a</Assembly> <TypeName>SmartPart.UserControlWebpart</TypeName> </WebPart>

Example of SafeControl node:

<SafeControl 
Assembly="SmartPart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=dd064a5b12b5277a"
Namespace="SmartPart" TypeName="*" Safe="True" />

Using the SmartPart to create web parts solves these issues. You don't need to create a DWP file and you don't need to change your Web.Config! Once you have deployed your web part, you may have some problems regarding Code Access Security. Out-of-the-box SharePoint is running with a trust level that contains very limited privileges. For example: you can not access the object model or a web service; this will give you a security exception. If you take a look at the Web.Config file, you will see that SharePoint is running using the WSS_Minimal trust level (<trust level="WSS_Minimal" originUrl="" />). Where is this WSS_Minimal defined? Well if you look in the securityPolicy section of the Web.Config you will find:

<securityPolicy>
  <trustLevel name="WSS_Medium" 
policyFile="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\60\config\wss_mediumtrust.config" /> <trustLevel name="WSS_Minimal"
policyFile="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\60\config\wss_minimaltrust.config" /> </securityPolicy>

So WSS_Minimal is pointing to a trust level which is defined in the wss_minimaltrust.config on your hard disk. As you can see, another default trust level is WSS_Medium which will add permissions to access the object model. If you write a web part that uses the SharePoint object model, make sure you set the trust level to WSS_Medium. What about web parts that contain really dangerous stuff like accessing a web service or, even worse, writing a file on the hard disk? Well you need to make sure that you web part is running with elevated privileges. So far the theory, how can we do this? There are several possibilities:

  • Set the trust level in the Web.Config to full. This will solve all your CAS problems because everything will be running with full trust. Of course this is not a good solution, so use it only on your dev machine for testing reasons!
  • Deploy your web part assembly to the GAC instead of to the BIN folder. Assemblies deployed to the GAC will run with full trust, so it solves all CAS issues for the assembly in the GAC. Is this a good solution? In my opinion this is abusing the GAC to gain full trust permissions. I know some people would argue differently, but my advice: do not abuse the GAC for this. Especially during your development cycle, assemblies deployed to the GAC are cached so you will need an IISReset when you deploy a new version.
  • Create a custom policy file that will grant full trust to your own assembly. This is my favorite solution; it's the most difficult to implement, but it's very secure and you only have to do the work once.

In the custom policy file, you can grant for example full trust permissions only to your code. But what is your code, how do you identify your code? Well (once again in my opinion) the nicest way is to grant full trust to code that is signed with a specific public key. It's very secure and reusable, as long as you keep using the same public/private key pair (SNK) to sign your code, all your code will be running with full trust. If you want to use this technique, follow these steps:

  • Create your web part, and give your code a strong name by using a public/private key pair (SNK).
  • Create a customized policy file. The easiest thing to do is to start from the default policy files, for example the wss_mediumtrust.config file.
  • Copy that file and name the new file wss_customtrust.config for example. In this policy file you will need to add the following section, right after the FirstMatchCodeGroup:
<CodeGroup class="UnionCodeGroup" version="1" PermissionSetName="FullTrust">
 <IMembershipCondition version="1" class="StrongNameMembershipCondition" 
PublicKeyBlob="your public key blob"> </IMembershipCondition> </CodeGroup>
  • By adding this section to the policy file you will assign full trust permissions to all the code that is signed with that specific public key blob.
  • How do you retrieve the public key blob? The easiest way to do this is to use following little trick:
    • Start the Microsoft.NET Framework 1.1 Configuration (from the Administrative Tools)
    • Open Runtime Security Policy/Enterprise/Code Groups/All Code (actually what you open doesn't matter because we're not going to make any changes in this tool).
    • Right click on the All Code node and choose "New..."
    • Choose "Dummy" as the name (don't worry we are not going to save this!)
    • As the condition type choose Strong Name.
    • Click the Import button and point to your web part dll.
    • The public key blob will appear in the text box so you can easily copy and paste it in the IMembershipCondition node.
    • Cancel everything in the Microsoft.NET Framework 1.1 Configuration tool. (Do not save any changes!)
  • Once you have saved the wss_customtrust.config in the same folder as the default policy files, you need to alter the Web.Config file so your new policy file will be used. So change the trust node to
<trust level="WSS_Custom" originUrl="" />

In the securityPolicy node, add following node:

<trustLevel name="WSS_Custom" 
policyFile="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\60\config\wss_customtrust.config" />

You're done. When you test your hard work, you may end up with the "Assembly <assemblyName> security permission grant set is incompatible" exception. Don't worry, you'll need an IISReset. To give you all a head start I've uploaded my own prepped wss_customtrust.config. It's a modified version of the wss_mediumtrust.config that already contains the UnionCodeGroup to give code singed with a specific public key blob full trust. The only thing you need to replace is CHANGE_THIS, put in your own public key blob over here. This may look like an awful lot of work, my advice do it right the first time and you won't have any CAS issues anymore.

Although using the SmartPart to create web parts has some advantages, it doesn’t solve your CAS problems. Make sure you’ve assigned a strong name to your Web Application project that contains your user control, and use that strong name in a custom policy file as described above.

If you want to learn more about CAS, I would recommend visiting Maxim Karpov’s blog. He has written a couple of must-read articles and he has helped me with my own CAS problems some times. :-)

posted @ 10:23 PM | Feedback (5)

Wednesday, June 22, 2005 #

Adding web parts programmatically in SharePoint

When I’m delivering a SharePoint developer course I usually challenge my students to think of something that they would like to do in SharePoint with the object model. So far I always have been able to write the code, and today I got another interesting challenge: how can you add a web part to a web part page in code.

 

The code to accomplish this is quite easy, basically there are two scenarios: you add a web part that is displaying data for a list, or you add any other web part (e.g. a custom web part or a 3rd party web part like the SmartPart). The code for the first scenario is:

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;

// Get a reference to a web and a list
SPSite site = new SPSite("http://localhost:8000");
SPWeb web = site.OpenWeb();
SPList list = web.Lists["Contacts"];

// Instantiate the web part
ListViewWebPart wp = new ListViewWebPart();
wp.ZoneID = "Left";
wp.ListName = list.ID.ToString("B").ToUpper();
wp.ViewGuid = list.DefaultView.ID.ToString("B").ToUpper();

// Get the web part collection
SPWebPartCollection coll = 
	web.GetWebPartCollection("default.aspx", 
	Storage.Shared);

// Add the web part
coll.Add(wp); 

  

First you get a reference to the SPWeb in which you want to add the web part, and to the list you want to use (in this example the Contacts list). Next you create an instance of the ListViewWebPart class, in which you can set the ZoneID, the ListName and the ViewGuid. This is the tricky part, the ListName property should contain the ID of your list (a GUID), not the name of your list!! But the ListName property is of the type string, so you need to convert the List GUID to a string using .ToString(“B”).ToUpper(). The same goes for the ViewGuid. Finally you need to get a reference to the WebPartCollection for the page in which you want to add the web part (in this example the home page, being default.aspx). Now you can add the web part using the Add method.

 

For the second scenario, the code is as follows:

// Get a reference to a web and a list
SPSite site = new SPSite("http://localhost:8000");
SPWeb web = site.OpenWeb();

// Get the web part collection
SPWebPartCollection coll = 
	web.GetWebPartCollection("default.aspx", 
	Storage.Shared);

string dwp = @"<?xml version=""1.0"" encoding=""utf-8""?>
<WebPart xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns=""http://schemas.microsoft.com/WebPart/v2"">
<Title>SmartPart List 1.0.0.0</Title> <ZoneID>Left</ZoneID>
<Assembly>SmartPart, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=dd064a5b12b5277a</Assembly>
<TypeName>SmartPart.UserControlWebpart</TypeName>
<UserControlPath xmlns=""SmartPart"">
~\UserControls</UserControlPath></WebPart>"
; coll.Add(dwp);

The first section is the same, get a reference to your site and the WebPartCollection (you don’t need a reference to a list). Next you need to build a XML string containing the information about the web part you want to add. The contents of that string are the same as the DWP file that you need to create to use your custom web parts. A trick to figure out what needs to be in there (especially if you want to specify values for some properties) is to put the web part on a page (using the web interface), and choose “Export” from the dropdown menu of the web part. This will save the contents of the DWP in a file. Finally you can add the web part by calling the Add method of the WebPartCollection and using the dwp string as a parameter.

posted @ 4:00 PM | Feedback (11)

Thursday, June 09, 2005 #

Getting Started With ASP.NET 2.0 Web Parts in Beta 2

Here's a small tip for Patrick, since he's going to deliver a TechEd Session on Web Parts in ASP.NET 2.0. :-) An important thing in your web part pages is the functionality to switch to design mode (at run-time), so your users can change properties, location, connections etc. for the web parts. In the pre-Beta2 age, we had the WebPartPageMenu control for that, but in Beta 2 this control has been removed. The QuickStarts seem to be using a custom control that is simulating this behavior, but they don't provide the source for it. Luckily it's quite easy to re-create, you can switch by using WebPartManager1.DisplayMode = WebPartManager.DesignDisplayMode; and WebPartManager1.DisplayMode = WebPartManager.BrowseDisplayMode;. Check out Darren's post for more info!

posted @ 8:15 PM | Feedback (40)

Tuesday, May 31, 2005 #

My Media Center Experience

A few weeks back I decided that it was time to move on to the next era of watching TV: having a Media Center PC. Since we already have a couple PC’s at home, I had to find a budget solution to convince my wife, so I “transformed” an “old” PC into a state-of-the-art Media Center. The configuration of the PC is pretty straight forward: a Pentium IV running on 3Ghz, 1GB of RAM, and a 75 GB hard disk. The only hardware that I had to buy was a TV tuner card and a remote control. I went for the Hauppage WinTV-PVR 500 MCE which has 2 TV tuners, so you can record something and watch something else at the same time (a must have feature in my opinion).

 

The installation of Windows XP Media Center Edition was quite easy, just like a normal Windows XP. Also the Hauppage card installation was a bliss (got the latest MCE drivers from their site). The remote control (which comes with an USB infrared receiver) is really just plug-and-play, no driver installation required. After this easy installation came a disappointment: watching Live TV on the Media Center caused a lock-up after some time (some times after 5 minutes, sometimes after 60 minutes). I also noticed that when the PC was going to crash, the audio and video were getting slightly out of sync. I tried a lot of things to solve this issue: getting the latest drivers for all my hardware, getting the latest updates for Windows XP MCE, disabling hardware one by one and so on. But none of these solutions solved the crashing. Finally I looked on the internet for some help and on many forum postings (see links below) I found many people having the same problem. Luckily some of them were kind enough to post their solution! The solution is: do not use the latest NVidia drivers for your video card (I used a NVidia 5700)! The magic number is 66.93, when I installed this version of the drivers my problems went away. So now my Media Center is running like a charm!

 

After a couple of weeks using the machine, I’m convinced that it enhances my overall TV experience. I don’t have a lot of time to watch TV, and the typical problem is that when I can watch TV, there’s nothing on TV! Now with the Media Center, I have always something to watch: it’s so easy to record something; watch it and delete it. I just love it! I was a little bit afraid that my PC couldn’t handle recording and viewing Live TV at the same time (cause it’s not the latest hardware), but even recording two things and watching a record show at the same time works without any glitches. Very nice! The next thing I need to figure out is how to burn a recording to a DVD which can be played on normal DVD players as well. I’ve tested some applications like ArcSoft ShowBiz, but the creation of a DVD takes 2 hours. Anybody found some faster applications?

posted @ 8:08 AM | Feedback (7)

Wednesday, May 11, 2005 #

Excel XML Toolbox for Microsoft Office Excel 2003

A must have tool for every Information-worker-technology developer, get it from the MS Download Center.

The Excel XML Toolbox for Microsoft Office Excel 2003 provides many useful tools for working with XML in Excel. This toolbox helps developers in a number of ways:

Working with Custom-defined XML Schema

  • Reload schema into workbooks while preserving cell mappings.
  • Build a schema or add to an existing schema, directly from Excel.
  • View the schema for XML maps stored within workbooks.

Working with XML and the Excel Object Model

  • Quickly refresh all XML maps with bound data sources.
  • Refresh XML maps with bound data sources and persist cell formulas for mapped cells.
  • Use a new XML Range Properties tool to view XML mapped cell properties and to copy the XPath or Microsoft Visual Basic for Applications (VBA) statement to the Clipboard.
  • View the exportable XML data without exporting.

Working with SpreadsheetML

  • Quickly save the workbook as SpreadsheetML.
  • View the SpreadsheetML for the active workbook.

Shortcuts and More

  • Quickly open and close the XML Source task pane.
  • Turn on and off the borders for XML mapped cells.
    Import and export XML.

posted @ 6:53 PM | Feedback (5)

Monday, May 09, 2005 #

Pint2Share/Geek Dinner @ State College, PA (USA)?

Next week I'll be in State College, PA to deliver a SharePoint course. Any SharePoint fans or just general geeks around who want to meet?

I'm staying in this hotel, so I hope I got the location right. :-) Maybe someone has some tips for an European tourist; things to visit/to do after work?

posted @ 10:46 PM | Feedback (10)