Attention: We are retiring the ASP.NET Community Blogs. Learn more >

Fear and Loathing

Gonzo blogging from the Annie Leibovitz of the software development world.

  • Folder taxonomy and path limitations in WSS

    There's a path limitation in WSS so when you have a document library with versioning turned on, at some point previous versions of a document will vanish into the ethers of SharePoint. It only happens with past versions so your current version is fine no matter how long the path is. To test this out:

    1. Create a document library in a WSS site and enable versioning
    2. Start creating folders inside of folders inside of folders
    3. Upload a document and do a quick check out/check in to create 2 versions
    4. Select the version history for that document and view version 1 of the document
    5. You should get a HTTP 400 Error - Bad Request (if not, create some more folders in folders and try again)

    I don't know specifically where the cutoff is but in testing (and from logic) my gut would say after 255 characters which is a typical limit (it's the PATH limit in Windows) and would make sense.

    So basically the rule here is to try to stay away from a folder taxonomy to organize information. META data and custom views in document libraries is so powerful as you can have everything living in one "folder" but viewed by category (or whatever makes sense for your organization). It's a hard shift from the file centric way of thinking but you can seed the troops with some tools to get them started, spend some time training them and showing them how a slice through their data is much more informative than the "where did I put that file" approach they currently use. It's a tough sell and you'll get a lot of resistance as people are comfortable with a structured file system to do their organizing for them. In the end there are a lot of benefits to viewing your information with a slightly different twist and you'll avoid problems like the one I described above (although your mileage may vary).

  • Creating a Tabbed Interface for your WSS site

    This was asked in the newsgroups about how to build a tabbed UI in a WSS site. Luckily, there's a great FrontPage component you can use for this that makes building it a breeze. First pick a site you want to add the interface to (or create a new one, doesn't matter). Next open up the default.aspx page in FrontPage 2003.

    Adding the Tabs

    The FrontPage component we want to use is the Interactive Button. Find a place on your page you want the tabs to appear. In this demo we'll put them under the site description. Once you have a place for it and the cursor positioned there, select Insert | Interactive Button from the menu. This will bring up a dialog box to describe the button. Pick a button that works with the design of your site. NOTE: the buttons don't follow the style of your WSS site so you should land on what theme you use up front before adding the tabs. Below I've picked "Soft Tab 6" which matches the default WSS site style pretty closely.

    On the Font and Image properties you can alter the button to your hearts content. Click OK to insert the button onto your page. You should now have something like this in FrontPage:

    Now select the button on the page and copy it then paste it next to each other as many times as you want a tab for (1 tab for each page). In the example below we're going to have 4 tabs going to 4 different pages.

    Each tab (interative button in FP terms) represents a different page in the site. So first save the default.aspx page 3 more times as Tab1.aspx, Tab2.aspx, and Tab3.aspx (or whatever names you want). The reason why we save default.aspx is because we want to preserve all of the parts of the page. We could have created 3 Web Part Pages to hold content, but we would lose the Quick Launch bar and other properties so this just keeps things more consistent. Also you can't copy'n'paste an ASPX page in the folder view so this works for us.

    Now load each page up by double clicking on it in the Folder List, select each button on each page and change the properties so that a) the Text property of the button is what you want it to be and b) the Link property points to the file you want the button to take you to. We'll call our tabs Home, Contacts, Tasks, and Documents. After creating the new pages with all the renamed buttons we should have something like this (4 tabs with 4 pages loaded up):

    The FrontPage work is done so save all the files and close FP down. Now go back to the site in your browser and select each tab. This will take you to each new page you created (you can check it in the Url). Now drag and drop whatever web parts onto that page that's appropriate for your design. When your users hit the site, they'll click on each tab which will take them to the new ASPX page which contains the new lists. Because we copied the default.aspx page as our original, all the great stuff like the Quick Launch bar is there (and will be updated on all pages when you add new lists) and the tab interface looks seamless! Here's our Task and Document pages showing this off:

    Additional things you can do if you want:

    • Change the style of the button for the page that's currently selected (so Home for default.aspx) so people know what tab/page they're on
    • Rather than making the content static, you can drop it onto a webpart and reuse it (haven't tried this but it should work)
    • Create your own style that will change with the style of the website (this involves editing the HTML of the link buttons to make them use the named CSS styles of the WSS site)
    • Create some more images as a border to display below the tabs to make them integrate to the site a little better
    • Change the title of each tab page (in FP2003)

    One note, the technique here of creating all new pages and saving it will end up creating a lot of duplicate buttons. You can take the extra time to go into the HTML code of the page and have the buttons point to the already existing button images rather than creating new ones each time the page is saved.

    Additional Links
    Microsoft Office Assistance - Using Interactive Buttons

  • Coming soon to a user group near you... me!

    I just got word that I'm now officially a member of the MSDN Canada Speakers Bureau. The Speakers Bureau is a collection of top Canadian speakers who are dedicated to delivering high quality presentation and demonstrations at MSDN events and at MSDN User Groups across Canada.

    I had been accepted into the group a few weeks ago, but the machinations of the internal workings at Microsoft have finally grinded to a halt and settled now. I'm very happy to be inducted into the group which includes some people I've enjoyed listening to and have looked up to like Ryan Storgaard, Kate Gregory, and my fellow Calgary MVPer John Bristowe. I look forward to participating in the group in the coming year (and what's left of 2004) and getting out to User Groups across Canada to spread the good word (whatever that word is).

    For more information on the Speakers Bureau, you can check out the link here. For a list of MSDN Canadian User Groups check out this link. Speaking of MSDN events, check out the Deep Dive on building connected systems. Each participant will get a free copy of the new Microsoft book, Enterprise Integrated Systems. Oh, come on now, you're all a flutter right? Check out the event link here for more info.

    Anyways, just wanted to toot my own horn here (although I need to get them to update my profile because when I wrote it, I didn't think it was going to be used verbatim on the site and it's a very "I'm this" and "I'm that" blather) so see you on the circuit!

  • Differences with SharePoint View Styles

    I was putting together a sampling of views to demonstrate the various view styles in SharePoint and came across a bit of a bug (well, an annoyance really). First just a quick rundown of the various styles you can apply in a view:

    View Style is the style you set by selecting it from a list when you create or edit a view. There are 7 styles to choose from, all with different twists to how they present your list or document library. The nice thing is you can get some variations on presenting things to the user without having to resort to a DVWP. Okay, I'll admit there's not a lot of styles out-of-the-box nor are they fabulous in any way. A little variety but definately not a replacement for a custom FrontPage job.

    So, without further adieu, here they are:

    Basic Table
    The Basic Table is pretty much like the Default style. See below for details on what's different but pretty much it renders your view in the typical SharePoint view. Columns with clickable (sortable) headers, etc.

    Document Details
    The Document Details style is probably the most adventurous of the bunch and renders your items 2 across (no matter how wide the page is) with each item in a box. A link to the item itself and whatever columns you enable for the view along with an icon for the item and an icon for editing it.

    Newsletter
    I couldn't quite figure out the Newsletter style at first but the only difference I found from the Basic Table or Default style is that regular text fields were bold. I still don't know why they called it Newsletter?

    Newsetter, no lines
    Same as the Newsletter style but guess what, the lines between each row have been removed. Otherwise identical.

    Shaded
    Shaded is like the Default style but every other row is shaded using the colour of the site, alternating between dark and light. Typical ledger type display and helps break up the monotony when you have a lot of items.

    Custom
    The Custom style is set when you change any of the other styles like doing grouping, totaling or even adding columns. I guess it's there to just indicate that it's not stock.

    Default
    The default is well, the default. When you create a new document library or list you get a view called All Documents (or All Items for lists). This view uses the default style.

    Now when you actually build a view and apply the Basic Table style you'll notice something. It looks exactly the same. Well it is, almost. The two are the same (ignoring the Guids for the views when compared side-by-side) however the Default style throws two copies of this snippet of code in:

    <SCRIPT LANGUAGE="VBSCRIPT">
        On Error Resume Next
         Set NewDocumentButton = CreateObject("SharePoint.OpenDocuments.2")
         If (IsObject(NewDocumentButton)) Then
             fNewDoc2 = true
         Else
             Set NewDocumentButton = CreateObject("SharePoint.OpenDocuments.1")
         End If
        fNewDoc = IsObject(NewDocumentButton)
    </SCRIPT>

    This VBScript is for rendering the correct button on a toolbar. The Default style puts the code in twice but the Basic Table only puts it in once. No biggie and it's not needed so I would classify it as a bug, but maybe I'm just difficult that way.

    Anyways, hope that explains some things about the views and what the differences (and similarities) are.

  • DataGrids, Custom columns and Paging

    I had a co-worker who presented a problem today. It was around adding paging to a datagrid (grrr Microsoft for making us do all the work!) and the fact that he had added what looked right, but the grid wasn't rendering on the page change. I went through the typical scenario of setting up paging by adding the Page Index Change event handler then, nothing. Something wasn't right and I surmised that the problem was that he had gone through a few iterations of getting the paging going and taking various approaches (hand coding the event handler, adding it to the web.config, etc.) so my conclusion was that the DataGrid, the code behind, and the aspx page were out of whack somehow. I wasn't happy suggesting the "black magic" approach to rebuilding the DataGrid with a duplicate one on the page (or creating it from scratch again) just because there had to be an easier solution.

    Tonight I built a small spike project to test out what was happening. A couple of people have experienced pain and suffering in the past with the DataGrid and how events would just vanish and not fire. One thing I noted in his code was that he had a DataGrid on the page but was then building columns on the fly (to do some custom work with the columns and linking them to subsequent pages). Once I had my spike project up and running, I turned off the auto-generated columns and fed it the datasource (a quick object with a few public properties). Everything was still fine. The problem arose when I added this:

    BoundColumn datagridcol = new BoundColumn();
    datagridcol.HeaderText = "ID";
    datagridcol.DataField = "Id";
    DataGrid1.Columns.Add(datagridcol);

    I've used this method before but usually when I created a DataGrid completely from scratch and added it to the page controls manually. In my spike project after adding this code, the DataGrid vanished completely. So the question here is this a supported design? Building columns on the fly with a DataGrid control already on the page? Or is this a hybrid that isn't supported (or recommended)? Another interesting thing to note. I now can't get to my event handlers in the Property tab in Visual Studio anymore. The lightning bolt just isn't there now. Hmmm.

    Update:
    I did find a bit of a solution. I added the following to the DataGrid in the aspx page to fix it:

    <Columns>
    <asp:BoundColumn Visible=False></asp:BoundColumn>
    </Columns>

    Now the paging works and everything shows up.

  • Using localhost for organizing your work

    I'm just wondering what people are doing to keep track of their work these days. Sure, Outlook has a good set of tools for this. Calendar, Task list, etc. but information is still disparate and I'm jumping all over the place each time I do something. Doing web development means that we have IIS (or Apache if that's your thing) at our disposal which can serve up your own local work center. With .NET installed, the possibilities are even more plentiful. So rather than having Yahoo or MSN set as my homepage I would use http://localhost and put my collection of links, tasks, documents and other useful tidbits there in some kind of organized fashion. Each time I fired up my browser I could track what I was doing or have a categorized view of resources that I use on a regular basis. I found it was somewhat more effective than using static IE bookmarks and saw it as a next generation PIM, as those have all but vanished from the desktop.

    I've grown a little dissatisfied with having a static webpage that I was constantly editing so I looked for an alternative. SharePoint, while having a good collection of features for this, was out becuase it meant I had to run it on my server and I wanted something local (and simpler). After poking around on the web, I thought the current version of DotNetNuke would be a good choice. It's been kicking around for quite sometime, was built on .NET (grown up from the IBuySpy Portal Starter Kit that Microsoft created to show people what was possible with .NET) and the latest version is pretty slick. Lots of free add-ons, private assemblies mean I just upload a zip file and it's available as a new module so no messing with compiling or messy configurations and I can make the content as dynamic as I want it to be. I've been using that for a few days now and it's pretty darn effective. I use it for tracking a list of ongoing projects and tasks, a large collection of categorized links, a document manager, a photo album and there's even an MP3 player,.all organized on tabs (with my main page calling up the Daily Dilbert as you just can't live without that). So it's been my central core for my day to day work.

    While I'm not an organization freak (my cluttered office is painful evidence of that) I'm just wondering if anyone else is using something like this and if so, what's their experiences been?

  • Writing SharePoint Web Parts, the painful adventure...

    Writing Web Parts for SharePoint is an adventure. The type of adventure that you find yourself in the middle of, realize that you don't have your fedora cap and whip, and the boulder starts rushing towards you and the spiders are crawling all over you with no exit in sight. Not a very pleasant experience for anyone.

    Luckily there are some saviors to this story. I've blogged about this before but after a weekend of writing custom web parts the painful way, I've basically given up on the Microsoft way for now and focused on using an alternative. Until VS 2005 comes along, where writing Web Parts is much easier, there is an interim solution. Fons Sonnemans and Jan Tielens got together and put together SmartPart. It's a great little addition to your SharePoint development toolbox and one everyone should have. Don't bother writing Web Parts and going through the 42 steps that Microsoft wants you to in order to get your web part created (although the Web Part Templates does make this easier). Just create a custom user control and drop it into a folder on your SharePoint server. SmartPart will happily render it for you, taking care of all the SharePoint stuff for you. The best part of this (besides not having to jump through hoops built Web Parts) is the fact that you can use the full UI design mode tools in Visual Studio to build your controls. No more RenderWebPart calls with hand building controls. Since your control is running on the SharePoint server, you can easily interface with the object model and do whatever you normally would do like accessing lists and sites and users oh my.

    Anyways, check out the GotDotNet workspace here and give it a whirl. Beats the heck out of the fugly way of doing it today.

  • Web Parts without SharePoint, ASP.NET 2.0

    I've been watching the classes in ASP.NET 2.0 for quite some time and working with the betas to see how we might build applications today so we're positioned for the changes next year (check out the Visual Studio 2005 Beta Documentation site here for all the gory details on the new classes). Something that intrigued me was the WebPart classes they introduced.

    Living in the SharePoint space, web parts are the staple at to how to get information out to the presentation layer. In SharePoint they're a little ugly to write, but none the less are effective because the end consumer of the web part can choose how to display it (based on preferences through SharePoint for that particular instance of the web part). This includes appearance, what options they want to display, where they want it on the web page, etc. All of this fits into a nice framework and even allows you to have multiple copies of the web part with them pointing at different views or data sources. One persons way of using a web part may be different then someone else, either by design or organization. For SharePoint, this was the innovation that allows us to build applications on that platform with little effort and target content to specific audiences.

    When I saw the WebPart classes introduced in the 2.0 framework I started salivating. Bringing the capabilities of web parts to regular ASP.NET apps meant that I could introduce things like personalization and customization to apps without having to have to do a lot of work. Web Parts are similar to web user controls but provide the functionality to allow users to customize the website by adding, deleting, and moving controls around the page based on WebPartZones. Any ASP.NET server control can act as a Web Part but by creating a custom control derived from the WebPart class you gain access to advanced features.

    You can check out the new MSDN paper on Web Parts here. Something to look forward to with your apps and something to keep in mind on how to design your apps today as these new capabilties roll into the framework and enable you to start leveraging more features with less code.

  • Virtual Web Part Development with SharePoint

    With all this talk about Virtual User Groups, I somehow got down this path and wanted to say that there is one and only one (IMHO) way to develop web parts for SharePoint (at least that's the conclusion I've come to). Virtual PC 2004 kicks for this. I was able to take the time to get a new Virtual image setup and decided to get a new SharePoint environment setup in it. With the recent update to Virtual PC, Microsoft has made it a little better (and faster) for this.

    The install of Windows 2003 Server was smooth and getting Windows SharePoint Services running was a breeze. Basically:

    • Create a new Virtual PC image through the wizard
    • Pop in a Windows 2003 Server CD (I'm using Enterprise edition but whatever works for you)
    • Run the install (takes about an hour on a 2Ghz machine with 2GB of memory). You don't need a domain so just create a workgroup for it.
    • Once the install is done, make it a web server through the Manage Your Server setup screen
    • Download Windows SharePoint Services from here and run the setup (10 minutes)
    • Set your IIS to allow anonymous on the Default Web Site and set SharePoint to allow anonymous users by default as Readers
    • Install Visual Studio .NET and optionally MSDN (another hour)

    That's about it and Bob's your uncle. I only had to give it 400MB of memory in the settings and it runs well for running, administration, and debugging. The nice thing is that my local machine sees it (even though it's on a different workgroup than my box) and I can ping it and surf to it by name. Makes for great testing and developing because I can come in as a regular user and since it's running in Workgroup mode there's a Sign In button so I can become whoever I want for testing (Contributor, Admin or a user in a custom group). Much easier than when you're running on a domain with integrated authentication and you pretty much have God access to everything. I also don't have to worry about domains and that whole mess. Note that this setup is for WSS, SPS does require a domain to operate on but you can develop web parts on this environment and use them on SharePoint, you just can't use the SharePoint features like search, etc.

    Try it out if you've got the resources as it makes for a nice easy development setup. Debugging web parts has to be done on the server but that's what the install of Visual Studio is for and the speed is quite acceptable. Also there's a good site here on what OSes work (and what don't) under Virtual PC if you're looking on setting up different configurations (I have a Debian setup as well for some Linux development, nothing like a disposable machine!)

  • I love the UI, I love the UI, I love...

    Well, no. It's all great that you have a nice Domain Object. Grant you, it's now populated with an ugly Id attribute which it slugs around because someone, somewhere decided that it was important enough to save the information into a database and databases need a primary key to find stuff. The problem is when I have to show a list to pick from, one of which is what the user selected previously. My Domain Object has this attribute:

    Name: Author; Value: 21

    And there's a collection of Roles to pick from:

    Name: Reader; Id: 10
    Name: Author; Id: 21
    Name: Administrator; Id: 321

    So I have a simple LookupDTO I use in my UI and Service Layer that looks like this:

    class LookupDTO
    {
      string Name;
      int Id;
    }

    It's generic (all lookups follow the same pattern). Problem is that if you have a collection of Roles you can't just bind it to a DropDownList like this:

    // this returns an array of LookupDTO objects from the service layer
    uiName.DataSource = RoleService.FindListForProject(projectId);
    uiName.DataTextField = "Name";
    uiName.DataValueField = "Id";
    uiName.DataBind();

    Because the values are 10, 21, and 321 and you can't set uiName.SelectedIndex = 21 or else ASP.NET blows it's head up with a boundary problem (it's 0-based). Ugly. I hate the fact that my Domain Object says that it's Id is 21 (because that's the database id that was created when it got saved) but ASP.NET needs a 0 or 1 to let a user pick from. So do I need a mapper for my mapper? And then there's going back that you have to do another mapping. So maybe there's a UI component that has both the "real" value and the UI value? I don't know.

    I'm almost thinking that I should use a Guid in the database, but autoincrement is so nice and easy. A Guid would have it's advantage (other than driving my dba nuts) because I can pregenerate it in my Domain when a real object is created so I don't have to do fancy stuff in my SQL to get the ID that was just created. A common problem with using autoincrement in SQL is that you don't get it before the INSERT call. It's unique. I still think I'll have a problem in my UI layer because setting the HTML for a selected item in a dropdown list doesn't like "A04759E3-509C-42c6-BE27-20562B2BA6CA" as a selected value.

    I know there's a better solution out there to map "real" values to ASP.NET UI controls like dropdown lists that don't like indices that don't match the 0 based counting that HTML creates. There's a good blog by Steve Eichert here on Hooking your Domain Model to the UI. I think we need a good UI Mapper tool/pattern/something to make this a no-brainer.

    There's also a very nice add-in from Manuel Abadia over at CodeProject. It provides two way data binding in ASP.NET and looks pretty simple. You just hook up your collection to the fields on your webpage (through a designer) to set the databindings to your DTOs and call BindToWebForm (or BindFromWebForm). It turns this:

    // populate the webform with the customer data
    lName.Text = cus.Name;
    lSurname.Text = cus.Surname;
    lEmail.Text = cus.Email;
    lAddress.Text = cus.Address;
    lAge.Text = cus.Age.ToString();

    // get the customer data from the webform
    cus.Name = lName.Text;
    cus.Surname = lSurname.Text;
    cus.Email = lEmail.Text;
    cus.Address = lAddress.Text;
    cus.Age = Int32.Parse(lAge.Text);

    Into this:

    // populate the webform with the customer data
    bindingManager1.BindToWebForm(this);

    // get the customer data from the webform
    bindingManager1.BindFromWebForm(this);

    You can check out here. I need to find some time to look at it because this is nuts (or else I'm so out of it I'm missing the obvious). Maybe I haven't had enough coffee to think correctly. Friends don't let friends blog drunk (or semi-awake) might be a more appropriate title for this entry.