Ben Walters InfoPath MVP

Made it to Seattle

Today I arrived in Seattle for the MVP summit, the trip was a little more exhausting that I would have liked as I didn't get any sleep on the flight from Melbourne to LA, then my connecting flight from LA to Seattle was delayed about 1 hour as we waited for a fuel truck to show up and refill our plane. All up I think I've been up for about 26 hours, but to sit in my hotel with this view it's almost worth it.

IMAGE_041

Tomorrow it's off to the first day of the summit which should be great, not to mention Seattle has turned on it's best rainy weather for this week so I'll get to experience some winter weather (you know real winter weather not like that mixed up season Melbourne gets :o)

SharePoint Server 2007 Anonymous Access Gotcha!

Today for the first time I was attempting to create a SharePoint site with Anonymous Access. As I usually do when attempting to trying something new I fired up my MOSSDEMO image and promptly created a new web application. However after following all the steps to the letter in Inside Microsoft Office SharePoint Server 2007 book I was still being prompted for windows credentials when I attempted to access the site.

After attempting the set up 2 or 3 times it dawned on me, "I was using windows authentication to access the WSS_Content database" so when I hit my site SharePoint was passing through the authorisation request hence resulting in a prompt for windows credentials.

After creating a SharePointSvc account on my SQL server and setting up yet another web application my Anonymous access was up and running. Now to get forms authentication going!

 

image

 

[Update:]

 

Ok so put some egg on my face turns out my issue had noting to do with using a SQL account my problem was that my Network Service account didn't have access to my WSS Content database, added the service account to my SQL server and Bob's my uncle everything worked a treat.

Baby is ahead of schedule

Yesterday we went for the 12 week scan of our little bundle of joy, happy to say everything looks on track. The best thing is that originally we were due around 11th of October but turns out the first scan wasn't as accurate so we've gained a week.

image

 

image

My Xbox is back online

Since moving house a week or so ago I've been faced with a dilemma  do I connect my Xbox to the Internet via wireless or do I attempt to run a pretty blue cable around the perimeter of the room and hard wire into the router located in my study. Well after some deliberation (and approval from the wife) I decided to get an Xbox 360 wireless adapter. Only problem was once I got home I found I couldn't connect to my router, after an hours worth of "please hold Mr Walters while I check my resources" from customer support I decided to ping out for some help from my fellow MVP's. Luckily Phil Webster came to my rescue, turns out that my Linksys WAG325N will only allow my Xbox 360 Wireless adapter to connect if the router is running the original firmware version of 1.006 (keeping in mind that the current firmware revision is 1.012) so after a quick downgrade of my firmware version I'm now back online!

Just waiting now for Linksys to fix their firmware issues

Posted: Mar 26 2008, 01:40 PM by Ben Walters | with 2 comment(s)
Filed under:
Mario Invading Melbourne

While driving back to the office the other day I snapped everyone's favourite plumber Mario stopping traffic. Seems he's in town for the Game On exhibit at Federation square Which details game development from 1962 through to today, 

while I haven't had a chance to check it out yet I'm planning to head down there in the next couple of weeks. I'll be sure to post some more pics once I have them

 

image

Posted: Mar 18 2008, 01:39 PM by Ben Walters | with 1 comment(s)
Filed under:
Web Service Studio

Ok so I know that this utility is nothing new but this is something I've found very useful especially when developing with the SharePoint web services. It basically allows you to make calls to a web service and see the returned results (simple I know but very useful)

So why blog about it now? well it used to be when I was out on client site and needed to test a web service I would head over to GotDotNet and pull down the latest copy. Since GDN moved to MSDN I've found this tool near on impossible to track down. So I thought I'll put it up somewhere where I can reliably access rather than wasting time trawling search engines. Also this will hopefully make it a bit easier for others to find enjoy.

Windows 2008 SP1?

As you may have seen in my last post my Xbox is on the fritz so I thought I would setup a Window 2008 image and see if the performance gains for SharePoint that everyone keeps talking about really exist.

Anyway after finishing the setup I noticed something strange in the system properties

image

 

Still don't spot it?

image

Apparently the windows team have found a way of addressing the SP1 mentality that exists with server admins everywhere. Include it in the initial product ?!?

Why do early adopters get screwed over all the time?

Ok so before you read this you should know that I'm one of the biggest advocates of Microsoft technology. I'm always the first to jump into a verbal bout over the Xbox 360 to Playstation 3 debate but at the moment my commitment is feeling a little shaky.

