Hilton Giesenow's Jumbled Mind

Hilton Giesenow's Jumbled Mind

the madness that is...

News

This is my little spot in cyberspace where you will find a collection of random (but mostly software-related) thoughts and ideas that are frightening in their shining brilliance (or something like that ;->).
 
Please enjoy your stay and feel free to Contact Me.
 
Microsoft MVP

.Net Links

BlogRoll

Misc. Links

Syndication

The MOSS Show – Episode 4

After a loooong delay, I finally managed to finish editing episode 4 of The MOSS Show. In this episode, I interview our very own Zlatan Dzinic on Records Management in MOSS. It was an interesting editing job – we had some “technical” difficulties, so I had to basically rebuild Zlatan’s side of the conversation word by word, in a hour-long recording!!

Why So Quiet – The MOSS Show – a SharePoint Podcast

So amongst other things (like DevDays, computer crashes, crazy clients and the SharePoint and MOSS How Do I videos on Tech Net), I’ve been working on another side project for a couple of months, and I’ve finally launched it. For all those working with, or interested in SharePoint or Microsoft Office SharePoint Server (MOSS), check out my all-new, all-shiny, SharePoint podcast - The MOSS Show.

There’s still a lot of work to be done, both on improving the podcast, the site, the editing, and so forth, but I’m excited to finally have it launched (it’s been incubating for a looong time). If you’ve got any suggestions, please send them in. Also, if you’ve got topic or speaker requests/suggestions or ideas for the show in general, please also let me know.

- H

Talk on Continuous Integration

Last Wednesday I gave a talk at the local Scrum user group on Continuous Integration. Being that much of the audience was non-developer, I tried to keep it as conceptual as possible, but we even went through some code, both C# and XML, very tentatively. The talk covered SVN, Tortoise, MSTest and CruiseControl.net.

For those who were there, I hope it was worthwhile. I had a great time meeting the user group members. For some details on the talk contents, visit the user group’s site. Go here for my continuous integration slides.

Server Quest II

A while back, Microsoft release "Server Quest", a very cute, 80's-style adventure game. You can check it out at http://www.server-quest.com/. For those who're keen to try the next run in these Silverlight in-browser adventures, Server Quest II has just come out.

If you want to take it a step further and write your own, then spin over to the competition page.

On a side not, if you just feel like playing retro Commodore 64 games, Scott Hanselman has an interview with a guy who created a Silverlight 3.0 emulator.

Fixing SharePoint Error: This form was customized not working with attachement.

I've been working with creating a custom list Feature in a MOSS project recently, and today I hit an error when creating a custom edit page for a content type. I'm trying to override the default new, edit and display pages for a specific content type, and all has gone fine till now, but today I noticed that the Attachments button was not working, and that it was giving the following error - "This form was customized not working with attachement." One of the most interesting solutions I found via Google was to this hotfix, but it is unsupported and also seemed to focus more on SharePoint Designer, so I carried on my search...

Eventually, I stumbled upon a blog post where the author had gone searching through the form.js JavaScript file to locate the error, and it helped me resolve the issue finally with just a touch of hacking around in SharePoint :->.

The form.js file contains the following:

function ShowPartAttachment()
{
 if (document.getElementById("part1")==null ||
  typeof(document.getElementById("part1"))=="undefined")
 {
  var L_FormMissingPart1_Text=   "This form was customized not working with attachement.";
  alert(L_FormMissingPart1_Text);
  return;
...

so, what the above reveals is that the JavaScript was expecting an element called "part1" somewhere on the page. This lead me to go searching in the DefaultTemplates.ascx file (in C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\TEMPLATE\CONTROLTEMPLATES), where I found the following:

<SharePoint:RenderingTemplate ID="UserListForm" runat="server">
    <Template>
        <SPAN id='part1'>
            <wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbltop" RightButtonSeparator="&nbsp;" runat="server">
                    <Template_RightButtons>
                        <SharePoint:SaveButton  runat="server"/>
                        <SharePoint:GoBackButton runat="server"/>
                    </Template_RightButtons>
            </wssuc:ToolBar>
            <SharePoint:UserInfoListFormToolBar runat="server"/>
            <TABLE class="ms-formtable" style="margin-top: 8px;" border=0 cellpadding=0 cellspacing=0 width=100%>
            <TR><SharePoint:CompositeField FieldName="Name" ControlMode="Display" runat="server"/></TR>
            <SharePoint:ListFieldIterator runat="server"/>
            <SharePoint:FormComponent TemplateName="AttachmentRows" runat="server"/>
            </TABLE>
            <table cellpadding=0 cellspacing=0 width=100%><tr><td class="ms-formline"><IMG SRC="/_layouts/images/blank.gif" width=1 height=1 alt=""></td></tr></table>
            <TABLE cellpadding=0 cellspacing=0 width=100% style="padding-top: 7px"><tr><td width=100%>
            <SharePoint:ItemHiddenVersion runat="server"/>
            <wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbl" RightButtonSeparator="&nbsp;" runat="server">
                    <Template_Buttons>
                        <SharePoint:CreatedModifiedInfo runat="server"/>
                    </Template_Buttons>
                    <Template_RightButtons>
                        <SharePoint:SaveButton  runat="server"/>
                        <SharePoint:GoBackButton runat="server"/>
                    </Template_RightButtons>
            </wssuc:ToolBar>
            </td></tr></TABLE>
        </SPAN>
        <SharePoint:AttachmentUpload runat="server"/>
    </Template>
</SharePoint:RenderingTemplate>    

You can see right at the top of the template, the main controls for the page are contained within a Span tag with an id of ... 'part1'. Well, here's what my template looked like to begin with:

<SharePoint:RenderingTemplate ID="MyCustomTemplate" runat="server">
    <Template>
        <table cellpadding="0" cellspacing="0" id="onetIDListForm">
            <tr>
                <td>
                    <table border="0" width="100%">
                        <tr>
                            <td class="ms-toolbar" nowrap="">
                                <SharePoint:FormToolBar ID="FormToolBar2" runat="server" />
                            </td>
                        </tr>
                        <tr>
                            <td>
                                <table class="ms-formtable" border="0" cellpadding="2">
                                    <SharePoint:ListFieldIterator ID="ListFieldIterator1" runat="server" />
                                </table>
                                <SharePoint:RequiredFieldMessage ID="RequiredFieldMessage1" runat="server" />
                        
                            </td>
                            <tr>
                                <td class="ms-toolbar" nowrap="">
                                    <table>
                                        <tr>
                                            <td class="ms-descriptiontext" nowrap="">
                                                <SharePoint:CreatedModifiedInfo ID="CreatedModifiedInfo1" runat="server" />
                                            </td>
                                            <td width="99%" class="ms-toolbar" nowrap="">
                                                <img src="/_layouts/images/blank.gif" width="1" height="18" />
                                            </td>
                                            <td class="ms-toolbar" nowrap="">
                                                <SharePoint:SaveButton runat="server" ID="savebutton2" Text="Manage Tasks" />
                                            </td>
                                            <td class="ms-separator">
                                            </td>
                                            <td class="ms-toolbar" nowrap="" align="right">
                                                <SharePoint:GoBackButton runat="server" ID="gobackbutton2" />
                                            </td>
                                        </tr>
                                    </table>
                                </td>
                            </tr>
                        </tr>
                    </table>
                    <img src="/_layouts/images/blank.gif" width="590" height="1" alt="">
                </td>
            </tr>
        </table>
    </Template>
</SharePoint:RenderingTemplate>

So to start off, I wrapped my template in the same Span, to see what would happen:

<SharePoint:RenderingTemplate ID="MyCustomTemplate" runat="server">
    <Template>
    <SPAN id='SPAN1'>
        <table cellpadding="0" cellspacing="0" id="Table1">
            ...
        </table>
        </SPAN>
    </Template>
</SharePoint:RenderingTemplate>

But, when I did this, I still hit an error, just further down in the same piece of JS:

 

function ShowPartAttachment()
{
    if (document.getElementById("part1")==null ||
        typeof(document.getElementById("part1"))=="undefined")
    {
        var L_FormMissingPart1_Text= "This form was customized not working with attachement.";
        alert(L_FormMissingPart1_Text);
        return;
    }
    document.getElementById("part1").style.display="none";
    document.getElementById("partAttachment").style.display="block";
    GetAttachElement(FileuploadString+FileUploadIndex).focus();
}

this time on the line in the code above referring to "partAttachment". Off we go again into DefaultTemplates.ascx, where we find:

<SharePoint:RenderingTemplate ID="AttachmentUpload" runat="server">
    <Template>
        <INPUT type=hidden name='attachmentsToBeRemovedFromServer'>
        <INPUT type=hidden name='RectGifUrl' value="/_layouts/images/rect.gif">
        <SPAN id='partAttachment' style='display:none'>
        <TABLE cellSpacing=0 cellPadding=0 border=0 width="100%">
        <TBODY>
        <TR>
            <TD class=ms-descriptiontext style="padding-bottom: 8px;" colSpan=4 vAlign=top>
            <SharePoint:EncodedLiteral runat="server" text="<%$Resources:wss,form_attachments_description%>" EncodeMethod='HtmlEncode'/>
            </TD>
        </TR>
        <TR>
        <TD width=190px class=ms-formlabel vAlign=top height=50px><SharePoint:EncodedLiteral runat="server" text="<%$Resources:wss,form_attachments_name%>" EncodeMethod='HtmlEncode'/></TD>
        <TD width=400px class=ms-formbody vAlign=bottom height=15 id=attachmentsOnClient>
            <SPAN dir="ltr">
             <INPUT type=file name=fileupload0 id=onetidIOFile class="ms-fileinput" size=56 title="Name"></INPUT>
            </SPAN>
        </TD>
        </TR>
        <TR>
            <TD class=ms-formline colSpan=4 height=1><IMG SRC="/_layouts/images/blank.gif" width=1 height=1 alt=""></TD>
        </TR>
        <TR>
            <TD colSpan=4 height=10><IMG SRC="/_layouts/images/blank.gif" width=1 height=1 alt=""></TD>
        </TR>
        <TR>
        <TD class="ms-attachUploadButtons" colSpan=4>
            <INPUT class="ms-ButtonHeightWidth" id=attachOKbutton type=BUTTON onclick='OkAttach()' value="OK">
            <span ID="idSpace" class=ms-SpaceBetButtons></span>
            <INPUT t class="ms-ButtonHeightWidth" id=attachCancelButton type=BUTTON onclick='CancelAttach()' value="Cancel">
        </TD>
        </TR>
        <TR>
        <TD colSpan=4 height=60>&nbsp;
        </TD>
        <TD>&nbsp;
        </TD>
        </TR>
        </TBODY>
        </TABLE>
        <script>
            if (document.getElementById("onetidIOFile") != null)
                document.getElementById("onetidIOFile").title = "<SharePoint:EncodedLiteral runat='server' text='<%$Resources:wss,form_attachments_name%>' EncodeMethod='EcmaScriptStringLiteralEncode'/>";
            if (document.getElementById("attachOKbutton") != null)
                document.getElementById("attachOKbutton").value = "<SharePoint:EncodedLiteral runat='server' text='<%$Resources:wss,form_ok%>' EncodeMethod='EcmaScriptStringLiteralEncode'/>";
            if (document.getElementById("attachCancelButton") != null)
                document.getElementById("attachCancelButton").value = "<SharePoint:EncodedLiteral runat='server' text='<%$Resources:wss,form_cancel%>' EncodeMethod='EcmaScriptStringLiteralEncode'/>";
        </script>
        </SPAN>
    </Template>
</SharePoint:RenderingTemplate>

So it looks like we need to make use of the AttachmentUpload control in our template. Also, if we look at what the JavaScript is doing, it's hiding the one element and showing the other, so clearly the AttachmentUpload control needs to be outside our Span. With this in mind, I tried the following:

<sharepoint:renderingtemplate id="MyCustomTemplate" runat="server">
    <Template>
        <SPAN id='SPAN1'>
            <table cellpadding="0" cellspacing="0" id="Table1">
                ...
            </table>
        </SPAN>
        <SharePoint:AttachmentUpload ID="AttachmentUpload1" runat="server" />
    </Template>
</sharepoint:renderingtemplate>

If you've followed all this way, don't worry, we're getting close...

With all of the above in place, I was now getting an error on the line below referring to idAttachmentsTable:

function OkAttach()
{
    fileID=FileuploadString+FileUploadIndex;
    fileInput=GetAttachElement(fileID);
    filename=TrimWhiteSpaces(fileInput.value);
    if (!filename)
    {
        var L_FileNameRequired_TXT="You must specify a non-blank value for File Name.";
        alert(L_FileNameRequired_TXT);
        fileInput.focus();
    }
    else
    {
        var L_FileUploadToolTip_text="Name";
        oRow=document.getElementById("idAttachmentsTable").insertRow(-1);
        RowID='attachRow'+FileUploadIndex;
        oRow.id=RowID;

back for the last time in DefaultTemplates.ascx, I found:

<SharePoint:RenderingTemplate ID="AttachmentsField" runat="server">
    <Template>
        <TABLE border=0 cellpadding=0 cellspacing=0 id=idAttachmentsTable>
            <asp:Literal ID="AttachmentsList" runat="server"/>
        </TABLE>
    </Template>
</SharePoint:RenderingTemplate>

but I also spotted:

<SharePoint:RenderingTemplate ID="AttachmentRows" runat="server">
    <Template>
        <TR id=idAttachmentsRow>
        <TD nowrap="true" valign="top" class="ms-formlabel" width="20%">
        <SharePoint:FieldLabel FieldName="Attachments" runat="server"/>
        </TD>
        <TD valign="top" class="ms-formbody" width="80%">
            <SharePoint:AttachmentsField FieldName="Attachments" runat="server"/>
            <SCRIPT>
            var elm = document.getElementById("idAttachmentsTable");
            if (elm == null || elm.rows.length == 0)
                document.getElementById("idAttachmentsRow").style.display='none';
            </SCRIPT>
        </TD></TR>
    </Template>
</SharePoint:RenderingTemplate>

so I did another search on "AttachmentRows" and came right back to the UserListForm we had near the beginning (and which also has the AttachmentUpload control at the bottom, and outside of the Span, but which I've not shown below for brevity -see earlier for the full template):

<SharePoint:RenderingTemplate ID="UserListForm" runat="server">
    <Template>
        <SPAN id='SPAN2'>
            ...
            <SharePoint:ListFieldIterator runat="server"/>
            <SharePoint:FormComponent TemplateName="AttachmentRows" runat="server"/>

so I added the FormComponent into my control template, and uploads are now working fine. The full template now looks like this:

<%@ Control Language="C#" %>
<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="SharePoint" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
    Namespace="Microsoft.SharePoint.WebControls" %>
    
<SharePoint:RenderingTemplate ID="MyCustomTemplate" runat="server">
    <Template>
        <span id='Span3'>
            <table cellpadding="0" cellspacing="0" id="Table2">
                <tr>
                    <td>
                        <table border="0" width="100%">
                            <tr>
                                <td class="ms-toolbar" nowrap="">
                                    <SharePoint:FormToolBar ID="FormToolBar2" runat="server" />
                                </td>
                            </tr>
                            <tr>
                                <td>
                                    <table class="ms-formtable" border="0" cellpadding="2">
                                        <SharePoint:ListFieldIterator ID="ListFieldIterator1" runat="server" />
                                        <SharePoint:FormComponent ID="FormComponent1" TemplateName="AttachmentRows" runat="server" />
                                    </table>
                                    <SharePoint:RequiredFieldMessage ID="RequiredFieldMessage1" runat="server" />
                                </td>
                                <tr>
                                    <td class="ms-toolbar" nowrap="">
                                        <table>
                                            <tr>
                                                <td class="ms-descriptiontext" nowrap="">
                                                    <SharePoint:CreatedModifiedInfo ID="CreatedModifiedInfo1" runat="server" />
                                                </td>
                                                <td width="99%" class="ms-toolbar" nowrap="">
                                                    <img src="/_layouts/images/blank.gif" width="1" height="18" />
                                                </td>
                                                <td class="ms-toolbar" nowrap="">
                                                    <SharePoint:SaveButton runat="server" ID="savebutton2" Text="Manage Tasks" />
                                                </td>
                                                <td class="ms-separator">
                                                </td>
                                                <td class="ms-toolbar" nowrap="" align="right">
                                                    <SharePoint:GoBackButton runat="server" ID="gobackbutton2" />
                                                </td>
                                            </tr>
                                        </table>
                                    </td>
                                </tr>
                            </tr>
                        </table>
                        <img src="/_layouts/images/blank.gif" width="590" height="1" alt="">
                    </td>
                </tr>
            </table>
        </span>
        <SharePoint:AttachmentUpload ID="AttachmentUpload1" runat="server" />
    </Template>
</SharePoint:RenderingTemplate>

and the attachment fields works perfectly.  Hopefully this will help someone with the same problem.

- H

QueryString Decomposing Tool

I was doing a bunch of work with querystring variables a little while ago, so I spun up a small little Windows app that breaks a url into the address and querystrings, and then breaks these querystrings down variable by variable as well. You can pick it up here at CodePlex.

Here is a screenshot:

QueryString Decomposer 1

You can also add it into Visual Studio as an external tool (which you can do with pretty much any .exe, in fact).

QueryString Decomposer 2

I also command-line enabled it and set it Visual Studio to pass the selected text to the app so that you can select any text in the IDE, then launch it off the Tools menu (or set a keyboard shortcut) and have it pre-loaded with the passed in query string. To do this, go to External Tools:

QueryString Decomposer 3

Then add your .exe with a title (including shortcut key if you want) and set Arguments using the arrow alongside to some of the available variables (in this case $CurText, which is Current Text).

QueryString Decomposer 4

Visual Studio 2010 CTP

Lennie De Villiers has downloaded the full CTP and is able to offer to anyone who wants it. He'll be away for a couple weeks working in Uganda, it seems, but if you want it contact him or me from about mid -Jan (when I'll hopefully be getting a copy from him).

Thanks Lennie!

Scott Hanselman - Been and Gone

For those who missed all our advertising (including my post about the event), yesterday we had the one and only Scott Hanselman come and talk to us. Scott gave an absolutely awesome (and very candid) presentation about ASP.Net MVC and some of its related aspects. The talk was very well received, so Scott a big thanks again for taking time out of your holiday vacation to come visit us.

Incidentally, I tried to record the event with my little webcam. The video came out ok, but the sound is pretty unusable. Anyone very good at sound editing want to give it a go?

By the way, a huge thank you to BSG for so kindly sponsoring Scott's flights and some of the other expenses.

P.S. If you have no idea who Scott Hanselman is, you're probably not too involved in day to day software development. He's got excellent blog posts on just about everything.

Windows SharePoint Services (WSS) How Do I: Create a New Site Column?

In this video, I discuss how to create a Site Column, which is a pre-defined column definition that can then be re-used across multiple different lists in the entire Site Collection.

Windows SharePoint Services (WSS) How Do I: Configuring Forms Based Authentication Without IIS 7

I posted a little while ago a link to my video on configuring Forms Authentication (FBA) in WSS using the new admin interface that is now part of IIS 7 and wraps a lot of the config settings and the management tools for using things like Roles and Members (Users) in an ASP.Net application, in this case a WSS site.

For those without IIS 7 (basically those with Windows Server 2003, I guess ;->) this video shows how to configure Forms Authentication in WSS using the Admin Website that ships with the free Visual Web Developer Express IDE from Microsoft (and can also of course be done with the full Visual Studio product).

S.A. Developer.net December Event - The One and Only Hanselman!

That's right, we're very fortunate to have the one and only Scott Hanselman joining us for an extra-special last event of the year! This is definitely one event not to be missed! Please RSVP if you are coming so we can plan the room, etc.

N.B. Because of Scott's plans, this will be a daytime event (see the time below).

Where and When

Topic: Building a Real Website with ASP.NET MVC: Suffering the Pain and Joy
Date: 17 December 2008
Time: 13:00 (sharp!)

Microsoft Cape Town Offices
Golf Park 3
Engen House
Raapenberg Road
Mowbray
7925

RSVP on this post

Windows SharePoint Services (WSS) How Do I: Configuring Anti Virus In Windows SharePoint Services (Using ForeFront)

In this video I have a look into the anti virus settings in Windows SharePoint Services 3.0, using Forefront Security for SharePoint, Microsoft's anti virus protection product. Here's a screenshot:

Configuring Anti Virus (With ForeFront) (Time 0_05_53;03)

Windows SharePoint Services (WSS) How Do I: Configuring Forms Based Authentication Using IIS 7

I was putting together a How Do I video on configuring Forms-Based Authentication (FBA). However, whereas a lot of the steps were previously far more manual, sometimes even requiring development work, with IIS 7, a large portion of the work can be done directly in the IIS Admin Console (including adding users, roles, etc.). As a result, I've broken the topic into 2 similar but separate videos. The first is at How Do I: Enable Forms-Based Authentication for a Windows SharePoint Services Site Collection (Using IIS 7)

HDI.WSS.FormsAuthenticationWithIIS7

Windows SharePoint Services (WSS) How Do I: Creating Web Applications & Site Collections

In this video, we look at how to create a new web application and site collection from within the Central Administration web site. The video also covers creating sub site collections within a root site collection, as you can see below:

HDI.WSS.CreateApplicationAndSiteCollection

Windows SharePoint Services (WSS) How Do I: Working With Managed Paths

Managed Paths in Windows SharePoint Services allow you to control the paths for your site collections within a web application. You can see more about it at Making Use of Managed Paths To Control Site Collection URLs.

HDI.WSS.UsingManagedPaths

More Posts Next page »