You see today marks the 3rd time my Xbox 360 has RROD'd on me. So while I would usually be sitting down making my way through Lost Odyssey I've had some time to think.

See I was at the front of the line 2 years ago at my local EB games when XBox 360 was launched in Australia and was home within 10 minutes setting up my new console like an excited boy on Christmas morning.

Of course after I had come back down to earth and made it back to work I was quick to promote Microsoft's new console to anyone that asked (and everyone that didn't) so essentially I become one of Microsoft's greatest marketing resources a word of mouth that wouldn't shut up.

This all went along fine and then MS announced the Xbox 360 Elite, little more expensive but included a 120 GB HDD and HDMI port. I could live with that as MS provided me the ability to pick up a 120GB drive anyway and as for the HDMI port well I couldn't use it at the time anyway so it didn't bother me too much.

Then MS started fitting HDMI ports on all consoles and to rub salt into the wound  tacks on  a price drop. Now I have no problem with the price drop that's something that's bound to happen sooner or latter.

The HDMI port however means that any one of my friends who goes and buy's an Xbox today will get more value for money and a better built console than someone who supported the console when it was first released. This wouldn't bother me so much if MS offered some type of upgrade program e.g. trade in your old console with $50 and we'll give you the new one or some way to get the new features fitted to the old console.

However MS didn't offer any such upgrade offer and here I'm stuck with a console that for the 3rd time in 3 years has died on me and the best MS have to offer is a repair job after repair job to tide me over until my Xbox is out of the extended RROD warranty period and they try and sting me $130 each time the console dies.

So to close I put one warning out there Microsoft, be wary of breeding a SP1 mentality amongst your gaming community the first couple of months of a new console release are key to it's success or failure. As it stands come the next round of console releases I will be asking myself "Should I buy now or should I wait a couple of months until they get it right?"

Posted: Mar 10 2008, 05:09 PM by Ben Walters | with no comments
Filed under: ,
MOSSIG follow up SharePoint installer project from Codeplex

Hey everyone as promised here is the link to the SharePoint web Part project template for Visual Studio 2008 that I showed last night.

Also don't forget Will mentioned that a full VSE for Visual Studio 2008 is due out in the next couple of months. I'll do my best to put up link to this as soon as I know more.

 

Finally a big thanks to all who attended and presented last night, and don't forget to checkout MOSSIG.Net for all details on upcoming presentations and news.

Technorati Tags: ,,,
Filtered Drop Down Lists 101 Part 2

Now for the long awaited second half of my post on working with Filtered Drop down lists.

In my first post I showed you how to created filtered drop down lists using the InfoPath rich client. In this post I will show you how to achieve the same functionality in a web based form.

The biggest draw back about creating this functionality in a web based form is that filtered fields are not supported in web based forms. So we need to create another means to filter our data, an external data source like a web service for example provides us with this ability as all the filtering can be done using code and then returned to the InfoPath form via a data connection.

In my last post I used a set of data based around car manufactures and models. I'll use the same data for this example. This doesn't mean that only an XML file can be used to source this data there is no reason why you couldn't use SQL or another database as a data store to source your data.

For this post I'm going to create a reasonably basic web service that contains 3 web methods. The first will return a list of car manufactures, the second will return a list of car models for the supplied manufacturer, and the third method will return a list of available colours for the selected Manufacturer/Model combination.

Method 1

/// <summary>
    /// This method returns a list of car manufacturers
    /// </summary>
    /// <returns></returns>
    [WebMethod]
    public string[] GetCarManufacurer() 
    {
        //Create an xml document to hold the list of cars
        XmlDocument carList = new XmlDocument();
        
        //Load the car list into the XmlDocumentObject
        carList.Load("http://localhost/FilteredDropdown/Reference%20Files/Cars.xml");

        //Create xmlNode list to hold a list of the manufacturers
        XmlNodeList carMakers = carList.SelectNodes("//Cars/Car");

        //create a string array to retun a list of car manufacturers
        string[] returnString = null;

        if(carMakers.Count >0 && carMakers != null)
        {
            returnString = new string[carMakers.Count];

            //Create a counter interger to track where we are in the colleciton
            int counter = 0;

            //Take each car node in the collection and add the Make child node to the string array
            foreach (XmlNode car in carMakers)
            {
                returnString[counter] = car.SelectSingleNode("Make").InnerText;
                counter ++;
            }
        }

        //return the string array
        return returnString;
    }

Method 2

 /// <summary>
    /// This method will return a list of Car Models for the provided Make or manufacturer
    /// </summary>
    /// <param name="Make"></param>
    /// <returns></returns>
    [WebMethod]
    public string[] GetModelList(string Make)
    {
        //Create an xml document to hold the list of cars
        XmlDocument carList = new XmlDocument();

        //Load the car list into the XmlDocumentObject
        carList.Load("http://localhost/FilteredDropdown/Reference%20Files/Cars.xml");

        //Create xmlNode list to hold a list of the models for the supplied manufacturer
        XmlNodeList carModels = carList.SelectNodes("//Cars/Car[Make=\"" + Make + "\"]");

        //create a string array to retun a list of car manufacturers
        string[] returnString = null;

        if (carModels.Count > 0 && carModels != null)
        {
            returnString = new string[carModels.Count];

            //Create a counter interger to track where we are in the colleciton
            int counter = 0;

            //Take each car node in the collection and add the Make child node to the string array
            foreach (XmlNode car in carModels)
            {
                returnString[counter] = car.SelectSingleNode("Model").InnerText;
                counter++;
            }
        }

        //return the string array
        return returnString;
    }

Method 3

 /// <summary>
    /// This method will return a list of available colorus for the provided model/Make combination
    /// </summary>
    /// <param name="Model"></param>
    /// <returns></returns>
    [WebMethod]
    public string[] GetAvailableColors(string Model, string Make)
    {
        //Create an xml document to hold the list of cars
        XmlDocument carList = new XmlDocument();

        //Load the car list into the XmlDocumentObject
        carList.Load("http://localhost/FilteredDropdown/Reference%20Files/Cars.xml");

        //Create xmlNode list to hold a list of the models for the supplied manufacturer
        XmlNodeList carColors = carList.SelectNodes("//Cars/Car[Model=\"" + Model + "\" and Make= \"" + Make + "\"]");

        //create a string array to retun a list of car manufacturers
        string[] returnString = null;

        if (carColors.Count > 0 && carColors != null)
        {
            returnString = new string[carColors.Count];

            //Create a counter interger to track where we are in the colleciton
            int counter = 0;

            //Take each car node in the collection and add the Make child node to the string array
            foreach (XmlNode car in carColors)
            {
                returnString[counter] = car.SelectSingleNode("Color").InnerText;
                counter++;
            }
        }

        //return the string array
        return returnString;
    }

 

With the web service out of the way we now need to setup our InfoPath form to use it. First we'll design a new blank form in InfoPath, making sure the "Enable browser compatible features only" option is checked.

image

 

With our blank form created we now need to define our data structure like the one below, you'll notice that I have plural duplicates of the same node so I have a Make node and a Makes node, the plural node will be used to store the items returned from the web service. This allows for different entries in the "Cars" repeating list to have different items in their drop down lists.

image

Now remember anything that has a plural name should have the repeating box ticked

Next we'll lay out our controls on the form right click on the "Cars" group and select "Repeating Table" you should end up with a table that looks like this

image

Now this is pretty ugly and to be honest we don't need the "List" columns so removed those columns and change each of the remaining text boxes to drop down lists.

You should have a table should look like this

image

With our form setup we now need to hook up our web service to return the data we need for this we'll need a couple of Data Connections.

From the "Tools" menu select "Data Connections" this will display the "Data Connections" window

image

image

Click the Add button to start the "Data Connection" wizard, for our first connection we want to retrieve a list of Car Manufacturers so select the Create New Connection to Receive data radio button. Then click the next button

image

Now we want to pull the data from the web service we created earlier so select the Web Service radio button the click next

image

Enter the name url of your web service then click Next

image

 

InfoPath will then attempt to interrogate the WSDL for the web to determine the methods available. This will then present you with a list of available web methods to use, as we want to get a list of car Manufacturers we'll select GetCarManufacturer then click Next

image

For this example we are not going to store a copy of the InfoPath data with the form as it may change, but you may in your implementation prefer to store the data with the form to reduce trips to the server. For now simply click next to continue to the next step.

image

In the final step we can set when the data connection is queried and the name of the connection. This step however is usually overlooked and hence becomes a source of performance issues latter on. Be sure to check to see if you really need the data loaded automatically, as this can increase the load time of the form especially if there are multiple connections that need to be queried. For now we'll accept the defaults and click the finish button as we want this data to be returned each time the form is loaded. Click close to close the "Data Connections" window

image 

 

With our first data connection created we can now hook up our first drop down list to the GetCarManufacturer method. Right click on the "Make" drop down list and select "Drop Down List Box Properties". This will display the properties window for the drop down list box.

image image

First thing we need to do is rename the field to be something a little more intuitive. So change the Field name to "Make" to match our title in the designer.

Next we need to make the drop down list source its data from the data connection we created earlier. So from the "List Box Entries" section select the "Look up values from an external data source" radio button. By default InfoPath will select the first available data connection as we only have one available this is the one we want to use. With our data connection selected we now need to select the field that is going to be used in the drop down. Click on the "Edit Xpath" button next to the entries text box.

image

This will open the select field or group dialog, from here we can select the returned string array as the source for our drop down list. Then click "OK" to close the "Select a Field or Group" dialog.

image

On the properties dialog make sure the"Show only entries with unique name" check box is ticked the click ok to close the properties dialog.

With the "Make" drop down list setup we now need to add some code behind the "Changed" this code will execute the second data connection "GetModelList"lets move on to the "Model" drop down. First we need to create a new Data connection to return a list of car model. Open the Data Connections dialog via the tools menu, and click the "Add" button to to start the Data Connection wizard.

Create a new connection to receive data

image

Select "Web Service" as the data source

image

Enter the address of the web service we used earlier and click next

image

Select the "GetModelList" web method then click next

image

On the next screen we need to provide a sample value for InfoPath to query the web method we have selected. This allows InfoPath to determine the XML that will be returned from the web service ahead of time. Which in turn allows us to map our drop down to the returned results. For this example click on the set value button enter "Ford" then click ok. Finally click next to move to the next step.

image

As this data will change each time we use the form there is no need to store the data with the form so click next to progress past this screen

image

Lastly we don't want this data source to be queried when the form is loaded as we will not have a valid parameter to pass to it so clear the "Automatically retrieve data when form is opened" Check box and click "Finish"

image

Now we have our second data connection to return our Model data setup we need to add a rule to our Make drop down to copy the selected Make into the GetModelList connection and run the query when. Open the properties for the Make drop down list and click on the "Rules..." button

image

Click on the "Add..." button to add a new rule to the list

image

Name the rule "Get Model List" then click on the "Set Condition..." button

image

Basically we only want this rule to run when the "Make" drop down is not blank so select "Is not blank" from the second drop down then click ok

image

Add a new action to set a fields value, as we need to pass in the selected make to the web service before it can be queried

image

Now the field we want to set is the query parameter of the GetModelList connection we made earlier so click on the "Select Field" button next to the field text box to select the appropriate field.

image

Click ok to close the "Select a Field or Group" window and return to the action window. Click on the FX button next to the "Value" text box to set the value that will be provided to the web service. Then enter a full stop in the "Insert Formula" window (A full stop is XPath shorthand and represents the current node) then click ok to close the "Insert Formula" window

image

Click ok once more to close the "Action" window we should now have an "Rule" window with one action listed

image

Click the "Add Action..."button once more to add another action, now that we have set the value to be passed in we can now execute the data connection to get a list of returned results.

Select "Query Using Data Connection" from the action drop down then select "GetModelList" from the Data connection drop down and click ok.

image 

You should now have a rule that looks similar to the following

image

Click ok to save the changes

Now that the the filtered data has been queried we need to store it in the form, we need to do this so we don't get data inconsistencies when we add a new row to the repeating section.

First right click on the GetMake Drop down and select Programming>Changed

image

This will add a new event handler to the code that will execute after the value has been changed and also after any rules have been processed. So by the time this code executes the new values would have been selected and the GetModelList data connection should have been run. What the code now needs to do is to fill the ModelList/Models nodes with the models that were returned from the web service.

Model Population code

//If no models were returned then don't attmept to fill the list
if (getModels.SelectSingleNode("/dfs:myFields/dfs:dataFields/tns:GetModelListResponse/tns:GetModelListResult/tns:string", this.NamespaceManager) != null) 
{
    //Check for any existing entries that may have been carried over from the previous row
    if (currentRow.Select("../my:ModelList/my:Models",this.NamespaceManager).Count > 1)
    {
        currentRow.SelectSingleNode("../my:ModelList/my:Models[2]", this.NamespaceManager).DeleteRange(currentRow.SelectSingleNode("../my:ModelList/my:Models[last()]", this.NamespaceManager));
        currentRow.SelectSingleNode("../my:ModelList/my:Models[1]", this.NamespaceManager).SetValue("");
    }

    //Loop through each of the models returned and add them to the ModelList/Models node
    foreach (XPathNavigator model in getModels.Select("/dfs:myFields/dfs:dataFields/tns:GetModelListResponse/tns:GetModelListResult/tns:string", this.NamespaceManager))
    {
        //If the first node hasn't been set then set it with the first model returned
        if (currentRow.SelectSingleNode("../my:ModelList/my:Models", this.NamespaceManager).Value == string.Empty)
        {
            currentRow.SelectSingleNode("../my:ModelList/my:Models", this.NamespaceManager).InnerXml = model.InnerXml;
        }
        else //clone the last node in the list update it's value then insert the updated node at the end of the list
        {
            XPathNavigator newModel = currentRow.SelectSingleNode("../my:ModelList/my:Models[last()]", this.NamespaceManager).Clone();
            newModel.InnerXml = model.InnerXml;
            currentRow.SelectSingleNode("../my:ModelList/my:Models[last()]", this.NamespaceManager).InsertAfter(newModel);
        }
    }
}

Now that the models are being populated we can hook up the datasource for our Models Drop down list, switch back to the form designer and right click the models drop down and select properties

image

Select the "Look up values in the forms data source" option then for the entries value select the "Models" repeating node under the "ModelsList" group

image 

Make sure you check the "Show Only entries with unique display names" then click ok to save your changes

Now run your form to test your changes, you should find that when you select a make the model list automatically becomes populated with the data from the web service, plus because we are storing the returned data in the form if a new row is added the returned data is duplicated from row to row

image

image

 

image

 

image

Now I've left the code for setting the colour up out on purpose consider it a little challenge to make sure you can understand the concepts.

However I'm not completely heartless, if you want the complete solution you can always download it from here

you should note however this solution was created in Visual Studio 2008 so you may have to play around to get it running Visual Studio 2005, if I get time I'll put up a second copy for everyone stuck on old tech :o)

Using the Content Query Web part on MySite

So I was out on client site today attempting to setup the content query web part on a MySite, after exporting the web part and re-importing it to the my site I then got a "Could not load XSL file. The system cannot find the file specified" error. After google failed to provide me an answer I decided to have a play around with the site settings for the MySite and found that if I enabled the "Office SharePoint Server Publishing Infrastructure" site collection features the content query web part started working like a charm. Not only that but if I deactivated the feature afterwards the web part would continue to function normally

MOSSIG Agenda for 27th Feb

So as promised here is the agenda for the upcoming MOSSIG meeting on the 27th of Feb, be sure to head on over to the MOSSIG site and register so we have an idea of catering requirements

Ben Walters – “Developing Web Parts using Visual Studio 2008 and the Web Part Template Project”

SDM

Ben will be showing you how to develop Web Parts for SharePoint2007 quickly and easily using the Web Part Template project from Codeplex.

Tim Wragg – ‘Adventures in the SharePointDesigner’

Professional Advantage

The SP Designer is one of the great unknowns with little help and guidance available.

In this session, Tim will help crack open some of its great features and take us through a recent implementation of the Sanctuary Lakes site which incorporates Forms Authentication and integrations with Dynamics CRM and Great Plains – all done through the Designer!.

Chris O’Connor – Visio Integration with SharePoint – using K2 Workflow's

SDM

Chris will present the new Visio 2007 product, focusing on integrating list data from SharePoint for flowcharting, and viewing workflow tasks graphically.  The demo will also focus on the new K2[black pearl]workflow tool, with the Visio designer used to create SharePoint workflow's without the need for any coding or programming skills required.

 

Also Microsoft Developer Evangelist Andrew Coates contacted us with some awesome news for members who might be interested in sitting certification exams. Microsoft is launching a new certification offer to all User Group members (including MOSSIG members) to encourage MCP / MCTS certification.

This is an opportunity for you to save some money on exams and for the MOSSIG group a chance to win $3000.- worth of goodies to give away.

Here’s what Andrew had to say:

“* We're making it attractive for UG members to get certified - We've got 100 free exam vouchers for UG members who get an MCP or MCTS cert between now and May 31 (pass 1, get 1 free)

* We're making it competitive between User Groups - the UG with the highest number of MCTS/MCP certifications passed between now and May 31 get a $3000-worth hamper of SWAG to distribute”

For full details head on over to: http://technet.microsoft.com/en-au/cc182196.aspx

More Posts Next page »