Synergy
THE COMPANY . CONTACT
Blog 
Go Search

 MOSS Blog Posts

Sort by:
|
Group by:

Open PDF Files in a New Window
Randy Williams
Category: Design;Development
8/27/2010

A request that I get occasionally is how to force SharePoint to open up PDF files up in a new window.  Assuming you have Adobe Reader installed, the default behavior is to prompt the user to open the PDF file.  For some customers, they want it to automatically open up in the same browser window.  This is easy to do by following the answer shown here. (Note: this does assume that the browser plug-in is installed and enabled).

For me, I like this solution and simply use the back button when I’m done and want to return to SharePoint.  If I want it in a new window, I either hold down Ctrl and click the link or just right-click the link and select Open in New Window.  Basic browser stuff, right?  In most cases, I convince the customer that this is a training issue on how to use the browser. However, that doesn’t always fly with every customer, does it?

If you to force the PDF file to load into a new browser window, keep reading...

There are a number of posts on workarounds to the problem.  One says that you should write a httphandler.  Not a bad solution, very thorough, but a complex one unless your a seasoned SharePoint and ASP.NET developer.  Another talks about editing the global onet.xml file (gasp!) which is not supported by Microsoft and this targets much more than just PDF files.  Others suggest a somewhat elegant JavaScript solution.  This searches through the <A> tags on the page and inserts a target attribute and sets it to _blank which opens it in a new window.  The problem with this is that the target attribute is deprecated when using the strict XHTML doctype which will present problem with SharePoint 2010 sites.

I think I have a pretty-good workaround that addresses the problem.  This is a page-specific fix, so it is not global to all libraries or links in your farm. I like it this way as you have granular control where you want to use it, meaning you may only want to use it on certain pages within team sites.

The solution is to add this code to a Content Editor Web Part (CEWP) on the page:

<script language="javascript" type="text/javascript">
_spBodyOnLoadFunctionNames.push("OpenPDFInNewWindow()");

function OpenPDFInNewWindow()
{
// Get the collection of <a> tags
var aAllLinks = document.getElementsByTagName('a');

// For each <a> tag
for(var i=0;i<aAllLinks.length;i++)
{
var oA = aAllLinks[i];
var sHREF = oA.attributes["href"].value.toLowerCase();
// Is this a pdf link?
if(sHREF.indexOf(".pdf") > 0)
oA.href="javascript:window.open('" + sHREF + "').focus();";
}
}
</script>

Credit goes to Daniel whose code I modified to have this functionality.  To simplify this for all of you, I am also making this available using a .DWP web part.  You can simply upload this into the web part gallery of your site collection which allows you to more easily add it to any page. To download, click here.


Southeast Asia SharePoint Conference - 2010
Randy Williams
Category:
7/20/2010

image 

You are invited to the biggest SharePoint event of the year!

www.sharepointconference.asia

 

Southeast Asia SharePoint Conference

Tuesday October 26 2010 – Wednesday October 27, 2010

Grand Copthorne Waterfront Hotel, Singapore

**** Early Bird Discount for first 275 Registrations***

clip_image001

This is THE Conference to learn about SharePoint.

A beautiful location. Over 40 sessions with three tracks from which to choose; Business, Voice of a Customer – Case Studies and TWO concurrent Technical Tracks. Local and International experts. Hundreds of Business and Technical people. An opportunity like no other, and you're invited.

Full details at http://www.sharepointconference.asia.

image

Platinum Sponsor

Running over two days, delegates will be able to visit exhibition and information booths, attend workshops, learn from motivational customer case studies and partake in educational seminars.  There is something for everyone from end users, administrators and developers to managers and CIOs. Become part of the SharePoint community, connect at the conference and enjoy on-going benefits, resources and idea sharing after the event. 

Audience and Technologies

The SharePoint Conference is intended for a wide audience and has content to cover roles such as:

·         Business Roles like End Users, Business Champions, Power Users and Business Managers 

·         Information Architects, Record and Information Managers, IT Managers, CIO and Decision Makers

·         Technical Roles including Developers, IT Pro, Systems Administration and DBA's

Microsoft Technologies covered during the conference include:

·         SharePoint Foundation 2010 SharePoint Server 2010

·         SharePoint Designer and Visual Studio

·         Integration with other Microsoft Products including Office, InfoPath, Excel, Access and Visio

·         Integration with 3rd Party products enhancing SharePoint functionality​

Best of Local and International Speakers and Experts

We have an exciting line up of regional and international speakers to help make this a great conference. Over the coming weeks we will highlight some of the world renowned SharePoint experts who are coming to Singapore to share their knowledge.

Pre and Post Conference Workshops

Take advantage of the additional training opportunities on Monday October 25th and Thursday October 28th, with intensive half day workshops with hands on labs – 12 in total to mix and match to suit your needs. These cover Business and Technical Content by top international experts. These include:

  • SharePoint Governance
  • Planning and Managing SharePoint Projects
  • Spicing up your Site: SharePoint Designer
  • Improving Business Processes with Workflow (InfoPath and SharePoint Designer)
  • Upgrade to SharePoint 2010
  • Business Intelligence in 2010
  • Improving Document Management
  • Power User 2010
  • SharePoint 2010 Overview
  • SharePoint Development

Full details at Get to the Point Workshops. These workshops are HIGHLY recommended. Note that workshop costs are additional to conference registration and places are limited.

Accommodation

Accommodation should be booked directly with the hotel. Full details on accommodation rates are available on the Conference Website. There are a number of other hotel and motel options in the area.

Registrations Available Now

Group Registrations for 5 or more participants are available and will receive a 20% discount
Early Bird Registrations of $SGD300.00 will apply to the first 275 delegates who register.
Regular Registration fee is $SGD400.00

clip_image004

These rates include GST and also include attendance at the Networking Event 5:30-7:30 Tuesday 26 October.

Connect with SPC SEA

Web site: http://www.sharepointconference.asia/ 
Linkedin:
http://events.linkedin.com/SharePoint-Conference-South-East-Asia/pub/364552
Facebook:
http://www.facebook.com/pages/SharePoint-Conference-South-East-Asia/135980859759693
Twitter: #SPCSEA
@spcsea

 


Problems with VSeWSS Import Tool for Visual Studio 2010
Randy Williams
Category: Development
7/9/2010

The other day I blogged about the latest (RTM) version of the VSeWSS Import Tool for Visual Studio 2010.  I have been testing it out on a number of projects, and I have to say, it doesn’t work very well.  And I have not been testing it with complex projects.  For example, I took a very simple VSeWSS 1.3 empty project that had just a single web part and found three major issues with it.

1. The <SafeControl> entry is not automatically created for the assembly within the manifest.xml.

2. The element manifest for the feature portion of the web part is not upgraded properly.  Specifically, it defines the module this way which is bogus:

<Module Name="WebParts" List="113" Url="_catalogs/wp">
<File Path="EmbeddedImage\EmbeddedImage.webpart" Url="EmbeddedImage/EmbeddedImage.webpart" />
<Module>

The proper syntax for it is

<Module Name="WebParts" List="113" Url="_catalogs/wp">
<File Path="EmbeddedImage\EmbeddedImage.webpart" Url="EmbeddedImage.webpart" Type="GhostableInLibrary" />
</Module>

3. Finally, it does not replace the type correctly in the web part definition file (.webpart).  SharePoint is then not able to match up to the assembly when the web part is added to a page.

The beta version that came out in January 2010 seemed to be much more functional.  Even though it’s not supported, let’s hope basic functions like this can be improved.  Otherwise, it will probably be easier to manually upgrading the projects.


Upgrading VSeWSS Projects to Visual Studio 2010
Randy Williams
Category: Development
7/7/2010

While WSP Builder was the de-facto program to build SharePoint WSP solutions for SharePoint 2007, a number of my projects were based on various versions of VSeWSS. I have previously upgraded some of those with the beta version upgrade version, but I did notice recently that Paul Andrew released an update on his blog (http://code.msdn.microsoft.com/VSeWSSImport) and wanted to try it out.

The utility which is based on VSIX works okay, but it’s a bit of a pain to actually get it installed as you first must download and install the Visual Studio 2010 SDK.  You then need to build the project to generate the VSIX file.  Finally, you then run the VSIX to add the extension to Visual Studio.  So, I’ve done all these and am making the release-build compiled form available for download.  Simply download and run this in your development environment to add the Import VSeWSS Project template.

Kirk Evans wrote a simple blog that overviews how it works.  No need for me to duplicate his good work, so you can read about it here:  http://blogs.msdn.com/b/kaevans/archive/2010/06/16/import-sharepoint-projects-from-visual-studio-2008-to-visual-studio-2010.aspx

And here is the download:  VSeWSSUpgradeTool.Installer.vsix


SharePoint Conference 2010 – Southeast Asia
Randy Williams
Category:
6/28/2010

Event organizers have been working hard on this the past couple of months, and I’m proud to say that the SharePoint Conference for Southeast Asia is very much moving forward.  Debbie Ireland (SharePoint MVP from New Zealand and event organiser), Steve Sofian and I are working closely with Microsoft and the community to help make this a reality.

At this time, we are finalising the sponsorship packages, marketing plans, pricing, and venue.  Conference dates, although still tentative, are looking to be 26 & 27 of October.  We are also looking forward to having half-day pre- and post-con workshops the day before and day after.

Singapore has been selected as the host country.  But I do want to emphasise that this is a regional event, and we are working hard to ensure delegates from the region get word and have an opportunity to come.  In the meantime, you can register your interest by going to http://www.sharepointconference.sg and fill out the attendee survey. If you are interested in speaking, we have a form that you can fill out to submit your topic.  If you are keen to sponsor, we also have a form for you as well.

Also, as a personal note, I was at the Australia SPC a couple of weeks ago in Sydney.  It was a great event, with a solid turnout.   Feedback from Microsoft, sponsors, speakers and attendees was positively glowing. With lots of effort and maybe some luck, we can put on an equally good event for Southeast Asia.

Stay tuned and I’ll keep you posted on our progress.  I hope to see you there!


Single Sign On Web Part Update
Randy Williams
Category: Development
6/27/2010

I’ve gotten a lot of requests for the Single Sign On Web Part that I wrote about a couple years ago:  Developing a Web Part to Automatically Login using Single Sign On

I’m glad that it’s proven to be useful for many of you.  I have been meaning to update it for some time, and I have finally made a number of useful changes.  Here is a summary of the major improvements:

1. Cleaned up the HTML to make it XHTML 1.0 compliant

2. Added a new custom property to allow you to specify whether you want the web part to display in a new window. This is the new default setting.

3. If credentials for the currently logged in user do not exist for the configured application, it gives the user a link to create them

4. When using the web part to display the application in the new window, I provide a link to reset your credentials for the configured application

5. Improved error handling

On my list is to update this for the new Secure Store Service in SharePoint Server 2010.  As soon as it’s ready, I’ll let you know.  In the meantime, here are the updated files:

Source Code

WSP

PS. Thanks go to William White (http://www.willswebworks.com/) for many of his suggestions and assistance.


Speaking at Tech Insights 2010 – Kuala Lumpur
Randy Williams
Category:
6/7/2010

I have been confirmed as a speaker for Tech Insights 2010 in Kuala Lumpur, Malaysia.  Branded “Ignite your passion” this is sure to be a busy three days of content covering a range of IT Pro and Developer topics.  Some of the interesting ones I see on the agenda include “What do you see from cloud computing? Rainbow or thunderstorm” and “BPOS – Tips and Tricks from the Field”.  The event is scheduled to run from 29 June to 1 July at the Faculty of Computer Science & IT, University of Malaya Main Campus. 

Registration fees are very reasonable, just RM120 (SGD 50) with a RM40 discount for early bird registrations.  They have a pretty cool AJAX-based web site up and running at http://www.techinsights.my.  Unfortunately, I will not be able to attend for the full three days and my two sessions will be on 30 June.  Here are my two sessions:

Upgrading to SharePoint 2010

While SharePoint 2010 brings significant improvements, you may be wondering how well your environment will upgrade. If you currently have a SharePoint investment, and you’re planning on upgrading, this is the session for you. We’ll look at the hardware recommendations, upgrade options, how to deal with customisations, and discuss what steps you should begin today to ensure you're upgrade goes smoothly. For the demos, we'll look at the output from the Pre Upgrade Checker in SharePoint 2007. We'll then do a live upgrade of a fairly complex SharePoint 2007 content database to SharePoint 2010 so you can see exactly how the upgrade works. We'll then fix some of the problems encountered on the spot.

What's Changed for Developers with Visual Studio 2010 and SharePoint 2010

SharePoint's strength as a development platform improves in this new release. This talk will overview the major changes such as building visual web parts and consuming RESTful web services. We'll also look at something called sandbox solutions and will introduce the new client object model. Finally, we'll cover the improved tooling in Visual Studio 2010 which will help simplify the development and packaging of your SharePoint WSP solutions.


SharePointPROs.SG User Group Meeting – May 2010
Randy Williams
Category:
5/26/2010

Thank you for those who joined us for the post-launch session for the SharePoint User Group.  I know we were all pretty tired by that time, but we really appreciate your sticking around a while longer to hear a few other stories on SharePoint 2010, plus get a little food and maybe a polo shirt as well.

My thanks go to Linden Daniels and James Price for each of their sessions.

I am making the two slide decks available. Here is Linden Daniel’s talk on Information Architecture.

And here is my deck on Upgrading to SharePoint 2010.

Thanks again for coming.  Till next time...


Future of Productivity Launch - Singapore
Randy Williams
Category:
5/26/2010

Wow.  Yesterday was a very busy day at the launch event.  For those that made it to the event, I hope you were enthused by Steve Ballmer’s talk and educated by the others.  I know a few have asked about my slide deck and while this will be available through the Microsoft channels wanted to get it online right away. So, here it is:  FOP-Demos

I am also providing the source project code for each of my three demos.

Demo 1: Visual Web Part. You will need to change the connection string to a suitable database for your environment.

Demo 2: Sandbox Solution.

Demo 3: Excel Add-In.  You will need to change the paths of the REST web service reference.  In my development environment, the Url of my SharePoint web application is http://portal.synergy.com. The data that I used for the chart can be found in the list template (SalesData.stp) inside the Zip file.

Hands on Labs

Not sure if you knew, by COMAT (our training partner) and we built the customer immersion lab experience downstairs.  I wrote the SharePoint labs that were available.  I am also providing electronic copies of these here.  While this was built for the lab environment at the event, you should be able to get these to work in your own environment without too much re-work:

Client Model Model (Silverlight Application):

Sandbox Solutions

Workflow

SharePoint Conference South-East Asia

And, as a reminder, we are working hard to put on a SharePoint Conference here in SEA in the late October time frame.  I would appreciate all of you taking a couple of minutes and letting us know if you are interested by completing our survey.  You can find that and other details here:  http://www.sharepointconference.sg.

 

And in case you just need to see one of the dorkier photos of me…here is one of the snaps send to me during my presentation.

clip_image002


Visual Studio 2010 Auto-retracting SharePoint Solutions
Randy Williams
Category: Development
5/24/2010

While I like the new SharePoint packaging and deployment tools in Visual Studio 2010, there are some areas that will trip you up at some point.  One of them in particular, is the auto-retraction of a WSP solution after you finish debugging from Visual Studio.

Here is a common scenario:

1.  You write a new web part using Visual Studio 2010. 

2.  You then use F5 to build, package and deploy the web part into your local SharePoint environment. 

3.  You then add the add the web part to a page. 

4.  Everything is working fine, so you stop debugging from Visual Studio. 

5.  You now go back to your web page in SharePoint and refresh, and your web part is no longer there.  What happened?!?

Well, by default, in SharePoint 2010, you have the nice (or maybe not so nice option) highlighted here called auto-retract after debugging:

image

As you can see, when you stop debugging, it will run through a full retract of the solution, which deactivates the feature for a web part and then retracts and removes the solution from the solution store.

In my case, I prefer this option to be cleared.  If I want to retract it, I will do that myself.  You might consider doing the same.  Note that this is a project-specific setting, and any new SharePoint projects you create will always have this enabled.  I don’t know of any way to disable this permanently for new projects.


Speaking at Australia SharePoint Conference, June 2010
Randy Williams
Category:
4/25/2010

I’m thrilled to be heading down under again to speak at the Australian SharePoint Conference in June, held in Sydney.  The event is scheduled for June 16+17 and will have several concurrent tracks covering business, technical, voice of the customer, vendor. In addition, the event also has pre- and post-conference sessions titled “Get to the Point” that are intense four-hour workshops for those looking to get deeper, hands-on experience.

There are still open seats and the cost of A$650 for two full days of SharePoint content is quite a bargain.

My session is on June 16 at 10:30 – 11:30.  Here is the topic:

What's Changed for Developers with Visual Studio 2010 and SharePoint 2010 - 200 Level

SharePoint's strength as a development platform improves in this new release. This talk will overview the major changes such as building visual web parts and consuming RESTful web services. We'll also look at something called sandbox solutions and will introduce the new client object model. Finally, we'll cover the improved tooling in Visual Studio 2010 which will help simplify the development and packaging of your SharePoint WSP solutions.

Hope to see you there!  For more information or to register, please visit http://www.sharepointconference.com.au.


Business Value Launch – Singapore 2010
Randy Williams
Category:
4/25/2010

Finally SharePoint 2010 has arrived!  The product RTM’ed earlier this month, and was made available for download on April 22.  There is a pretty big SharePoint wave that has been building for quite a while, and it will no doubt grow with the Business Value Launch that is scheduled for 26 May 2010 at the brand new Marina Bay Sands.  But, this is not just a SharePoint launch.  It is the culmination of several years of research and development for many new products.  The full list includes:

  • SharePoint 2010

  • SQL Server 2008 R2

  • Visual Studio 2010

  • Microsoft Office 2010

  • Microsoft Visio 2010

  • Microsoft Project 2010

This is an event that you do not want to miss.  Microsoft is bringing in Steve Ballmer as the keynote presenter, and after the morning of keynote addresses, there will be four separate afternoon tracks covering Business Productivity, Collaboration, Business Intelligence, and Application Development.  I will be delivering one session in the afternoon titled SharePoint 2010 and Office 2010 Development.  Here is the outline:

Learn how you can be more productive in developing Office Business Applications using Visual Studio 2010. Attend this session to experience the ease of SharePoint development and deployment with the embedded tooling support in Visual Studio 2010. We will also cover how you can easily develop and customize Office 2010 applications and deploy them using ClickOnce.

In addition to the sessions, there will also be 100 machines provides for hands of labs, sponsored by COMAT.  I am personally writing the SharePoint developer labs, so come give SharePoint 2010 and Visual Studio 2010 a test drive!

Hope to see you there.

To learn more and to register for this free event, go to http://www.microsoft.com/singapore/futureofproductivity/default.aspx


    Exporting WSPs in preparation for upgrading to SharePoint 2010
    Randy Williams
    Category:
    2/16/2010

    If you are doing a database attach upgrade of your SharePoint environment from 2007 to 2010, you will be required to re-deploy all of your WSP solutions to your new farm.  Hopefully you have these stored in a designated location.  Fortunately, a script is available that can easily pull these from SharePoint’s configuration database in case you’re missing some.

    See Gudjon Porteinsson’s blog entry below for two ways to do it.  The first is the recommend approach, using the SharePoint object model.  If your farm is down, but you have access to your config database, the other way is to scrape these directly from the database.  This latter approach is not advised or supported by Microsoft, but when the you-know-what hits the fan, we do what we can.

    http://zgud.spaces.live.com/blog/cns!76596824C411964C!224.entry

     

    I took the liberty of creating a small console app based on Gudjon’s object model method and am making it available here for download.  This must be run directly on a server in the farm.  It will create the WSP files in the same folder from which you ran the program.  You must be a farm admin for it to run properly.


    Note: There is also a utility on CodePlex called SharePoint Solution Exporter (
    http://solutionexporter.codeplex.com/). Unfortunately, as of this writing, it does not support the exporting of globally-deployed WSP solutions.


    How to search across geographically dispersed farms without crawling
    Category:
    12/20/2009

    How to search across geographically dispersed farms without crawling

    In-between the release of SharePoint SP1 and SP2 Microsoft released an infrastructure update or mini service pack where a number of significant additions were introduced in particular a new feature called federated Search.

    Federated Search which was first featured in Search Server 2008, allows users to search against a number of different sources at the same time by adding a federated location trigger to the start of the search string.

    A trigger such as "Always" will always include the federated location in the search scope, or a trigger such as "Weather" will return anything from the federated location to do with weather.

    With a trigger added you can search against the index on the local farm and a number of additional sources such as a WSS 3.0 site with RSS enabled or any site that follows OpenSearch 1.0/1.1 standards without the need to crawl the remote source.

    OpenSearch sites provide a URL to a web page that returns XML results that can be used to configure the query string in Central Administration for the federated location, XML rendered result examples are RSS feeds, ATOM, ATOM2, or RDF. SharePoint has built - in XSL to render these schemas as HTML, so that the Federated Results web parts can display the results. Sources without XML formatted results can be used however you would need to write custom XSL to display the results.

     

    So with a little bit of central administration configuration a farm administrator can set up search to allow a user to federate results from geographically dispersed farms within your organisation.

    As you will see from the 4 points below they are fairly straight forward for a seasoned SharePoint administrator to configure.

    1. Enable RSS on the remote Site and copy an RSS search results URL
    2. Configure a new federated location on the local Farm using the copied URL
    3. Add a federated result Web Part to the Site the user will be searching from to include a result sent to the copied URL
    4. Check for Anonymous access or enable Kerberos
    5. Enable RSS on the remote Site and copy an RSS search results URL

      1. To enable RSS on the remote site you want to search against, on that site go to Site Settings > Modify all site settings > Site Administration> RSS and enable "Allow RSS feeds in this site collection" and "Allow RSS feeds in this site" tick boxes . This will allow you to pull the RSS URL from a search query result on the site you want to federated search.
      2. Go back to the home page and do a search against any known query
      3. On the results page note that an RSS icon is present
      4. If you perform a search against our own site and then select the RSS feed you would be taken to a page with something like the below URL

        http://www.synergyonline.com/Search/_layouts/srchrss.aspx?k=sharepoint&s=Synergy&u=&start=1&source=http%3A%2F%2Fwww%2Esynergyonline%2Ecom%2FSearch%2FPages%2FSearch%2Easpx%3Fk%3Dsharepoint

      5. Copy the URL of the RSS feed site and delete everything after the k= and replace it with {searchTerms}, its case sensitive so make sure the T in terms is capitalised.
      6. Leaving you with this http://www.synergyonline.com/Search/_layouts/srchrss.aspx?k={searchTerms}
      7. The "searchTerms" parameter is a placeholder for the search words that are forwarded to the federated location
    6. Configure a new federated location on the local Farm to use the RSS URL

      1. Open the local farms Central Administration site and navigate to the SSP of the Web Application you want to search against, normally the default SSP.
      2. Select Search administration then "Federated locations" from the left hand Nav.
      3. Select New Location
      4. Give the location a name, a display name, description, an author and a version as SharePoint it will ask you to fill them in once OK'd.
      5. Select "Always" as the trigger or select "Prefix" and add something relevant to the search e.g. Courseware. Basically this means that "Always" or "Courseware" will be the trigger you will need to add at the beginning of any search query that you want to include in the federated search results
      6. Expand Location Information and select the OpenSearch 1.0/1.1 radio button.
      7. In the Query Template section replace {searchTerms} in the text box with the RSS URL you edited in step 5:
    7. Add a federated result Web Part to the Site the user will be searching from to include a result sent to the RSS URL

      1. OK at the bottom of the page of federated location you have just configured, you can leave everything else as default, but feel free to explore.
      2. Open your local SharePoint site and perform any search from the home page.
      3. When the search results page loads go to "Site Actions" and select "Edit Page"
      4. Add a new Web Part in the "Right Zone"
      5. Expand the "All Web Parts" tree and Scroll down to nearly the bottom and select the "Federated Results" Web Part
      6. Select "Edit" and Modify Shared Web Part" of the newly added Web Part
      7. In the "Location" drop down select the name you gave your New Location in step 2IV and apply the changes to the Web Part
      8. Publish the page
    8. Check for anonymous access or enable Kerberos on the farm

     

    Kerberos is fast becoming the authentication method of choice for Network Security Teams unfortunately it's a little strenuous to configure for SharePoint to take advantage of it. If your Network Security team will allow anonymous access to be enabled on the remote farm then federated search will work as discussed in points 1 to 3 above however if not there is no easy way around it but to configure Kerberos authentication for all SharePoint farms. Once done though it will ensure that user credentials are passed through to the remote SharePoint servers and that security trimmed search results are returned to the user. As stated above Kerberos is a skill and fortunately too large a topic to cover in this blog post. If you want a more thorough understanding we recommend the following TechNet article as a great starting point on how to configure Kerberos in your SharePoint farm.

    http://technet.microsoft.com/en-us/library/cc263449.aspx

    1. Test it works

    To test that you're new federated Search works just add the trigger before the search query string. So if you wanted to search against the local index and a remote server your search query would start with "Always" or "Courseware" followed by the object you are searching for

    An Example using the above would be to type in the search box of the Local Site "Courseware Design course" representing the parameters "trigger {searchTerms}" to return a result from the remote site and the local site of anything to do with "Courseware" and "Design Course"

    1. Let the user know that federated search is available

    Try adding a custom List web part to the Search Results Page with a column called triggers and locations to show users what federated locations are available to them.

    1. Asynchronous and synchronous Federated Search Web Parts

    As multiple federated "New locations" are available to configure or add to the farms SSP SharePoint provides a way to display more than one federated result at the same time by allowing an administrator to place multiples of the "Federated Results" web part in conjunction with the "Top Federated Results" web part on the Search Results page

    1. Top Federated Results - web part: By using the Top Federated Results web part you can display the first result returned from up to 10 sets of differing remote locations. The order in which it returns a result is based on which location is listed first in the web parts properties so it's recommended to place the most relevant remote locations at the top of the list.

       

      The Top federated results web part renders synchronously only. If it was asynchronous it would allow the results to return after the synchronous web parts have already rendered so it's not allowed. This is to avoid the core search web parts results shifting down whilst been read if the top federated results web part is placed above it.

       

      Unfortunately if the results from the remote locations are slow in returning then all the synchronous web parts have to wait till the federated web part has finished rendering meaning it controls the final page load time and could impact the users experience if they have to wait for the core results web part to render waiting for the federated results to do the same.

       

    2. Federated Results - web part: By default the Federated Results web parts will be rendered asynchronously so the core results web part will render when it's ready without having to wait.

       

      If you have multiple Federated Search Results web parts on the page and you have configured them all to be asynchronous they will be displayed in the order they get results. So this could make the page jump from rendering web part to rendering web part as its result is returned. This is because the web part is placed in a zone on the page that is fixed and the order in which the result is returned does not automagically put that web part it belongs to at the top of say the right hand zone if it was originally configured at the bottom of the middle zone. If the jumping is too much you can uncheck asynchronous and the results in each web part will not be rendered until all the results have been returned. Again a slow location will mean the page load time will be affected in the same way that applies to the top federated results web part.

     

    The next article will show how to select a federated source from the search control on any page in a site.

     


    Using SPLinq in SharePoint 2010
    Randy Williams
    Category:
    12/18/2009

    With the next release of SharePoint and Visual Studio, Microsoft is making an even stronger statement on the future of Linq.  Up until now, SharePoint developers could easily bypass this technology.  With this latest release, it is becoming a more prominent mechanism to query for SharePoint data.  And there are some good reasons to use it.  Here are just a few that come to mind:

    1. Strong data typing and intellisense when working with SharePoint list and library data.
    2. No need to use CAML for your queries
    3. Use a friendly, SQL-like syntax
    4. Easily perform join operations between lists that have relationships (lookup columns)


    While CAML is still a big big part of SharePoint, at least the querying aspects can be now handled a better way.  The purpose of this article is to walk you through the basics of using SPLinq in a server-side object model example.  While different forms of Linq exist in both client- and server-side code, the SPLinq library that we’ll be using only works for code running directly on the SharePoint server.  In other words, you use it in the sample places you would use the server object model.

    The example that I’ll create for you in this article will be a simple SharePoint application page (deployed inside (14\template\layouts).  It will have a single drop down list that will display the list of projects that originate from a SharePoint list. After the project is selected, a data grid of all the people that have been assigned to that project will be displayed in a data grid.  These people originate in a contact list within the same web site.  So, the basic relationship is like this:

    image

    This relationship was established in SharePoint by adding a lookup column in the contacts list to point to the project.  Here is how the solution will look when we are finished:

    image

     

    Let’s get started.  We begin by creating an Empty C# SharePoint project in Visual Studio 2010.  In the project, I’ll add a new Application page, which is one of the many new SharePoint templates now baked into this version of Visual Studio.  This will add a new Layouts folder (mimicking the SharePoint root), a sub folder and your application page.  It also adds a few references to the project.  One that it doesn’t add that we’ll need is for Microsoft.SharePoint.Linq (or SPLinq for short).  If this is the first time you’ve added this assembly reference, you can browse for it at 14\ISAPI\Microsoft.SharePoint.Linq.dll. 

    Now, go into the code window for the Application page and add a couple of using statements for the Linq libraries we’ll use.

    using System.Linq;
    using Microsoft.SharePoint.Linq;

    The code that we’ll use for the application page should be located in the PlaceHolderMain content tag.  Here is the markup that will provide us the interface shown in the screen shot above.

    Select Project<br />
    <asp:DropDownList ID="lstProjects" runat="server" AutoPostBack="true"
    OnSelectedIndexChanged="lstProjects_SelectedIndexChanged">
    </asp:DropDownList>
    <SharePoint:SPGridView ID="grdContacts" runat="server" AutoGenerateColumns="false" >
    <HeaderStyle HorizontalAlign="Left" />
    <Columns>
    <SharePoint:SPBoundField DataField="FullName" HeaderText="Full Name" />
    <SharePoint:SPBoundField DataField="EMail" HeaderText="EMail Address" />
    <SharePoint:SPBoundField DataField="BusinessPhone" HeaderText="Phone" />
    </Columns>
    </SharePoint:SPGridView>
    Now, switch back into the code page.  As I mention above, when working with Linq, we get a strongly-typed way of working with data.  We also get intellisense.  At this point in the project, what we need to do is code against the projects and contacts lists in SharePoint.  Well, for Linq to help us out, we first need to import a C# class file that represents the lists and libraries that we’ll be coding against.  Unfortunately, this is something that you’ll need to do from the command line.  The utility that we’ll use is called spmetal, which is the SharePoint equilvalent of sqlmetal if you’ve used that to create Linq entity classes for SQL tables.  You’ll find this utility in the 14\bin folder on your SharePoint server which is the same folder as stsadm and other command-line utilities.  Here’s the basic syntax I used for my example:
     
    spmetal /web:http://sp2010a/teamsite /code:SPTeamsite.cs /namespace:SPTeamsite

    I chose this web Url as this is where my two lists (projects and contacts) are located.  By default, this command will examine all visible lists and libraries in this web site and generate entity classes in the code file you specify (e.g. SPTeamsite.cs).  You have a lot of control over how the entity classes are generated by passing a parameters file to spmetal.  I won’t cover that in this article and instead refer you to the details here: http://msdn.microsoft.com/en-us/library/ee535056(office.14).aspx.  (Note: Fellow MVP Walkek Mastykarz created a nice Visual Studio snap-in that you might consider using.  It will simplify your having to call spmetal this way and will also easily work on a single list.  See http://blog.mastykarz.nl/imtech-spmetal-definition-extension to check it out).

    Once the class file is created, I can just import it into my SharePoint project.  You now get the strongly-typed entity classes which will give us intellisense.  Yea!

    To begin working with linq, you need to create a data context, which basically acts as the handle to all code in the entity classes we just imported.  It’s common to create this is a class level variable as I have here.

    SPTeamsite.SPTeamsiteDataContext data;
     
    SPTeamsite is the namespace since I specified that when I ran spmetal.  SPTeamsiteDataContext is the class name since it simply appends DataContext to the name of your code file.  Again, this can be changed by using an spmetal parameter file.  The next step is to initialize this object, and I do this within the Page_Load event.  Here is the code.
     
    data = new SPTeamsite.SPTeamsiteDataContext(SPContext.Current.Web.Url);

    You can see that I chose to initialize it with the current web.  This allows me to dynamically load it at runtime and also makes this portable to other SharePoint web sites that also have these lists.  My next step is to populate the projects drop down list which I only want to do when the page is initializing (i.e. not in a post back).  I will do this using a simple linq query.  Here is how it looks.

     

    if (!Page.IsPostBack)
    {
    var q = from p in data.Projects
    orderby p.Title
    select p;

    If you haven’t seen linq before, you’ll notice it does resemble SQL, if you move the select line to the top.  Other that that, it is quite SQL like.  As I mentioned, you do get intellisense both on the data context and the list (entity).  Here is the intellisense when working with other entities in the data context.
     

    image

    And here is the intellisense when working with a single list.  In this case, it’s the project list which is a simple custom list so it doesn’t have many columns.

    image

    While not used in this demo, here is a modifed form of the projects query which filters out all blank (empty string) projects and only returns just two of the columns, aliased to different names.

    var q = from p in data.Projects
    where (p.Title != "")
    orderby p.Title
    select new { ID = p.Id, ProjectName = p.Title };

    For those that have worked with CAML and SPQuery objects, I’m sure you’ll agree this is MUCH easier.  From here, we just need to bind the results to our drop down list.  Here is the code that does it.

    lstProjects.DataSource = q;
    lstProjects.DataValueField = "Id";
    lstProjects.DataTextField = "Title";
    lstProjects.DataBind();

    Nice. At this point, we have the drop down list box working.  Feel free to run to deploy and test it out so far.  F5 deployment works great if you set the startup item project property to point to your application page.  Our final step is to add the code when a project is selected. Here is the code.

    protected void lstProjects_SelectedIndexChanged(object sender, EventArgs e) 
    {
    Int32 projectId = Int32.Parse(lstProjects.SelectedValue);

    var q = from c in data.Contacts
    where c.Project.Id == projectId
    orderby c.LastName
    select new {FullName = c.FirstName + " " + c.LastName, c.EMail, c.BusinessPhone};

    grdContacts.DataSource = q;
    grdContacts.DataBind();
    }

    Take a minute to absorb it.  I hope you find it fairly intuitive even though it is a two-list join operation.  In this case, I find it even simpler than using the join syntax in SQL.  This is because you don’t need to tell SharePoint how to link the two lists (e.g. Contacts.Project = Project.Title) as the entity classes already know that.  (Let me clarify that the lookup column on the Contacts list is called Project and it points to the Title column in the Project table.)  For the columns, I dynamically create a new column called FullName to represent a concatenated form of the first and last name.  Be sure that the returned column names match the SPBoundField entries used in the SPGridView control.  At this point, binding to the SPGridView is trivial.

    That’s it.  The code is complete and should match the screen shot above.  You’ve now seen a very easy way to query for data in your server object model code.  If you haven’t already, it’s time to start embracing Linq as it’s quickly become the de-facto way to query for data from any system.


    Developing a Silverlight 3.0 Web part for SharePoint 2010
    Randy Williams
    Category: Development
    12/18/2009

    It’s been a while since I’ve been able to work with Silverlight.  I did quite a bit of work about a year ago and blogged about my experiences (here is one of the posts).  With SharePoint 2010 development from Silverlight gets much easier.  Not only do we have all the Silverlight plumbing automatically in place on the web front end, but there is also a Silverlight web part wrapper that we can use to to easily point to our .xap file.

    Not only is it easier, it’s also much more powerful.  In this article, I will walk through the Silverlight client object model, one of the three client object models that Microsoft ships for SharePoint 2010.

    The goal of this post is to demonstrate how this works by creating a simple Silverlight app that does a multiple-file check out.  This application will be written in Visual Studio 2010 which also has built-in project types for Silverlight.

    We start by creating a new C# Silverlight project as shown here.

    image

    After you name the project and click OK, you’re prompted to create a web project to host it.  Since this will be integrating directly with SharePoint, I’ll not do this.

    image

    For the Silverlight project, add two references that allows us to work with the Silverlight client object model. These are the Microsoft.SharePoint.Client.Silverlight.dll and Microsoft.SharePoint.Client.Silverlight.Runtime.dll assemblies.  Both of these can be found in the 14\TEMPLATE\LAYOUTS\ClientBin folder.

    Open up the MainPage.xaml file and drag and drop a List box control from the toolbox onto the design canvas. For the listbox, set the SelectionMode property to multiple.  This will hold our list of files.  For my example, I will name my control lstFiles.

    Now add a button beneath the list box.  Set the Content property (the label for the button) to Check Out.  Here’s what your design editor should looks like

    image

    Create a new method for the Loaded event on the LayoutRoot object (this is the grid that is nested inside the Silverlight user control).  To do this, first click the Grid element in the XAML markup.  In the Properties panel, click the Events button and double click in the Loaded event drop down.  This will create the event handler and take you to the code behind page.

    Add this using clause at the top

    using SP=Microsoft.SharePoint.Client;

    We prefix it with SP to avoid some object name conflicts.  In the partial class for MainPage, let’s create these class-level variables.

    //class variables
    SP.ClientContext context;
    SP.Web myWeb;
    SP.List myList;
    SP.ListItemCollection myItems;
    List<File> files;

    In the LayoutRoot_Loaded method, let’s initialize our client context.  This will provide our entry point and become the object through which all calls to SharePoint are made. Here’s the code.

    context = SP.ClientContext.Current;

    By specifying the Current property, we are telling it to take the current SharePoint context.  In other words, the web site in which this will be working.  Since this will become a web part, we won’t know what the Url is so we just have the client object model look it up.  It’s the same idea as SPContext if you’ve used that before.  Next, let’s make a reference to the web site via this line of code.

    myWeb = context.Web;

    You can think of this as acting like the SPWeb object in the server-side object model.  And what you’ll start to see is that the client object model mimics many of the same behaviors that you’ve used in the server object model.  Although, it’s definitely a subset of the commands, so do not expect a complete duplication. 

    Next, let’s get a handle to a document library.  In my demo web site, I have a library called Docs where I have loaded a number of files.  Here is how I reference it.

     

    //Get handle to document library
    myList = myWeb.Lists.GetByTitle("Docs");

    Pretty close to the server object model. One difference that you are not referencing the list as a collection.  You’ll understand why in a minute.  Before that, let me prepare a query to return all the files in the library.  For this (just as you would have done with the WSS/MOSS object model in the previous version), you can create a CAML query.

    //Get all files
    SP.CamlQuery query = new SP.CamlQuery();
    query.ViewXml = "<View></View>";
    myItems = myList.GetItems(query);

    While this is a very simply CAML query, some can be downright ugly.  I’ve found that it supports the same query capabilities such as ViewFields, Where, OrderBy, etc.

    At this point, let me make something clear.  You you know, the client object model runs on the client, away from the server.   To be efficient in its call backs to the server, the design is to batch operations to minimize the number of round trips.  In this case, none of the code I’ve shown you so far has gone back to the server.  This is the reason why I cannot reference the Docs library by doing something like myWeb.Lists[“Docs”] which would be how you’d do it in the server object model.

    To batch these operations up, you can use the Load method on your client context object. 

    //batch up work to do
    context.Load(myList);
    context.Load(myItems);

    I batch up the list object since I requested a handle to it, and I batch up myItems since I am issuing query on the list.  However, still at this point, a call hasn’t been made.  That’s done with the ExecuteQueryAsync method as you can see next.

    //execute
    context.ExecuteQueryAsync(getRequestSucceeded, getRequestFailed);

    At this point, the call to the server is made and the batched requests are processed.  If all goes well, the getRequestSucceeded callback delegate is run.  If an error occurs, the other one is called.  In case you’re wondering why I didn’t use a synchronous (or blocking) call, it’s because Silverlight requires all calls to be made asynchronously.  This is actually done on a separate thread to prevent the UI from ever locking up.  Yes, it’s more complex, but results in a better user experience.  And, isn’t that what Silverlight is all about?  So, let’s first look at the getRequestSucceeded method.  Here is the code:

    private void getRequestSucceeded(object sender, SP.ClientRequestSucceededEventArgs e)
    {
    files = new List<File>();
    Dispatcher.BeginInvoke(() =>
    {
    //iterate through each file and add file to our list of files
    foreach (SP.ListItem item in myItems)
    {
    files.Add (new File() {Filepath = item["FileRef"].ToString(),
    Filename = item["FileLeafRef"].ToString()});
    }
    //bind to listbox
    lstFiles.DisplayMemberPath = "Filename";
    lstFiles.ItemsSource = files;
    });
    }

    Let me first clarify what this Dispatcher.BeginInvoke is.  As I just mentioned, we are now running on a separate thread.  Since we want to process the results and bind them to our listbox, we must do this on the UI thread.  The rule to remember:  anytime you want to change the UI, you must do it on the UI thread.  Ok, so the syntax that we’re using simply goes to the dispatcher object (the thread that dispatched the currently-running thread), and runs the block of code as an anonymous function.

    Inside the anonymous function, the code here should be pretty straightforward.  We iterate through each item that came back using the foreach statement.  We add these into a files object (which is a generic list).  The FileRef column is the filepath to the file relative from the web site (e.g. Docs/file1.doc).  FileLeafRef is just the filename.  From this point, we simply bind this to the lstFiles, my listbox object.

    Before I go too much further, let me give you the File class that we use in our generic list.  Just add this as a new class to your code behind page.

    /// <summary>
    /// Class to hold each file instance
    /// </summary>
    public class File
    {
    public string Filepath { get; set; }
    public string Filename { get; set; }
    }

    Next, here is the code that is run if an error occurs. 

    private void checkOutRequestFailed(object sender, SP.ClientRequestFailedEventArgs e)
    {
    Dispatcher.BeginInvoke(() =>
    {
    MessageBox.Show("Error occured: " + e.Message);
    });
    }

    That’s enough code to start testing.  We still haven’t implemented the check out, but let’s first see if our list of files is populated correctly. 

    As you may already know, the compiled output for a Silverlight application is a .xap file, and this is what SharePoint needs when using the built-in Silverlight web part.  So, somehow, we need to get this .xap file referenced in SharePoint.  There are lots of options such as manually uploading into a document library, placing it into the 14 hive.  However, this is a perfect example of where a sandbox solution would work great.  What I’ll do is deploy this as a module-type feature and locate it within the root web of the web site where this feature is activated.  Here’s how you can do this.

    Add a new Empty SharePoint project to your current Visual Studio solution.  When prompted, make it a sandbox solution which should be the default.  For my demo, I’ll also set the debug Url to the web site where my Docs library exists as you can see here.

    image

    Click Finish and then a new item in this new project.  Make it a module type as shown here.

    image

    Let’s do a little bit of clean up before we add our .xap file as a new file in this module.  Start by removing the Sample.txt file.  This also automatically removes the <File> entry from the elements manifest file (Elements.xml) for this Feature.  This feature file management is part of the new SharePoint tooling in Visual Studio 2010. 

    What we now need to do is reference the .xap file from the Silverlight project as a file in this module.  You can do this manually, but there’s a great automated way to do this.  In the Visual Studio Solution Explorer, click the SilverlightModule node (which was the name of the module I added).  In the properties window, click the ellipsis button for the Project Output References.  In the dialog, add a new member and set the Project Name to point to the Silverlight project.  Set the Deployment type to be Element File.  This is shown here.

    image

    Click Ok to save.  The final step is to simply add the <File> entry into the elements manifest file (Elements.xml). Here is the syntax showing the new line I’ve added.

    image

    Here is what this means during deployment: the SLApp2.xap file (the filename of my compiled Silverlight application) will be located within the SilverlightModule folder within the WSP package.  The Url is where in the web site this will be placed when this feature is activated.  Upon activation, SharePoint will copy the .xap file into the root folder of the web site.  I could have also stored this into a document library as a ghostable reference as well.

    At this point, I am going to do a full build of my projects.  After this, I will select deploy as shown here.

    image

    This should package everything up and deploy it as a sandbox solution into SharePoint.  It will then activate the feature in my teamsite web site (http://sp2010a/teamsite).  At this point, I just need to go into a web page within this site and add the built-in Silverlight web part.  In case you haven’t seen this before, here is how it looks when adding.

    image

    After you add it, it will prompt you for the Url to your .xap file.  I will enter in /teamsite/SLApp2.xap which is the path relative from the site collection to the Silverlight application.  When all this is done, here is how it looks.

    image

    Pretty cool so far.  Okay, actually it renders this way below with a messed up title.  This, I assume is just a beta 2 bug.  To resolve it, I just set the chrome type for the web part to None.

    image

    Let’s now go back to the Silverlight app and implement our final piece of logic to do the check out.  Go to the design page (MainPage.xaml) and double click on the Check Out button to create an event handler.  Here is the code I am using inside the button click event.

    //iterate through each file selected
    foreach (File item in lstFiles.SelectedItems)
    {
    //batch up file for checkout
    SP.File f = myWeb.GetFileByServerRelativeUrl(item.Filepath);
    f.CheckOut();
    }
    //execute
    context.ExecuteQueryAsync(checkOutRequestSucceeded, checkOutRequestFailed);

    This should be easy to follow and very much like the server object model.  The only difference is that I need to call the ExecuteQueryAsync again to actually call back to do the work.  The final items are the two callback methods when check out completes.  Here they are.

    private void checkOutRequestSucceeded(object sender, SP.ClientRequestSucceededEventArgs e)
    {
    Dispatcher.BeginInvoke(() =>
    {
    MessageBox.Show("Files checked out");
    });
    }

    private void checkOutRequestFailed(object sender, SP.ClientRequestFailedEventArgs e)
    {
    Dispatcher.BeginInvoke(() =>
    {
    MessageBox.Show("Error occured: " + e.Message);
    });
    }

    Time to recompile and redeploy everything.  When re-deploying new versions of Silverlight apps, you need to be careful that the browser does not cache your old version of the application.  I’ve gotten in the habit of always dumping my browser cache, and I would suggest you do the same.  When that’s done, refresh the page and test it out. 

    image

    If we select the Docs library, you can see that these two documents are indeed checked out.

     

    image 

     

    As you can see, performing functions like this are much easier than calling into or creating your own custom web service.  You might be wondering what exactly the client object model is doing to perform this task.  Well, actually, it is calling a web service.  In this case, the client.svc WCF web service that is new in SharePoint 2010.  For this example, it is posting a package of XML to the http://sp2010a/teamsite/_vti_bin/client.svc/ProcessQuery function.  Here is the XML payload that it is sending.

    <Request AddExpandoFieldTypeSuffix="true" SchemaVersion="14.0.0.0" LibraryVersion="14.0.4536.1000" ApplicationName="Silverlight Library" xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009">
    <Actions>
    <ObjectPath Id="41" ObjectPathId="40" />
    <ObjectIdentityQuery Id="42" ObjectPathId="40" />
    <Method Name="CheckOut" Id="43" ObjectPathId="40" />
    <ObjectPath Id="45" ObjectPathId="44" />
    <ObjectIdentityQuery Id="46" ObjectPathId="44" />
    <Method Name="CheckOut" Id="47" ObjectPathId="44" />
    </Actions>
    <ObjectPaths>
    <Method Id="40" ParentId="3" Name="GetFileByServerRelativeUrl">
    <Parameters>
    <Parameter Type="String">/teamsite/Docs/Coal.docx</Parameter>
    </Parameters>
    </Method>
    <Method Id="44" ParentId="3" Name="GetFileByServerRelativeUrl">
    <Parameters>
    <Parameter Type="String">/teamsite/Docs/ElectricPower.docx</Parameter>
    </Parameters>
    </Method>
    <Property Id="3" ParentId="1" Name="Web" />
    <StaticProperty Id="1" TypeId="{3747adcd-a3c3-41b9-bfab-4a64dd2f1e0a}" Name="Current" />
    </ObjectPaths>
    </Request>
     

    This example walked you through the client object for for Silverlight, but remember that there are two other client object models.  One is for just regular .NET applications (Windows Forms, WPF, console, etc.) and another one is for JavaScript (i.e. web pages).  The one for .NET is very similar to the one you’ve seen here since both are based on incarnations of the .NET Framework.  The JavaScript one is conceptually similar, but its syntax is a bit different.


    With that, I’ll bring this article to a close.  Hopefully you learned a thing or two about the client object model.  I also hope you’re eager to go out and give it a test drive in your own applications.  Have fun!


    Creating a Simple Visual Web Part in VS2010
    Randy Williams
    Category:
    12/18/2009

    One of the features of the Visual Studio 2010 when developing on SharePoint 2010 is the ability to more easily create web parts that use the familiar drag-n-drop experience from the toolbox.  That is, instead of having to hand-write all of the code in your CreateChildControls method, you format and layout your controls using the design view.

    The way this works is by wrapping the web user control (.ascx page) within a web part.  Actually, this idea isn’t all that new.  It’s something that we could do in VS 2005/2008 and that last version of SharePoint as well.  This is why SmartPart because such a useful utility. 

    Now, there are some drawbacks to this design that I should also share.  First off, since the web part lives in the file system, it cannot be used in a sandbox solution.  Secondly, since the web part lives in the file system, your web part needs code permissions to read from the file system and this may pose a security problem depending on your organization’s security policy.  I won’t go into details on these here, but will simply share three workarounds for this: 1) create a custom CAS policy for your web part; 2) Deploy your web part to the GAC; 3) Elevate the trust level in your web.config to Full.  #1 is the best options from a security sense (think principle of least privilege);  #2 is the easiest option and perhaps the most practical workaround; #3 is a very bad idea and I strongly discourage this option.  In my demo here, I will employ option #2 which is what Visual Studio will automatically do for us.

    To start off, create an empty project in Visual Studio 2010 as you can see here:

    image

    After you give it a suitable name and continue, you’ll be prompted for the site.  Enter in the appropriate Url.  Note, here’s where you can see that the sandbox solution is greyed out.

    When the project finishes completion, you will see that it created a new module-based Feature, a WSP Package, a user control and a web-part code behind file as shown here:

    image

    The idea at this point is that you open the user control (.ascx page) and go to the design view.  At this point, simply drag and drop your web server controls from the toolbox to the design surface. Use either the design or source tabs to format as you want.

    For this demo, I created a simple form as you can see below.  The Due Date control is not a ASP:Calendar control, but a SharePoint:DateTimeControl.  For this control, I set the DateOnly attribute to true (so it doesn’t show the time).

    image

     

    Here is the code I place into the Create button click event:

    SPWeb web = SPContext.Current.Web;
    SPList tasks = web.Lists["Tasks"];
    SPListItem newTask = tasks.Items.Add();
    newTask["Due Date"] = DateTimeControl1.SelectedDate;
    newTask["Title"] = TextBox1.Text;
    Label1.Text = "Task created";
    newTask.Update();

     

    As you can see, it just adds a new item to a list called Tasks in the same web site in which the web part is used.  At this point, you can simply hit F5 and the project will be packaged and deployed to your development environment.  If the startup item in your project is a visual web part, by default the browser will automatically take you to a screen where you can create a new web part page.  You can go ahead and create a page, but I just usually navigate back to an existing page and add the web part there.

    Here is what it looks like as I add it to my page.

     

    image

    And here is how it looks when in use.

    image

    Finally, here is the new task that was created.

     

    image

     

    Very easy as you can see.  Aside from the security drawbacks I mention above, it is a simple and effective solution to develop UI-intensive web parts.  This may also be a useful option for those that have a heavy investment in existing web user controls and need to get them working in SharePoint.


    Overview of using REST in SharePoint 2010
    Randy Williams
    Category: Development
    12/18/2009

    REST (or Representational State Transfer) is an easy way to easily get or post items to a server-side web service.  It is used in situations where you would use a web service but do not want the overhead and tightly-coupled nature of SOAP. With REST, it’s just a simple, client-server-like request using HTTP to retrieve or send information.  Technically, REST is not a protocol, but an architectural style.

    SharePoint 2010, being based on WCF in the .NET 3.5 Framework, has built-in RESTful web services which allow us to take advantage of this simplicity in custom applications we write.  It is one of the many data access mechanisms used in SharePoint 2010 development.  REST is intended for remote applications (i.e. not running physically on the SharePoint server) that need basic read/write capabilities to SharePoint’s list and library data.

    (Technical Note: At the time of writing, this was based on SharePoint 2010 beta 2. For this to work, you need to download and install the v1.5 CTP2 version of ADO.NET data services on your SharePoint web front ends).

    To help demonstrate some examples, let’s just go into the browser and make some get requests.  First off, here is a simple way to retrieve the lists and libraries in a web site.  (In my examples these will come from a SharePoint teamsite.)

    http://sp2010a/teamsite/_vti_bin/listdata.svc

    To retrieve information for a single list

    http://sp2010a/teamsite/_vti_bin/listdata.svc/Contacts

    Or perhaps just a single contact (in this case, the one with ID = 1)

    http://sp2010a/teamsite/_vti_bin/listdata.svc/Contacts(1)

     

    The output result comes back as an XML-based ATOM feed which is similar to RSS but having some notable advantages such as supporting binary object types.  By default, your browser may by default render this in a friendly HTML-way.  If you want to see the raw XML output--and for this demostration, we do--you’ll need to tell your browser otherwise.  For IE version 8 go to Tools –> Internet Options –> Content tab –> Feeds and web slices Settings.  In this dialog, clear the Turn on feed reading view checkbox as shown here:

    image

    When you do that and issue the request again, here is the output you’ll see below.  This one was for a single contact (click image to enlarge).  You’ll notice you’re getting the actual data contents for this contact plus the metadata (column name, data type, etc).  So, you’re basically getting a strongly typed data set.

    image 

    As you might expect, there are plenty of options to filter and sort.  Such as

    http://sp2010a/teamsite/_vti_bin/listdata.svc/Contacts?$filter=LastName eq 'Smith'

    and

    http://sp2010a/teamsite/_vti_bin/listdata.svc/Contacts?$orderby=LastName desc

    To learn more about the other querystring options, here is a great MSDN article that walks through many of them and other REST details:  http://msdn.microsoft.com/en-us/library/cc907912.aspx

    Using the browser this way is great for learning and testing, but what if we want to consume this in a real application?

    Consuming Rest in a Real Application

    Go into Visual Studio 2010 and create a new project.  For my demo, I’m going to create a new C# Windows Forms application.  To consume a RESTful web service in Visual Studio, you can go to the Data menu and click Add New Data Source.  In the dialog box, choose SharePoint as shown here:

    image

    In the Add Service Reference dialog, add the Url to a SharePoint 2010 web site.  Since you chose SharePoint data source, you do not need to specify the _vti_bin/listdata.svc.  Visual Studio will do that for you.  In my case, I add http://sp2010a/teamsite.  After I click the Go button, here is what I am shown:

    image

    For those that have consumed web services (either SOAP .asmx or WCF .svc ones), this should look familiar.  Visual Studio will be creating a proxy class for you that represents the strongly-typed nature of all of these lists.  Click OK to continue and a new proxy class will be created for you.

    Before I go any further, since I am working on Beta code, I need to replace the older ADO.NET data services client DLL.  To do that, go to the project references for the project and remove the System.Data.Services.Client entry.  Replace it with the DLL found in C:\Program Files (x86)\ADO.NET Data Services V1.5 CTP2\bin. 

    Next step is to go to the Data menu again and this time, select Show data sources.  From the list choices, I’m going to drag and drop Contacts onto my form.  This will create a GridView control and bind all of the columns based on the contacts type.  Since I only want to display a few columns, I’ll click on the GridView and edit the columns (see the Columns the properties window for the GridView object).  When I’m done, here is what I see:

    image

    Ok, enough design work.  Let’s write some code.  Go into the code for the form.  Add two using clauses to the top (you might need to rename the first one based on your project name and the name you gave to your service reference). 

    using RestDemo.ServiceReference1;
    using System.Net;

     

    Next, create a new class-level variable to hold the data context.  This is one of the proxy-class objects that was created that represents your interface to all the lists for the web site.  Notice that you also need to initialize it with the desired Url.  (Note: while you can change this to a different SharePoint Url, you must make sure that the list(s) that you intend on working with exist and have the same schema).

    TeamSiteDataContext context = new TeamSiteDataContext(new Uri(http://sp2010a/teamsite/_vti_bin/listdata.svc));

    Next, in the Form_Load event, add the following two lines.

    context.Credentials = CredentialCache.DefaultCredentials;
    contactsBindingSource.DataSource = context.Contacts;
    The first line will authenticate to SharePoint using your current logged-in account.  Of course, other login methods are available.  The second references the Contacts entity.  The contactsBindingSource is an object automatically created by Visual Studio when you added the Contacts list to your form. The data source for the GridView automatically points to this data source, so we can simply use it to wire everything up.  Simple, right?
     
    Note: In this example, I have not specified columns or rows.  In other words, give me everything which is not very efficient, sort of like a “select * from table” SQL command.  This is great for a simple demo, but not practical for large lists.  Here’s how it looks.

    image

    We’ve seen above that REST allows you filter and sort.  What if you wanted to be more efficient and filter and sort in our application. You can and one way you can do this is with LINQ.  Here is the modified code that I use instead.

    var q = from c in context.Contacts
    where c.ID > 100
    orderby c.FirstName
    select new { c.FirstName, c.LastName, c.EMailAddress, c.BusinessPhone };

    contactsBindingSource.DataSource = q;

    Notice that I’m just selecting a subset of contacts, sorting by first name and only returning the columns that I’m using in my GridView.  Better, right?  Now I get 100 rows (instead of 200 shown in the first one), properly sorted.

    image

    For those curious sorts (like me!), you might be interested in what the REST query looked like.  Here it is (as extracted from Fiddler):  http://sp2010a/teamsite/_vti_bin/listdata.svc/Contacts()?$filter=ID gt 100&$orderby=FirstName&$select=FirstName,LastName,EMailAddress,BusinessPhone

    We’re not quite done yet.  As I started off at the top of the article, I briefly mentioned that REST supports sending information back.  Among others, it supports insert and update operations.  This is also very easy to do.

     

    Sending updates back to the server

    Let’s first start by enabling our Save icon for the GridView control.  To do this, just click the save icon in the designer and set the Enabled property to True.  Now, double click the icon and add this line of code into the save event.

    context.SaveChanges();
     
    Next, create a new method for the CurrentItemChanged event on the contactsBindingSource object.  To do this, go to design view for your form and select the contactsBindingSource object (you’ll find it just underneath the GridView).  In the properties panel, click the events icon (it looks like a lightning bolt).  You’ll get something like this shown here. 
     
    image

    Now, double click the entry next to CurrentItemChanged.  This will create a new event handler and take you to the code behind file.  Add this one line into this method.

    context.UpdateObject(contactsBindingSource.Current);
     
    We’re nearly done, but have one small problem.  In order to update an item back on the server, it needs all of the columns.  This is so SharePoint can compare if there was a column-level conflict in the editing.  (Note: if a conflict does occur, this will be caught an an exception will be thrown in your client application).  So, we just make a minor change to our LINQ query.  This is a bit less efficient, but necessary for editing this way.
     
    var q = from c in context.Contacts
    where c.ID > 100
    orderby c.FirstName
    select c;

    Notice that I’m selecting the whole record, not just certain columns.  As written, this will update the data context with the most recent item that has changed.  When you click the save button (coded above), this modified item will be send back to the server.  For those curious about what exactly does this do, this sends an HTTP merge request back to the server with the payload of the newly modified record.  Here is the XML that was posted.  

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
    <category scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" term="Microsoft.SharePoint.DataService.ContactsItem" />
    <title />
    <author>
    <name />
    </author>
    <updated>2009-12-18T05:01:07.5478515Z</updated>
    <id>http://sp2010a/teamsite/_vti_bin/listdata.svc/Contacts(201)</id>
    <content type="application/xml">
    <m:properties>
    <d:Address m:null="true" />
    <d:BusinessPhone m:null="true" />
    <d:City m:null="true" />
    <d:Company m:null="true" />
    <d:ContentType>Contact</d:ContentType>
    <d:ContentTypeID>0x01060028B781066EBD3A4E93FE3073BAD6D104</d:ContentTypeID>
    <d:CountryRegion m:null="true" />
    <d:Created m:type="Edm.DateTime">2009-12-18T12:42:05</d:Created>
    <d:CreatedByID m:type="Edm.Int32">1</d:CreatedByID>
    <d:EMailAddress m:null="true" />
    <d:FaxNumber m:null="true" />
    <d:FirstName>Mickey</d:FirstName>
    <d:FullName>Mickey Mouse</d:FullName>
    <d:HomePhone m:null="true" />
    <d:ID m:type="Edm.Int32">201</d:ID>
    <d:JobTitle m:null="true" />
    <d:LastName>Mouse</d:LastName>
    <d:MobileNumber m:null="true" />
    <d:Modified m:type="Edm.DateTime">2009-12-18T12:59:25</d:Modified>
    <d:ModifiedByID m:type="Edm.Int32">1</d:ModifiedByID>
    <d:Notes>&lt;div&gt;&lt;/div&gt;</d:Notes>
    <d:Owshiddenversion m:type="Edm.Int32">8</d:Owshiddenversion>
    <d:Path>/teamsite/Lists/Contacts</d:Path>
    <d:ProjectID m:type="Edm.Int32" m:null="true" />
    <d:StateProvince m:null="true" />
    <d:Version>1.0</d:Version>
    <d:WebPage m:null="true" />
    <d:ZIPPostalCode m:null="true" />
    </m:properties>
    </content>
    </entry>

     

    With that, I’ll bring this post to a close.  You know have an introductory knowledge on using REST in your SharePoint 2010 applications.  Have fun with it!


    Speaking at Community Technology Update 2009 II
    Randy Williams
    Category:
    12/1/2009

    In what should be my final lecture of the year, I will be speaking at the Community Technology Update (CTU) 2009 on 19th Dec 2009.  This is an all day event covering four tracks: IT Pro, Developer, Special and Hands on Labs.  For a full rundown of all the sessions, please check out the event web page at http://www.sgdotnet.org/events/CTU2009v2/default.aspx.

    The event is being held at Microsoft Singapore, Level 21.  Here is my session:

    Development on SharePoint 2010 using Visual Studio 2010

    SharePoint's strength as a development platform improves in this new release.  This talk will overview the major changes such as building visual web parts and consuming RESTful web services.  We'll also look at something called sandbox solutions and will introduce the new client object model.  Finally, we'll cover the improved tooling in Visual Studio 2010 which will help simplify the development and packaging of your SharePoint WSP solutions.

    Early bird registration is just SGD$10 for this all day event and $15 at the door.


    SharePoint Pod Show Episode 38 – Backup and Recovery Strategies
    Randy Williams
    Category:
    11/30/2009

    From the plethora of SharePoint resources out there, one of my favorites is the SharePoint Pod Show that is hosted by Rob Foster, Nick Swan and Brett Lonsdale. Just one reason is that I can be lazy and just queue up the episodes into my MP3 player and just passively listen.

    Anyway, I’ve been bugging the hosts for a while to do a session so I can sort of “return the favor.”  Our schedules finally aligned at the recent SharePoint Conference last month in Las Vegas, and I sat down with Nick to talk about backup and restore strategies in SharePoint.  The taping went quick, and it was a lot of fun.  If you have a few minutes, take a listen:  http://www.sharepointpodshow.com/archive/2009/11/27/backup-and-recovery-strategies-episode-38.aspx.


    Speaking in Malaysia at Information Worker Community Day 2010
    Randy Williams
    Category:
    11/30/2009

    I will be speaking in Kuala Lumpur, Malaysia on the 10th of December.  The event is called Information Worker Community Day 2010 and is co-organized by the Malaysia SharePoint User Group.  There is no cost to register.  For registration or details on the event, see http://spugmalaysia.org/IWCommunityDay.aspx.  If you’re in the neighborhood, please join us as it will be a jam-packed event with both IT Pro and Developer tracks focusing on SharePoint 2010!

    Here is my talk and session abstract:

    Upgrading to SharePoint 2010

    While SharePoint 2010 brings significant improvements, you’re probably wondering what the upgrade story is.  If you currently have a SharePoint investment, and you’re thinking about upgrading, you don’t want to miss this session.  We’ll look at the hardware recommendations, upgrade options, how to deal with customisations, and discuss what steps you can take today to ensure you’re ready when SharePoint 2010 is released.  For the demo, you’ll see a live upgrade of a SharePoint 2007 content database.


    Speaking at World of Windows Server Conference - Singapore
    Randy Williams
    Category:
    11/30/2009

    Happy Holidays everyone.  December is shaping up to be a busy month for speaking engagements.  On Wednesday night, the 9th of December, I’ll be at Microsoft Singapore giving a talk titled Kickstart Collaboration with Windows SharePoint Services.  The session will be end-user oriented, and here is the synopsis:

    The Gartner Group tells us "most companies don't understand how much value collaboration creates." In this session, you will see why SharePoint is the business collaboration platform for the enterprise and the web. We will start by demonstrating the value that Windows SharePoint Services-a free feature that comes with Windows Server-gives you. We will then see how SharePoint Server can extend the value across the enterprise.

    This is part of a multi day and evening event held on 8-10 December.  During the daytime, a 3-day SQL Server 2008 master class will be held, and the breakout sessions are in the evenings from 6:30 to 9:30pm.   For more information on this event or to register, please go to http://www.microsoft.com/singapore/wowsc/default.aspx

    For the evening events, the registration fee is only SGD$49 per evening/pax.  Hope to see you there!


    What's New in SharePoint 2010?
    Milan Gross
    Category: Architecture
    11/25/2009
    On November 25, I participated in a seminar hosted by Dimension Data Learning Solutions in Sydney on the top new features coming in SharePoint 2010. The presenters were myself and Gayan Peiris from Microsoft. Gayan is a SharePoint Technology Specialist and former MVP. Although this is only the beta 2 version of SharePoint 2010, already the number of new capabilities are impressive and we put together a slide deck that was heavy on details and light on marketing so that we could show as many of the features as possible. Here is the PDF version of the presentation we delivered: What's New in SharePoint 2010?

    Joining up with Steve Sofian to run SharePointPROs.SG
    Randy Williams
    Category:
    11/13/2009

    Effective immediately, I’ll be will be joining forces with MVP Steve Sofian to assist in running the SharePointPROs.SG user group. Now that the news is public on SharePoint 2010, we have a lot of community work to do!  I’ll be working with Steve to evangelize the new version, assist in the recruitment of new sponsors, work towards getting a new SharePoint site hosted (hopefully on 2010!), and of course occasionally handle speaking duties.

    So, don’t be surprised if you see me around the island more often trying to entice new membership.  (hint, hint).  We currently meet on the second Thursday of every month at the NTUC Center (Microsoft’s offices).  If you’re in town or curious about what the user group is about, please drop us a line.  We are also on Facebook, so become a fan.  Hope to see you at a future meeting.


    Presentation Decks – Microsoft Singapore
    Randy Williams
    Category:
    11/13/2009

    This week I did a few talks for Microsoft and the Singapore SharePoint Users Group.

    1.  One of the talks focused on the business value of SharePoint as an Internet-facing platform.  It covers a little bit of the value proposition that SharePoint brings and discusses basics of designing SharePoint web sites.  Here is the PowerPoint deck:  BrandingSharePointFIS

    2.  Another talk covered what’s new with SharePoint 2010.  This briefly introduces the 6 workloads of SharePoint.  Here is the deck:  SharePointOverviewWhatsNew

    3.  The final deck was an overview of Upgrading from WSS 3.0 / MOSS 2007 to SharePoint 2010.  I have numerous screen shots that walks you through an actual upgrade of a content database from a 2007 farm that was attached to a 2010 one.  Here is the deck:  SharePoint2010Upgrade


    SharePoint 2010 Hands on Labs
    Randy Williams
    Category: Development
    11/2/2009

    At the SPC, they had a huge lab room set up with dozens of hands on lab exercises for IT Pros and developers.  Microsoft has now released part of these that are developer focused out to the community.  The remaining ones, I’m told, will be released as part of the public beta coming out later this month.

    So, the first is a series of 10 videos that you can follow.  Topics range from Building Web Parts in SharePoint 2010 to using the client side API (Client-side object model) to building sandbox solutions.  You can watch each of them here: http://msdn.microsoft.com/en-us/sharepoint/ee513147.aspx

    For those that already have the early SharePoint 2010 bits, you might want to download the actual lab exercise and go through these steps yourself.  These are the same lab files that are used in the videos above. Just a warning that not all of the resources you need may be available, so you may have to work your way around some of the steps.  http://www.microsoft.com/downloads/details.aspx?FamilyID=C010FC68-B47F-4DB6-B8A8-AD4BA33A35C5&displaylang=en

    Enjoy!


    SharePoint Conference 2009 - Reflections from a Developer
    Randy Williams
    Category:
    10/24/2009

    I am now sitting in Los Angeles (LAX), having finished the first of my three flights back home.  My next flight is to Toyko and then to Singapore—just another 22 hours to go.  :-)

    But the trip was worth it.  And what a trip it was.  The SharePoint Conference (SPC) was a lot of fun, more on that in a minute.  Before the conference, I had a chance to catch my favorite baseball team, the Los Angeles Dodgers battle the Philadelphia Phillies.  Having been a Dodger fan since the late 70’s, it was my first game at Dodger stadium.  The game was great with the Dodgers pulling ahead in the bottom of the 8th inning; however, it was all for naught as the Dodgers lost the four other games of the series to end their season.  Here’s a shot of me at the end of the game.

    image

    So, yes, what did I think about the conference?  The sessions, overall, were okay.  About half of them were pretty good; the others were just so-so.  As many will tell you, it’s the networking and catching up with old friends that is the best part.  I’m still totally stoked about the next version and thrilled that the NDA is finally lifted.  And there were a few surprises.

    Big news items first. 

    • The public beta for SharePoint will be in November.  Microsoft wasn’t specific about when during the month it will be available.  I’m quite anxious as well as I have been working on bits that were released back in July.
    • New product naming has been announced.  Windows SharePoint Services (WSS) is now called SharePoint Foundation.  The name for SharePoint Server doesn’t change.  Is it too early to start calling Foundation SPF?


    That said, let me just give you a quick rundown of some of the major changes to the product from a developer perspective.  These are not listed in any order of importance.

    Business Data Catalog, now called Business Connectivity Services (BCS) will be part of SharePoint Foundation.  BCS is completely revamped, supporting full read/write operations.  Through it users can now create what is called an External Content Type (ECT) which allows you to have a fully readable and writable linked list in SharePoint that originates from a back-end source of data.  Creation of line-of-business models can be done from SharePoint Designer and Visual Studio. These models can also leverage ADO.NET data services, so you have write managed code to expose all operations.

    Developers now have a visual web part, which allows them to use Visual Studio’s toolbox to drag and drop controls onto a page.  Sound great?  Hold on.  It’s really just an .ASCX user control that the web part wraps by using the LoadControl method to dynamically load the control into memory.  So, effectively, this is the same thing we had before in the previous version.  And the problem with this continues to be code access security.  You see, for the web part to load the control from the file system, it needs file system permissions.  There are only two advised ways you can do this.  1) Deploy the web part assembly into the GAC, or 2) deploy to the bin and write a custom CAS policy to grant the assembly permissions.  The first may not be allowed by your security policy, and the second is just painful.

    Visual Studio’s tooling for building SharePoint solutions takes a radical shift in Visual Studio 2010.  VSeWSS as we know it goes away. In the new tools, there is significant improvement in the ease of building features, Solutions, event receiver, etc.  For example, you can much more easily control which element manifests get bundled into your features and which features get packaged into your WSP solution.  For developers new to SharePoint, you’re sure to appreciate the ease of building and deploying SharePoint code.  IMO, there is a downside that I must share.  Microsoft has really abstracted the process of understanding how features and solutions work.  For example, you really don’t need to understand the XML of the manifests (feature.xml, manifest.xml, elements.xml, etc), nor do you need to understand where in the SharePoint root (14 folder now, by the way) these file artifacts get placed.  Why is this a downside?  For one, troubleshooting.  Newbie SharePoint developers will likely have a hard time figuring out how to resolve feature and solution problems because Visual Studio hides so many of these details. One could also make the argument that by not understanding the architecture here, you groom developers that don’t really understand what they’re doing.  Incidentally, there was a very heated discussion on this back at the MVP Summit in March earlier this year.  This was when we first saw these tools and expressed our concern to Microsoft over the direction they were taking.  We’ll see what happens.

    Sandbox solutions.  These are similar to the WSP packages that you have build to the previous version, but there is a critical difference.  The idea with the “sandbox” is that site collection administrators can load them into a new gallery where they run in a locked-down, or throttled state.  The solution’s resources are not stored to the file system and all code is run in a no-compile way (as far as I can tell, similar to how customized pages run).  Okay, this is pretty cool, but these restrictions will prevent you from having any solution just be “sandboxed.”  For example, a visual web part cannot be sandboxed because of the .ascx control.

    Client Object Model (CLOM).  This is probably my favorite feature.  With CLOM, we now have a radically improved way of consuming SharePoint content from client applications, whether they are browser apps (via JavaScript), Silverlight, WinForms/WPF, Console Apps, whatever.  How many of you have written an app in the previous version and had to go through the classic SOAP-based Web Services?  Isn’t it painful trying to consume the XMLNode objects and don’t you wish you could just treat items as you would in the Server object model (e.g. SPListItemCollection)?  With the CLOM, you can.  There are actually three forms of the CLOM, one for JavaScript , one for Silverlight and one for regular .NET apps.  Expect many additional posts from me on this subject.  I’m stoked!!

    Built-in Visual Studio templates for developing a Silverlight Application.  And with that, there is an OOB web part for hosting Silverlight applications.  Just point it to the .XAP file and you’re good to go.  Now that it is easier it is to build and deploy Silverlight apps, look out.  I expect this to really take off and may possibly be the the leading development platform of the future.

    Rich support for WCF-based Web Services and REST.  Those that haven’t played with REST are strongly encouraged to do so and will find that read/write operations on content get so much easier, even without using CLOM.

    Full read & write editing through Excel Services.  Support for full web-viewing of Word and PowerPoint files.  Access and Visio Services is brand new.

    Developer Dashboard.  When I first saw this, it reminded me of turning on tracing in the web.config for those that have done that before.  But it’s much better than just that.  You’ll get the time each server-side event has taken, along with each of the database calls.  Administrators should also find value this in as there is a reference to specific ULS log file for helping to identify the log file for this execution cycle.

    While not directly related to developers, but something you’ll be pleased to hear is that you can now enforce relational integrity between lists using the newly redesigned lookup column.  For example, if you have a parent list Customers and a child list Orders.  On the Order list, you have a lookup column pointing to the customer.  What’s different is that you now can define how you want this relationship to work.  That is, if a customer is deleted, it will either (1) cascade the deletes operations to all the related orders, or (2) block the deletion.  This is great as we were relegated to writing item event receivers to implement this in the past.

    Completely different UI. If you’ve seen the SharePoint sneak-peek videos, you have already seen this.  Yes, the UI is SharePoint 2010 has been completely revamped.  With full XHTML support, WCAG 2.0, AJAX, new master pages and easier-to-use and lighter-weight CSS, new branding and customization projects will get easier.  However, what if you have invested heavily in branding a 3.0/2007 site?  Well, you will have generous backward compatibility by continuing to use the v3 UI; however, all these benefits of 2010 are not available to you.  The net result is that most branding efforts will need to be redone to take advantage of the new features.

    Microsoft has also unveiled a new SharePoint 2010 Developer Center.  Be sure to check it out and begin reading up on the new technology here:  http://mssharepointdeveloper.com

    Well, it’s time for me to board my flight.  I’ll continue to post more detailed updates over the next couple of months.  And to answer what may be an important question from you: “When will SharePoint 2010 be released?”  I can’t say.  Honestly, no further details were shared on this.  My prediction is still sometime second quarter next year, so we’ll have a good long beta to get ready before it hits the streets.

    Off to Tokyo.  Sayonara.


    Magazine Article: Step-by-Step SharePoint Disaster Recovery
    Randy Williams
    Category: Architecture
    10/6/2009

    My first article for Windows IT Pro magazine has been printed.  It involves how to recover a SharePoint farm from just the SQL Server-based database backups.  You’ll find it in the Oct 2009 print edition or online here:  http://windowsitpro.com/article/articleid/102572/step-by-step-sharepoint-disaster-recovery.html.

    My next article will be on SharePoint security.  I’m working on it right now and it should be in print hopefully before the end of the year.


    SharePoint – Yesterday, Today and Tomorrow
    Randy Williams
    Category:
    10/6/2009

    On the Microsoft SharePoint Team Blog, a very interesting and somewhat nostalgic article has been posted.  It discusses the evolution of SharePoint from its very humble beginnings from Site Server, Office Server Extensions and Digital Dashboard.  Back at that time (late 1990s), I recall writing some “Outlook Today” interfaces that were pre-cursors to today’s dashboards. As some of you may remember, they were mostly ASP web pages that were hosted inside Outlook.

    The MS blog article then takes us forward through STS 1.0 through WSS 2.0 and Portal Server 2003.  While I experimented a bit with these early versions of the product and even architected and helped deploy a sizeable SPS 2003 for the US Air Force, I can’t honestly say I liked the product from a technology standpoint.  Honestly, I just thought it was convoluted.  Being a purist in some ways, I had problems with the kludgy ASP.NET integration and SQL Server incorporation.  The SharePoint team was not entirely to blame, the 1.0 and 1.1 ASP.NET Framework wasn’t very robust.  From a business standpoint, I was all over it.  While I thought the concept of SharePoint it was badly needed, it was just more trouble than it was worth.  Even after using it for quite sometime, I still couldn’t seem to remember where to go in Central Administration to configure some things.

    The article moves a few years forward into the release of the currently shipping product, WSS 3.0 and MOSS 2007.  What a difference four years makes.  The incorporation of CMS 2002, item level security, Excel Services, BDC, improved search, improved administration, improved Office integration, the product is finally ready for prime time.  And did customers respond.  Very few, including Microsoft were ready for the onslaught.  It’s been a lot of fun building solutions and training others on the product.

    As you probably know, we are eagerly awaiting the next release, dubbed SharePoint 2010.  The beta will be out shortly and the product will be publically unveiled in two weeks at the SharePoint Conference (SPC) in Las Vegas.  Having played with it for a couple months now, Microsoft has certainly raised the bar and done some amazing things with the product.  Each limitation SharePoint today has today has been closely scrutinized and many improvements are sure to please IT Pros, Developers, and of course, the most important cohort of users: the Information Workers.

    So with that, I hope you’ve all booked your tickets to the SPC.  It will truly be a show, Vegas style.  If you can’t make it, rest assured that the blogging community will do our best to prepare you for the significant improvements.  It’s been a great few years working with the product, and I’m as excited as ever about the new release.

    BTW, If you still haven’t seen the Sneak Peek videos yet on SharePoint 2010, I highly recommend checking them out.


    SharePoint Restores, Applying Updates and Understand Builds
    Randy Williams
    Category:
    10/3/2009

    When applying a new service pack or cumulative update to your SharePoint farm, you’re often instructed to do a backup both before and after the installation. Doing the backup beforehand is obvious.  If the patch somehow damages your farm, your backup ensures you can recover into a state just prior to the update.  This is doubly important for SharePoint since the updates cannot be uninstalled.

    However, it might seem odd that you are also instructed to backup immediately after your update as well.  Let me explain why.  When you apply a service pack or cumulative update, the installation (and the SharePoint Products and Technologies Configuration Wizard that is run immediately after) makes several changes.  The most relevant ones related to this topic are the upgrading of code files located on your SharePoint WFE(s) and making changes to the configuration and content databases. In short, SharePoint’s code and databases must always remain in sync.

    Let’s look at scenario that explains how these could get out of sync:  You have a farm that is currently patched to the SP1 level and you apply SP2. Shortly after the SP2 update, something happens to one of your site collections, requiring you to do a content database restore.  Your most recent backup is the one you made just prior to the SP2 update.  You go into SQL Management Studio and restore the SP1-version database on top of the damaged one.  After the restore, you try to access the web sites, and you find that all the web sites in each site collection for that content database are broken. You now have a much bigger problem, all because of mismatching versions.

    This is the main reason why you are instructed to run a backup after the upgrade.

    A good question you might be asking is “How come SharePoint isn’t smart enough to recognize the problem and just upgrade the database?”  Actually it is, but you can’t perform the steps as described in the scenario above.  Here is a better way to perform the database recovery which will usually result in a successful upgrade:

    Before you issue the restore, go into Central Administration and remove the content database that is damaged.  You can do this from the Application Management Tab –> Content databases.  After this is done, drop the old database in your SQL Server and restore it backup.  Finally, use the STSADM –o addcontentdb command to add the content database back.  When you do it this way, SharePoint checks the versions and if it detects an older version will usually make the necessary changes to upgrade it to the correct version level.  Incidentally, if you try to add the content database from the Central Administration GUI, you will be greeted with this error directing you back to STSADM:

    image

     

    I should add that I have heard cases where this upgrade doesn’t always work.  Erring on the side of caution, I still recommend doing the post-upgrade backup.

    Understanding SharePoint Build Numbers

    Let’s now look at how SharePoint uses build numbers and where these are stored.  I’m sure you’ve seen these before.  For example, here are some of the common build numbers for SharePoint v3/2007:

    RTM Build 12.0.0.4518
    SP1 Build 12.0.0.6219
    Infrastructure Update Build 12.0.0.6318
    SP2 Build 12.0.0.6421

     

    When performing a recovery, you can always find out what your database build numbers by looking at the versions table inside the database.  This applies to all SharePoint databases except Single Sign-On. If you query the versions table on your configuration database, for example, you’ll see values such as:

    image

    In the results above, you can see the latest version is 12.0.0.6421 or SP2.  What you’ll also notice is the lineage of the upgrades.  That is, this farm was originally built with RTM (Release to Manufacturing—i.e. the original release) and then upgraded to SP1 (6219) and then SP2.  Again, you can run the same query on the other SharePoint databases as well.

    Lastly, as you know, you can find the farm version in Central Administration if you go to Servers in Farm in the Operations tab.  Did you know that you can also find this in the registry?  This might be helpful if your SQL Server is down and you can’t run Central Administration.  You’ll find it in the Version value located in the the HKLM\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0 key.

    Armed with this architectural knowledge on versions and build numbers, you should have more confidence in your recoveries and also better understand why you should backup both before and after an upgrade.


    Developing an Employee Spotlight Web Part for SharePoint (Part 2 of 2)
    Randy Williams
    Category: Development
    9/30/2009

    Welcome to Part 2 of the Employee Spotlight Web Part.  In Part 1, we examined the how the web part looks, is configured, works, is customized, and is deployed.  This article will focus on the code that went into building the web part. 

    The web part was developed in Visual Studio 2008 using the Web Part project template from VSeWSS v1.3.  The SharePoint Solution (i.e. WSP) package was assembled using WSPBuilder.  Those interested in studying the web part or customizing this should download a zipped version of the source code available here.  Ok, let’s jump into the code.

    The personalization properties are all quite straightforward. For example, here is just one of them that defines the rotation frequency setting.

    //Define the configurable properties
    [Personalizable(PersonalizationScope.Shared),
    WebBrowsable(true),
    WebDisplayName("Rotation Frequency"),
    WebDescription("Specify the rotation frequency")]
    public Frequency RotationFrequency
    {
    get { return _rotationFrequency; }
    set { _rotationFrequency = value; }
    }

    Since the web part retrieves all the employee data from the User Profile store within the SSP (Shared Services Provider), the code makes use of ServerContext, UserProfileManager and UserProfile classes in the MOSS Object Model. 

    In the CreateChildControls method, one of the first steps is to select an user’s profile to display (see GetProfile method).  Of course the code needs to look at a number of configuration options (e.g. manual profile selected, cached profile name, rotation frequency, etc.) to determine who to select. 

    Once the profile is selected, the code simply iterates through each property one by one to generate the XML document that represents all the profile data for the user.  Since this web part code is executed under the identity of the impersonated logged-on user, we are assured that profile privacy settings are preserved.  That is, if the user cannot read a certain profile property, a null value is returned, and an empty node value is stored in the XML document.  For example <schools></schools>.  As recommended in Part 1, you should probably ensure that the privacy settings for each property that you want to display (dictated by the XSLT) is set to Everyone.

    Once the XML Document is constructed, the code pulls the current XSLT document and transforms the XML into HTML.  This is done via the Transform method on the XslCompiledTransform object (see my Transform method in the code).  The HTML is then just delivered back as the only output rendered by the web part.

    Ok, this was the easy portion, but there were two tricky areas that I had to work around.  The most significant one involved enumerating the actual users in the User Profile store.  (SharePoint Security note: Only users with the Manage User Profiles permission can enumerate profiles).  This is done as part of the GetRandomUserProfile method.  You see, most of the code is run under the context of the regular user account, and a regular user does not have permissions to enumerate user profile.  No problem, I figured I would just wrap this in a RunWithElevatedPrivileges block.  This would then revert the identity to the application pool account.

    The problem is that this just didn’t seem to be good enough.  As much as I tried even the application pool account didn’t seem to have permissions.  (Yes, I did grant the app pool account the Manage User Profiles permission as instructed at the end of Part 1).  After doing some research and asking my MVP colleagues, Brendon Schwartz directed me to this helpful blog: http://mphacker.spaces.live.com/Blog/cns!8040CC624DDC5404!290.entry

    It seems that the security context for calls into the User Profile store can be made under the credentials of the httpcontext.  In my case, the httpcontext is still set to the user, meaning the RunWithElevatedPrivileges does not changes the httpcontext.  Ok, so the hack I have to employ is the set the httpcontext to null, and when I do this, it uses the proper security credentials of the application pool.  Of course, this clearing out is only temporary, so I save it to restore once I have enumerated the profiles. 

    Here is the resulting code that works like a charm.

    //revert to app pool account
    SPSecurity.RunWithElevatedPrivileges(delegate()
    {

    try
    {
    //save our httpcontext. This is necessary as calls into the User Profile
    //store are actually made under the httpcontext identity if is is not null.
    //Must temporarily set to null to ensure this runs under the context of
    //the app pool count. See
    //http://mphacker.spaces.live.com/Blog/cns!8040CC624DDC5404!290.entry

    saveContext = HttpContext.Current;
    HttpContext.Current = null;

    //Get a UserProfile manager context
    upm = new UserProfileManager(ServerContext.Default);

    //build an array of profiles that can be selected
    profileArray = new ArrayList((int)upm.Count);

    //iterate through each profile to build the list
    foreach (UserProfile temp in upm)
    {

    //additional code has been removed

    }

    //restore our HttpContext.
    HttpContext.Current = saveContext;

    if (profileArray.Count == 0)
    throw new Exception("There are no enabled profiles");

    //Randomly select one from our list
    profileSelected = rnd.Next(profileArray.Count);

    }
    catch (Exception)
    {
    //attempt to restore HttpContext
    if ((HttpContext.Current == null) && (saveContext != null))
    {
    HttpContext.Current = saveContext;
    }
    throw;
    }
    });

     

    The other problem I had (and still have since it hasn’t been resolved yet), is that I store the account name (used when rotation frequency is being used) back into a hidden personalization property value for the web part. This seems like a reasonable location in which to store it.  However, even with RunWithElevatedPrivileges, I couldn’t seem to get the web part to property save the value for regular users. Users with either design or full control privilege works just fine. So, the known bug is if it is time to select a new user (for example, it’s a new day and the rotation frequency is daily) and a non-privileged user hits the page, it will randomly select a new user but is not able to cache it.  When a privileged user hits the page, it will randomly select a new user and properly cache it.  It’s a minor bug, but it was still annoying.  Here is the code that I am using:

    /// <summary>
    /// Save Profile State
    /// </summary>
    /// <param name="freqValue">The frequency value</param>
    /// <param name="accountName">The name of the user account to be saved</param>
    private void StoreProfileInState(int freqValue, string accountName)
    {
    //Save this modified State value. Unfortunately, this doesn't actually save if the user does not have
    //permissions to modify the web part's settings.
    //todo: figure out a way to get this to save in all cases
    State = freqValue.ToString() + ";" + accountName;

    //Inform web part manager that the state has been changed
    this.SetPersonalizationDirty();
    }

    If you have better suggestions on how to do this, please let me know!!

    Well, that’s how the solution came together.  I think it’s pretty flexible already, but feel free to download the code and improve upon it.  Again, the link to the code is here.

    Have fun!


    Developing an Employee Spotlight Web Part for SharePoint (Part 1 of 2)
    Randy Williams
    Category: Architecture;Development;Web Content Management
    9/30/2009

    A request that comes in from time to time during my SharePoint deployments is to be able to have an employee spot light section of the portal.  That is, they want to be able to “shine the light” on a particular (or even random) employee that exists in the organization. Since SharePoint does not have an out-of-the-box web part that provides this functionality, and there is not an easy-to-use and flexible solution that is available on the net, I finally ended up writing one recently.  This is what I will demonstrate in this article.

    The approach I took is that the information displayed in the web part originates from the User Profile store, which is SharePoint’s repository for people in an organization. Since the User Profile store is a function of Microsoft Office SharePoint Server (MOSS), this web part cannot be used on a Windows SharePoint Services (WSS)-only implementation. 

    The primary advantage of pulling this data from the User Profile store is that you do not need to maintain a separate database of all this user metadata.  (And, hopefully, you are synchronizing this data from your Active Directory and possibly from external databases going through BDC.  For more information on this, see the following article: http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-6-of-8).

    This article is broken out into the following sections:

    • How the web part looks
    • How it can be configured
    • How it works
    • How it can be customized
    • How to deploy

    In Part 2 of this article, I’ll walk you through the code.

    How the Web Part Looks

    Here is the default view on how the web part looks when spotlighting a user:

    image

     

    As I mentioned already, the content displayed originate from the user’s entry in the User Profile store. In this screenshot above, I use preferred name, title, phone, picture url, and the about me properties.  As you’ll see below, the look and feel (i.e. the HTML rendering) and the properties that you pull from the User Profile store can be fully customized.

    Basic Web Part Configuration

    The web part has the option of automatically rotating to a new random user after a defined time period. Available time periods are hourly, daily, weekly and monthly. With weekly, for example, the same user will be shown during the whole week. Additional options are to display a specific user, and this won’t rotate until you manually change to a new user. This might be helpful if you want to put the spotlight on a new user for an indefinite amount of time. A final option is to have it always rotate every time the screen is re-displayed.

    By default all users can be selected to be in the spotlight, but you also have the option to either include or exclude certain users. In other words, you can have it it include everyone except designated users. Or, conversely, have it exclude everyone except designed users.  In either way you use it, it is helpful to ensure certain users are never spotlighted.

    As with any web part, this can be used on different pages throughout the portal. Each place where the web part is used will have unique settings. For example, on the main front page of the portal, you may have a specific user set in the spotlight, whereas on the HR home page, you have a rotating user. 

    Let’s now examine how to configure the web part. All the settings are coded as shared personalization properties, meaning that any configuration setting you provide applies to all users who view this web part.  Each configuration listed here can be found in the Miscellaneous section when configuring the web part. Here are the configurable settings:

    • Rotation Frequency. Available values are None, Hourly, Daily, Weekly, Monthly.  None means that for every page refresh a new random user will be selected. Daily, for example, means that each day a new random user will be selected.  All instances of this web part will display the same user until the next day.

    • Manual Profile. Specify the domain\username to be manually (and always) spotlighted. Setting this value will override any rotation frequency setting.

    • Include or Exclude Users by Default. This check box allows you to set the default whether all users will be selected or no users will be selected.  By default this is set to include users by default.

    • Name of Profile Property to Either Include or Exclude users: Set the name of the custom profile property in the User Profile store that will determine who should be either included or excluded.  By default this is named ExcludeFromSpotlight, which means that you should create this property and then manually set this property value for users who should not appear in the spotlight.  Note: if you are including users by default, you do not need to create this profile property (meaning the web part can select from all users in the store). If you are excluding users by default, you must create this profile property so that it knows who it should include in the list of people that can be selected.

    • XSL: Allows you to define the XSL that is used to generate HTML. Through this configuration setting, you can completely redesign the look and feel of the web part’s output.  More details on how to customize this are covered later in this article.

    How the Web Part Works

    As you just read, an XSLT stylesheet is used to generate the displayed HTML for the web part.  This implies that the source data must exist in an XML format so it can be transformed into HTML. Here is an overview of how the process works:

     

    image

     

    The web part extracts the selected user’s information from the profile store and generates an XML format of this data (what I’ll call an XML document in this article).  The XSLT stylesheet then converts this XML document into HTML which is what gets output by the web part. 

    The schema of this document is quite simple where the name of each property becomes an element name.  The element contents are simply the value of the property.  For example, here is a sample XML document showing just a few of the properties and their values.

    <Profile>
    <AccountName>SYNERGY\rwilliams</AccountName>
    <PreferredName>Randy Williams</PreferredName>
    <WorkPhone>555-1212</WorkPhone>
    <AboutMe>SharePoint Trainer and Consultant</AboutMe>
    <PictureURL></PictureURL>
    <WorkEmail>rwilliams@synergyonline.com</WorkEmail>
    ...
    </Profile>

    Tip: To help you remember the schema, there is a Sample Data setting exposed by the web part.  It’s only purpose is for you to understand the XML document so you can customize the XSLT stylesheet.  Changing this XML has no impact on the how the web part works.

    As you might know, each profile property can be individually secured by a privacy setting. For example, one property value can be seen by everyone, the user’s manager, or only the user.  Some property privacy settings are set by the administrator and some are set by the individual user.  You should know that this XML document is re-generated on each rendering of the page (i.e. it is not cached).  While this may pose a slight performance hit, it is necessary to preserve the integrity of these privacy settings.  So, if a user who is viewing the spotlight web part does not have permissions to read a certain user’s property value, this XML element will not be included in the XML document.  In summary, only those properties that the user has permissions to see are shown. To prevent confusion and to ensure the web part renders consistently for all users, it is recommended that all properties that are to be included in the spotlight have a privacy setting of Everyone. This is all manageable through the SSP (Shared Services Provider).

    Additionally, you can add custom properties through the SSP administrative screen, and these will be included if the requesting user has permissions. This makes it very extensible. Of course, to be useful, these profile properties must have values. By default, many of these can be populated from Active Directory. Profile properties can also be synched with external databases as I mentioned above. Lastly, these values can also be manually updated.

    Customizing the Web Part’s Display

    Customizing the web part’s output involves providing the web part with the XSLT that is used to transform the XML document into HTML. Since the web part is just part of a larger HTML payload for the whole SharePoint page, only include the HTML fragment that needs to be displayed. The initial XSLT stylesheet that is loaded into the web part generates the HTML shown for the web part view above.  You can use any tool to help you generate the XSLT (such as SharePoint Designer) or you can write it from scratch. 

    Here is the initial XSLT stylesheet that the web part uses:

    <xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
    <xsl:output method='html' />
    <xsl:template match='/'>
    <xsl:apply-templates />
    </xsl:template>
    <xsl:template match='Profile'>
    <table>
    <tr>
    <td>
    <img src='{PictureURL}' />
    </td>
    <td>
    <span style='font-size:10pt;color:#606060;font-family:Tahoma'><xsl:value-of select='PreferredName' /></span><br />
    <hr />
    <span class='font-size:8pt;color:#ffffff;font-family:Tahoma'><b>Title:&#160;</b></span>
    <span class='font-size:8pt;color:#5b5b5b;font-family:Tahoma'><xsl:value-of select='Title' /></span><br/>
    <span class='font-size:8pt;color:#ffffff;font-family:Tahoma'><b>Phone:&#160;</b></span>
    <span class='font-size:8pt;color:#5b5b5b;font-family:Tahoma'><xsl:value-of select='WorkPhone' /></span><br/>
    <br/>
    <span class='font-weight:bold;font-size:8pt;color:#5b5b5b;font-family:Tahoma'>
    <xsl:value-of select='AboutMe' disable-output-escaping='yes'/>
    </span>
    <br/>
    </td>
    </tr>
    </table>
    </xsl:template>
    </xsl:stylesheet>

    How to Deploy

    Deployment for the web part is quite simple. Simply add the WSP solution to the solution store and deploy it to one or more web applications.  Since the web part is configured as a site-collection-scoped feature, you also need to activate this in the site collections you want to use it.  The web part’s assembly will be deployed into the global assembly cache (GAC).

    Decide whether you will be including or excluding users by default as described above.  Again, if you will be excluding users by default, you must create a custom profile profile and then enable those users who can be spotlighted.

    Security Note:  The application pool account(s) for the web application(s) where this web part is used must have the Manage User Profiles permissions within the SSP.  This ensures that the application pool is able to retrieve the list of profiles that are located in the store. To assign this permission, access your active SSP. From the User Profiles and My Sites group, click Personalization services permissions.  In this screen, add the Manage User Profiles permission to your your application pool accounts.

    Conclusion

    In this article, you have learned how the web part looks; how it can be configured; how it works; how it can be customized; and how to deploy it.  For SharePoint administrators out there, this is as much as you normally would need to know.

    For the developer’s out there that want to understand or improve upon the code, jump to Part 2 which will walk you through the code.  Part of the code is quite straight-forward, but there was an interesting problem that I had that I’ll explain to you.

    With that, here is the link to the SharePoint solution (WSP) that you can download.  Those interested in checking out the code now, here is the link.

    Enjoy!


    Singapore SharePoint Pros Meeting - PreUpgradeCheck
    Randy Williams
    Category: Architecture;Governance
    9/21/2009

    On Wednesday night, 16 Sept 2009, SharePoint expert Joel Oleson spoke at the Singapore SharePoint Pros meeting (SharePointPROs.SG).  The topic was a very relevant one, Preparing for Upgrade to SharePoint 2010.  In his talk, he introduced a very useful operation that has been added to STSADM, PreUpgradeCheck. I bring this up as not only does this very effectively point out problems in your SharePoint farm, it’s also a pretty documentation tool for parts of your farm.

    As you may recall, I recently mentioned out a new CodePlex utility called SPDocGen.  From a documentation standpoint, some advantages of PreUpgradeCheck are that the output comes out in an XML format (but nicely transformed into very readable HTML using an XSLT stylesheet).  It also contains some details that are not included in SPDocGen.  This includes information on your Alternate Access Mappings (AAM), size of your index and any large lists (greater than 5000 items) that it finds. However, SPDocGen still has some advantages, and you might want to consider running both of them.

    Running PreUpgradeCheck is a very safe operation and does not modify your SharePoint environment in any way.  This is different than the previous PreScan.exe tool (intended for 2003 to 2007 upgrades) which did, albeit harmlessly, make a few changes. Nonetheless, to be safe and until you’re comfortable with it, you should run on development or test environments first.  Joel’s advice is to make a virtual copy of your SharePoint farm and run it there.  Of course, in order to run PreUpgradeCheck, you must have upgraded to SP2.  If you haven’t, please make a plan of upgrading soon!

    For more information on upgrading and additional features in SP2, you can read another of Joel’s posts here: 5 Reasons SharePoint 2010 PreUpgradeCheck is better than Prescan.

    You can also view or download Joel’s slides from this link:  http://www.slideshare.net/joeloleson/preparing-for-upgrade-to-sharepoint-2010-with-joel-oleson-quest-software-webcast


    Developing and Managing Software Projects – Hawaii .NET Users Group
    Randy Williams
    Category: Development
    9/20/2009

    Even though I have relocated to Singapore, I still do my best to help assist with the .NET User Group and the SharePoint User Groups back in Hawaii.  On Wednesday evening, Sept 23, 2009 from 6-8pm (HST), I will be doing a special Live Meeting broadcast session.  Here is the session I will be presenting:

    Date: Wednesday, Sept 23, 2009, 6-8pm (Hawaii Standard Time)

    Topic: Developing and Managing Software Projects

    In this session, Randy will share his background on building and managing software projects. This talk will include some of the important academic issues such as understanding the various software development lifecycle models (waterfall, unified process, extreme programming, agile, Microsoft Solutions Framework) and some of the practical ones such as maintaining development environments (including virtualization). Other topics will include

    • Managing and triaging bugs

    • Juggling multiple project tasks and personnel

    • Promotion of code between development, test and production environments

    • Project documentation

    • Offshoring of resources

     

    While this is not a talk specific on .NET, we will be discussing all of this mostly in the context of Randy's experience in developing and deploying Microsoft solutions over the past 15 years.  Please bring your questions and opinions!

    Note: This will be done as a virtual broadcast using Live Meeting.  If you would like to attend the live broadcast (using Live Meeting), here is the url:
    https://www.livemeeting.com/cc/synergy/join?id=R8958T&role=attend&pw=p%3BzXR%5E53t

     

    (Post meeting update: The slides from this event are available here Managing Software Projects)


    Microsoft SharePoint Conference 2009 is Coming…
    Randy Williams
    Category:
    9/9/2009

    Have you registered yet?!?  It’s in Vegas baby.  There are still a few seats left, so if you do have a chance to make it to the great American Southwest next month, you’ll no doubt have a great time (both day and night) at the upcoming SharePoint conference. 

    This will be the definitive SharePoint conference this year and is the official unveiling of the next generation of SharePoint technology, SharePoint 2010.  Steve Ballmer will be giving a keynote, and the top names in the industry will be there covering a wealth of topics.  You can read more about what to expect on the conference Sneak Peek page located here:  http://www.mssharepointconference.com/pages/SessionSneakPeak.aspx.

    The event runs from October 19-22.  Hope to see you there!

    image


    Building a 64-bit SharePoint Development Environment
    Randy Williams
    Category: Development
    9/9/2009

    As many of us begin to ramp up on the next generation of SharePoint technology, we’re faced with a bit of an environment challenge.  As you may know and as I have blogged about previously, SharePoint 2010 will require a 64-bit machine. The challenge is for those who prefer to use virtualization software as their platform technology, and those that follow my blog know I’m a big fan of virtualization. What’s the challenge you ask?  I’m glad you asked…

    There aren’t a lot software choices when running a 64-bit virtualization environment.  First off, you have to rule out Virtual PC since that only supports 32 bit guests.  Yes, while you can run Windows Server 2008 (or R2) with Hyper-V (see a previous blog post last year of mine on this), there may be licensing issues and it’s certainly not laptop-friendly.  You’ve got VMWare Workstation, which is a pretty good product, but it’s not free.  However, there is another choice that I have been using lately and have been quite happy with it.  It’s called VirtualBox.  Here are some of the advantages I see:

    • It’s very easy to use, whether you have previous virtualization experience or not

    • It supports 64-bit guests (assuming your host is 64-bit)

    • It runs great on a Windows 7 host OS

    • Based on GPL, so it’s basically free (yeah, I like that).

    • It’s text-based logging feature makes troubleshooting very simple

    • Supports the major features you’d expect such as snapshots, saving state, multiple NICs, USB, shared folders, etc.

     

    So for those that are still searching for the ideal virtualization platform for desktops, it’s definitely worth taking a look at.  http://www.virtualbox.org.


    New Utility to Help Document SharePoint Farm Configuration
    Randy Williams
    Category: Architecture
    9/9/2009

    Fellow MVP Sezai Komur just released a cool utility that SP Admins should find helpful in documenting their SharePoint environment.  I’m a bit advocate of documentation, and documenting your SharePoint environment is quite important for a number of reasons, including disaster recovery. 

    You run the utility directly on one of your SharePoint WFEs, and it will scrape all kinds of useful settings such as web applications, timer jobs, site collections, content databases, etc.  The output is stored in an XML format and there’s a sample XSLT file that will even transform it into a Word doc for you.

    Definitely worth taking a look at.  You can find it on CodePlex called SPDocGen (http://spdocgen.codeplex.com/) or read more about it from Sezai’s blog located at http://sharepoint-sezai-moss-2007.blogspot.com


    Hiding the Sign In link for anonymous access to SharePoint web sites
    Gavin Adams
    Category: Design;Web Content Management
    8/27/2009

    On a recent project of developing a public facing website using SharePoint 2007, we had a requirement to hide the “Sign In” link from the site for those accessing the site anonymously.

    Firstly a bit of background on the SharePoint environment. It is configured with a single web application where the default zone has SSL access and windows auth for use by the content managers only. The web application has been extended to the internet zone for the http://www URL.

    What we wanted was the sign-in link and the authoring controls, site action menu, etc to be visible for authenticated users but not visible for anonymous users.

    Now I’d like to state that the following is not my idea just another one of those ideas which are spread across several blog posts. The following is an example of how I used this information in our implementation.

    The solution is to use a SharePoint:SPSecurityTrimmedControl to only make enclosed code visible to authenticated users.

    Here is the code snippet of what is in my master page including the SPSecurityTrimmedControl:-

       1: <!-- lock down authoring controls to only auth access -->
       2: <SharePoint:SPSecurityTrimmedControl PermissionsString="AddAndCustomizePages" runat="server">
       3:     <div id="sharepointAuthoring">
       4:       <div class="wrapper">
       5:                       <!--- --- --- Page Status Console --- --- --->
       6:                     <div style="height:0px;width:100%">
       7:                     <wssuc:DesignModeConsole id="IdDesignModeConsole" runat="server"/>
       8:                     </div>
       9:                     <!--- --- --- Site Actions Menu --- --- --->
      10:                     <span class="siteActionMenu">
      11:                     <PublishingSiteAction:SiteActionMenu runat="server"/>
      12:                     </span>
      13:                     <div class="sharepointLogin">
      14:                                     <!--- --- --- Authentication for Authors only --- --- --->
      15:                                     <span class="ms-globallinks">
      16:                                     <SharePoint:DelegateControl ControlId="GlobalSiteLink1" Scope="Farm" runat="server"/></span>
      17:                                     <span class="ms-globallinks">
      18:                                     <SharePoint:DelegateControl ControlId="GlobalSiteLink2" Scope="Farm" runat="server"/></span>
      19:                                     <span class="ms-globallinks">
      20:                                     <wssuc:Welcome id="explitLogout" runat="server"/></span>
      21:                     </div>
      22:                     <!--- --- --- Page Edit Toolbar --- --- --->
      23:                     <div class="console">
      24:                     <PublishingConsole:Console runat="server"/>
      25:                     </div>
      26:        </div>
      27:     </div>  <!-- end sharepointAuthoring -->
      28: </SharePoint:SPSecurityTrimmedControl>

     

    The key element here is the PermissionsString="AddAndCustomizePages" property of the SPSecurityTrimmedControl.

    This Permission levels and permissions page shows a list of all the permissions. If you refer to the Site Permissions table from the previous link we are looking for permission which do not have a read or limited access permission level. Two good candidates are either  AddAndCustomizePages or BrowseDirectories. These two have a minimum permission level of Design and Contribute respectively. As all the content managers for this site with either have a minimum of design or full control permission levels  it was ok to use the AddAndCustomizePages permission. If your authenticated users will only be a member of the ‘sitename Contribute’ group then you should use the BrowseDirectories permission.

     

    There are some alternative solutions out there which require some custom coding or making a copy of the welcome.ascx. The advantage of the solution above is that no custom code is required, just modify your master page to suit.

    I’d like to thank and reference the following blog posts for helping me solve this problem:-

    I hope you find this example helpful in your SharePoint WCM efforts!

    Gavin


    Windows 7 RTM is Ready for Download
    Randy Williams
    Category:
    8/7/2009

    For those who have been waiting for several long years for a solid, high performing client OS will be pleased to know that the final RTM (Release to Manufacturing) edition of Windows 7 is now downloadable for MSDN and TechNet subscribers.

    I myself cut over to Windows 7 back in February, and even found the beta to be good enough to use as my primary OS.  Prior to that I had been running Windows Server 2008.  If you’re looking for guidance on how I configure and use Windows 7 as a software development platform, here is a previous post that you might find useful: Building a SharePoint Development Environment on Windows 7.

    But wait, there’s more.  Sometime in the next week or two, the RTM edition of Windows Server 2008 R2 will also be available for download.  It’s definitely an early Christmas!


    Creating web part zone quick add groups
    Gavin Adams
    Category: Design;Web Content Management
    7/14/2009

    Often when creating page layouts or web part pages you will want to provide a short list or ‘priority’ list of web parts to your users.
    In this example we will:

    • Add a RSS viewer web part to a page
    • Configure the web part
    • Export the web part
    • Import the web part to the web part gallery
    • Modify the properties of the web part in the web part gallery
    • Create a basic web part page
    • Configure the web part zones using SharePoint designer
    • Add a selected web part from the the quick add group to the web part page

     

    Add the web part to the page

    The SharePoint portal that I am using is based on the collaboration portal template. Firstly we edit the home page of the portal and I will add the RSS viewer web part to one of the web part zones.

     

    Configure the web part

    Once the web part is added to the page, click on the web part edit menu to ‘modify shared web part’. Expand the appearance section and add in a custom title for the web part.

    image

    In the ‘RSS properties’ section, enter a feed URL. In this case I have added in the RSS feed URL of our Synergy MOSS blog.

    image

    Once this is completed, click ok to save the web part properties and return to the edit page screen.

     

    Export the web part

    Click on the edit menu of the web part, then click on the export link. Save the .webpart file to an appropriate location on your computer.

     

    Import the web part to the web part gallery

    Next click on the site actions menu, then site settings and then modify all site settings. From the Galleries collumn click on the Web parts link.

    image

    From the web parts gallery view click on the upload link. Then browse to the .webpart file that you saved previously and upload the file.

     

    Modify the properties of the web part in the web part gallery

    During the upload procedure you will be presented with a web part properties page. On this page are two sections that we are interested in.

    Firstly the Group section allow you to create a custom group. This will group all your custom web parts in the ‘Add web parts’ pop up window. Other default examples include search, Filters, Miscellaneous. In this example I will create a new custom group called Synergy.

    The second step will be to create a ‘Quick Add Group’. In this example below I will specify a new quick add group called ‘Synergy RSS’. I can also specify multiple quick add groups by separating the group names with semi-colons.

     

    image

     

    Create a basic web part page

    From the site actions menu click ‘view all site content’. Then click on the create link.

    image

    Create a web part page. In this case I have selected the ‘Full page, vertical’ layout and I will create the page in the Documents library.

    image

    Once the page is created, click on the page menu from the page editing toolbar and click ‘Save and stop editing’.

     

    Configure the web part zones using SharePoint designer

    Next we need to open up SharePoint designer 2007 (SPD2007). Click on file menu open site and then enter the URL for your portal.

    Once the site is open, browse to Document library and open up the web part page that we created earlier.

    The next key step is to modify the web part zone properties. I recommend using the split view in SPD2007,  then click on the web part zone, in this case the ‘Full page’ zone. This will select the appropriate selection in the code view.

    In our example the default code looks like:-

    <WebPartPages:WebPartZone runat="server" Title="loc:FullPage" ID="FullPage" FrameType="TitleBarOnly">


    The next step is to add the ‘QuickAdd-GroupNames’ property to the WebPartZone with the quick add group name that was defined earlier. Below is some example code based on this scenario.

    <WebPartPages:WebPartZone runat="server" Title="loc:FullPage" ID="FullPage" FrameType="TitleBarOnly" QuickAdd-GroupNames="Synergy RSS">

     

    Save and close the web part page in SharePoint designer.

    If you forget what this code is, you can always refer to the /_catalogs/masterpage/defaultlayout.aspx. You will notice the same property assigned to the default web part zones in this page layout.

    Interestingly there is no official MSDN documentation on this property. (http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webpartpages.webpartzone.aspx)

     

    Add a selected web part from the the quick add group to the web part page

    The next step is to simulate the experience of the end user. Return to the browser and edit the web part page that has been created.

    Click on the ‘Add a web part’ link in the ‘Full page’ web part zone.  You will now see as per below the ‘Synergy MOSS Blog’ web part listed in the Suggested web parts for Full page’ section of the Add web parts dialog window. Tick the ‘Synergy MOSS Blog’ web part and click on the add button. Then click on the ‘Save and stop editing’ button from the page editing toolbar to return the page to normal display.

    image

     

    Conclusion

    I hope that you find this a helpful article on a less than well documented feature.


    Manila – Philippines Post-Event Materials
    Randy Williams
    Category:
    7/14/2009

    I’d like to thank everyone who attended my session last week at Microsoft in Makati City. The turnout was fantastic and much better than I expected! As you noticed, this caused me to change my approach and break from the two sessions I had intended on deliver. I hope it was still useful, even though it was completely unscripted.  :)

    In any event, I know there are some who were still interested in my more technical sessions, and I apologize that I wasn’t able to go through it fully. However, as I promised, here are the links to the two PowerPoint sessions. I also have a couple people ask me about Business Intelligence, and I thought I’d also link to a session I did in May on the subject.

    Salamat,

    A Close Look Inside the SharePoint Engine

    Basic Developer Knowledge that Every SharePoint Admin Must Know

    SharePoint 2007 Business Intelligence


    First SharePoint 2010 Sneak Peek is Posted
    Randy Williams
    Category:
    7/13/2009

    On July 13, Microsoft finally released an initial look of the next release of SharePoint, dubbed SharePoint 2010. Three separate videos are available and in them you’ll get a good sense of what’s to come.

    The first video is an overall, non-technical overview of the product; another is a technical overview from an IT Pro (administrator) perspective; the third is for developers.

    There are a number of revelations that you can draw from this.  Here are just a few that you’ll see

    • The SharePoint UI will take on a radical new look. Expect it to be contain a lot of Silverlight and AJAX along with a context-sensitive, configurable ribbon.

    • Cross browser and mobile support is expected to be radically better

    • Business Data Catalog is being rebranded as Business Connectivity Services and now has full read/write and offline capabilities.

    • Office 2010 takes client integration to a whole new level with even better integration with Groove (now branded as SharePoint Workspace)

    The only drawback from this is it is only a sneak peek.  You’ll need to be patient for more. Those that are eager to learn more are strongly encouraged to attend October’s SPC in Vegas. I’ll definitely be there and am already counting the days. Expect the public beta to begin around that time.

    Enough of my commentary.  Please take a look and get ready for a whole new SharePoint world!

    http://sharepoint.microsoft.com/2010/Sneak_Peek/Pages/default.aspx


    Building a SharePoint Development Environment on Windows 7
    Randy Williams
    Category: Development
    6/30/2009

    Greetings fellow SharePoint Developers.  As a follow up to a post I made last year on Windows Server 2008 (http://www.synergyonline.com/blog/blog-moss/Lists/Posts/Post.aspx?ID=10), I figured I’d provide some guidance on the development environment I now use on Windows 7 (RC build 7100).  I also used this for some time on Windows 7 Beta 1 with great success.

    First off, let me mention that I run the 64-bit version of most versions of software.  This doesn’t really change much, but I find that the performance is just a bit better on my 4GB Dell D830 laptop.

    Here is a summary of the software I install on my host operating system:

    • 64-bit Windows 7

    • 64-bit SQL Server 2008 (I use the developer edition)

    • 64-bit MOSS 2007 (patched to SP2 level)

    • Office 2007 Enterprise

    • SharePoint Designer 2007

    • 64-bit Visual Studio 2008

    • 64-bit Virtual PC 2007 SP1 (I still use a number of virtual machines)

    • MOSS SDK (v1.5 from Apr 09 is the latest)

    There are a ton of other free utilities I like to load…I won’t list them all, but here are some of the essential ones.

    For the Windows 7 OS the install itself works just fine.  On my hardware, there are no driver problems and it installs and runs quickly. Here are the remaining steps I go through after the OS install:

    1. Create local machine accounts for MOSS. While not recommended for production, for my local dev environment, I usually go with these:

    • MOSS.Farm

    • MOSS.SspService

    • MOSS.AppPool (shared by both ssp and portal web apps)

    • MOSS.Search

    2. Install SQL Server 2008.  Nothing special here.  I usually just install the engine services (MSSQLSERVER) and the client management tools.  Make sure that you make your normal login account and a backup account a SQL Server administrator (sysadmin). This should prevent a possible occurrence of this problem I blogged about a few months ago: http://www.synergyonline.com/blog/blog-moss/Lists/Posts/Post.aspx?ID=69

    3. Install MOSS. I use SharePoint on Vista from Bamboo Solutions.  You should first start with this article to be sure that your application compatibility checker settings are temporarily turned off.  How to do this is detailed in this article: http://community.bamboosolutions.com/blogs/bambooteamblog/archive/2009/05/07/installing-wss-3-0-moss-sp2-on-windows-7-rc.aspx.  Make sure you turn this back on after your installation.

    From here, I follow these steps to get SharePoint installed: http://community.bamboosolutions.com/blogs/bambooteamblog/archive/2008/05/21/how-to-install-windows-sharepoint-services-3-0-sp1-on-vista-x64-x86.aspx.  This article also explains the necessary IIS settings.  Note: when I install, I select the setup.exe (not SharePoint.exe) from my x64 folder.  This will depend on the form of SharePoint you have.

    After the base install, I install the latest service pack. As of now, this is SP2.  Of course, WSS Service Pack first, MOSS Service pack second.

    4. After this, I add the C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\BIN as a path environment variable.  I only do this to make PSCONFIG and STSADM commands easier to execute.

    5. Create the Farm. You can optionally create the farm using the Products and Technologies Configuration Wizard.  Personally, I prefer to use PSCONFIG.EXE so that I can specify the name of my admin content database.  I normally use something similar to this command:

    psconfig -cmd configdb -create -server <local computer name> -database MOSS_Config -user <local computer name>\moss.farm -password <password> -admincontentdatabase Admin_Content

    6. After this, I then run the configuration wizard to finish the farm creation.

    7. Using Central administration, I finish the farm install.  This normally involving starting the Office Server Search, creating the SSP, and then at least one web application for a portal.

    8. Install Visual Studio 2008.  Apply SP1.

    9. Install MS-Office 2007.  Apply SP2.

    10. Install SharePoint Designer.  Apply SP2.

    11. Install various software and other utilities.  I list some of these above.  One configuration change that I needed to make to get VSeWSS to deploy solutions properly was to enable WCF HTTP Activation for the .NET Framework.  You can do this by going to Control Panel –> Programs –> Turn Windows Features on or off.  Here is the specific setting that you must enable (click image to enlarge):

    image

    12. Run Windows Update.

    At this point, my necessary software is pretty well set.  However, there is one important configuration change I make.  Since I am not always working on my local SharePoint environment, I prefer to keep these and related services in a manual state.  When I need to use the local SharePoint environment, I simply run a batch file which starts all of them.  Here are the services that I set to manual.  (To access your list of services, click Start, Run and type in services.msc)

    • IIS Admin Service

    • SQL Server (MSSQLSERVER)

    • SQL Server Agent (MSSQLSERVER)

    • SQL Server VSS Writer

    • Windows SharePoint Services Administration

    • Windows SharePoint Services Search (only if this is installed using Central Administration)

    • Windows SharePoint Services Timer

    • Windows SharePoint Services Tracing

    • Windows SharePoint Services VSS Writer

    • World Wide Web Publishing Service

    Here is my batch file (start.cmd) that I use to start all these services.

    net start mssqlserver
    net start sptrace
    net start spadmin
    net start w3svc
    net start iisadmin
    net start sptimerv3
    net start osearch

    If you also installed WSS Search, you also need this line (I place it right after sptimerv3)

    net start spsearch

    And here is the batch file (stop.cmd) I use if I want to stop all of them

    net stop w3svc
    net stop iisadmin
    net stop osearch
    net stop sptimerv3
    net stop spadmin
    net stop sptrace
    net stop mssqlserver

    If you also installed WSS Search, you also need this line (I place it right after iisadmin)

    net stop spsearch

    Of course, you may have other services that you may choose to add depending on your configuration.

    With that, I hope that gives you an idea on how to build a SharePoint development environment of your own.  Good luck!


    Speaking in the Philippines
    Randy Williams
    Category: Architecture;Development
    6/30/2009

    On July 7, I will be in Manila doing two of my more popular talks for a special MSDN presentation.  The event is being hosted by Microsoft, and it will be my first speaking engagement in the Philippines.  I’ve done some work there before and look forward to returning, especially since it’s mostly for holiday  :-).

    Below are the two sessions that I’ll be giving.  The event starts at 6pm and will be hosted at the Microsoft Offices in Makati City.  For more information or to register, please go to this link: http://msevents.ph/Event.aspx?EventID=8CBC6D915802A1D

    A Close Look Inside the SharePoint Engine (75 min)

    SharePoint is built on a number of different products and technologies. This session will give you solid architectural overview of both the product and its IIS, SQL Server and .NET Framework foundations. We’ll cover IIS Web sites, application pools, configuration and content databases, integration with Active Directory, code access security, and understanding key configuration settings in web.config. And if that isn’t enough, we’ll also unravel the mystery of how Web site virtualization and redirection actually works.

    Basic Developer Knowledge that Every Admin Must Have (75 min)

    You may have heard that SharePoint is both a development platform and a product. Its flexibility, while great for developers, can cause administrator heartburn as they try to manage what is becoming a mission critical application. This session will cover many of the must-know concepts such as features, solutions, site definitions and SharePoint scripting. We’ll also dive a bit deeper into the underpinnings such as IIS, and the global assembly cache. This session will provide key knowledge that administrators must have to effectively manage a SharePoint environment and be able to communicate with a development team.


    It’s All About Design – Perth, Australia
    Chris Bayot
    Category: Design
    6/27/2009

    I had the privilege of delivering my Design Seminar twice this week in Perth.  We had record numbers with standing room only.  Thank you everyone who took the time to attend. 

    I’ve had some requests for the slides, so I’ve posted them here.

    Whether you attended the seminar in Sydney, Canberra or Perth, the slide deck is the same.

    Aloha and see you next time!


    Post SP2 Expiration Date Fix is Available
    Randy Williams
    Category: Architecture;Development
    6/26/2009

    Microsoft has finally posted a formal resolution to the problem caused by installing SP2 in your SharePoint Services (WSS) of Office Server (MOSS) farms.  For those that missed the news a few weeks back, an SP2 upgrade causes the current license key to become inactive 180 days after the upgrade.  If this happened, the environment would become unusable by users, indicating that your "trial" has expired.  Many fixed the problem by simply re-entering their product key.

    This fix that has been released can be applied either before or after the SP2 upgrade and will ensure this problem never occurs. 

    The 32-bit version can be downloaded here: http://download.microsoft.com/download/2/F/5/2F51AB71-1325-49D2-9CB9-18DEC4780E99/office2007-kb971620-fullfile-x86-glb.exe

    The 64-bit version is here: http://download.microsoft.com/download/5/B/B/5BBD34A9-C528-42B0-8A5F-9A8997B25C32/office2007-kb971620-fullfile-x64-glb.exe

    For more information, you can read the kb article here:  http://support.microsoft.com/kb/971620


    Hawaii .NET Users Group Meeting – XNA Game Development
    Randy Williams
    Category: Development
    5/27/2009

    Our June 2009 .NET User Group event in Honolulu has been set, and we’re doing something a little different this time.  My friend and former co-former Jake from Title Guaranty will be doing a game development session on the XNA Game Development platform.  Here are the event details:

     

    Wednesday, June 17, 2009, 6-8pm

    Speaker: Jake Davis

    Topic: Introduction to XNA Game Studio 3.0 and Xbox Live Community Games

    Microsoft’s XNA Game Studio 3.0 allows independent developers to create games for Windows, Xbox 360 and Zune using managed .Net code. Xbox Live Community Games is game development community and product marketplace for the sale of XNA games on the Xbox 360.

    In this presentation we’ll demo creating an XNA game for the Xbox 360 and the process of releasing it on the Community Games platform. For those of you not familiar with the Xbox 360, we’ll have a brief overview of the console interface and the Xbox Live infrastructure.

    Jake's Bio

    Jake is a VB.Net developer specializing in creating applications with SQL Server databases. He’s currently learning C# to use in XNA development. His other interests include F1 and MotoGP racing and a love of video games. 


    See our website www.hawaiidotnet.org for location and other information on this and other events.


    SharePoint Business Intelligence Presentation at Microsoft, Singapore
    Randy Williams
    Category:
    5/25/2009

    Greetings.  Let me thank our training partner at COMAT and Microsoft for the great event today.  The turnout was well over 100 people, and I really enjoying doing the session.  For those that would like the slide deck, here it is at the link below.  Please note, I have marked some of the slides as hidden, so you may not have seen some of them in today’s session.


    SharePoint 2007 Business Intelligence


    Licensing Problem with MOSS SP2
    Randy Williams
    Category: Architecture;Design;Development;Governance
    5/23/2009

    Microsoft has just reported on their team blog that there is an unexpected licensing problem with SP2 for MOSS.  The problem is that resets the licensed status of the product.  This means that 180 days after you apply the service pack, the license will expire, and the system will be inaccessible by clients.  Obviously, not good.  If this does happen, it will not harm any data, and this only means that you need to reactivate the product.  Of course this is still important enough so if you’ve installed SP2 already, make sure you address this before it expires. 

    The problem does not apply to WSS. 

    Today, there are a two known courses of action you can take:

    1.  You can manually re-enter the license product key as instructed by this KB article.

    2.  You can wait for a hot fix that should be available shortly

    I suspect that this will be fixed in one of the upcoming cumulative updates.


    Slide Deck from Singapore {one} Nation Event
    Randy Williams
    Category:
    5/23/2009

    For those that attended the Microsoft {one} Nation event in Singapore on Saturday, 23 May, 2009, here are the slide decks for the two talks I gave:

    A Close Look Inside the SharePoint Engine

    Basic Developer Knowledge that Every SharePoint Admin Must Have

    Let me also take a moment to thank the audience for all their questions, Microsoft for hosting, and many of my fellow MVPs such as Tian-An Tan, Loke Kit Kai, Steve Sofian, and others who helped put on the event.  It was great fun.


    SharePoint 2010 Preliminary System Requirements
    Randy Williams
    Category: Architecture;Development
    5/13/2009

    Today a notice came out on the SharePoint team blog that I can now talk about.  (BTW: honoring an NDA can be difficult since there is so much that I’d like to share but sorry I just can’t).

    Anyhow, there were three items mentioned in the post:

    1) SharePoint 2010 will be 64-bit only. 

    That much is not a big secret.  Exchange 2007 did that route a couple years ago.  This will require customers have 64-bit compatible hardware and a 64-bit compatible OS.  Many of my customers have made this transition already, but I know of many that will not have this in place by the time 2010 is released.  This is not only an issue in production environments, it’s also a big deal for development ones.  You see, there’s a bit a pickle that Microsoft is putting in.  Here’s what I mean:

    SharePoint development today really needs to be done in a local environment.  That is, each developer should have their own dev environment in which they work.  Many that I know do their development in a Virtual PC 2007 running 32 bit guest operating systems (Virtual PC does not support a 64-bit guest OS).   Some of us have moved to Windows Server with Hyper-V as I blogged about last year.  This works okay since Hyper-V supports a 64-bit guest OS but it’s not an ideal platform especially if you do development on a laptop (as I do). 

    Unless something changes, MED-V seems to be the direction that Microsoft is going with the future of Virtual PC in Windows 7 meaning there will not likely be a new version of Virtual PC.  With no support for a 64-bit guest OS, that means Virtual PC 2007 will not be running SharePoint 2010.  Hence, your dev environment strategy needs to change.  Microsoft’s answer today is to use Windows Server 2008 for your development host OS.  Some of my colleagues have opted to move to VMWare Workstation, which unfortunately is not a free product and run their virtual machines in there.

    2) SharePoint 2010 will require 64-bit Windows Server 2008 or Windows Server 2008 R2 (currently in beta). 

    Got any 2003 machines?  It’s time to start planning the upgrade if you haven’t already.  Back to my development environment concerns, will it run on 64-bit Windows 7?  Apparently not.  Maybe Bamboo will also come out with a utility that lets you run it as with SharePoint on Vista today.

    3) SharePoint 2010 will require 64-bit SQL Server 2005 or 64-bit SQL Server 2008.

    Ah…so not only do you need to upgrade the WFE and application servers, you also need to do your database servers as well.  There will be no support for SQL Server 2000. 

    A final thought on how this will affect upgrades.  The basic idea is that those that are 32-bit or running Windows Server 2003 will not have an in-place upgrade option.  Make sure you factor this into your capital budgets for 2010 if you are planning on upgrading!

    Read the full article here:  http://blogs.msdn.com/sharepoint/archive/2009/05/07/announcing-sharepoint-server-2010-preliminary-system-requirements.aspx


    Resolving No Results When Issuing a MOSS Search
    Randy Williams
    Category: Web Content Management;Architecture
    5/7/2009

    I’ve seen this problem come up a few times, so I thought I’d share a couple of quick things to look at when troubleshooting this search problem with MOSS.  The problem was that when issuing a MOSS Search using the “This Site” or “This List” filter, no results would be returned.  However, when issuing the search against “All Sites” would work just fine. 

    Just to check off the basic things to look at, the following was fine:

    1) The crawler (default content access) account did have permissions to all content sources

    2) The content source URL for the SharePoint web application was listed

    3) There are no errors in the crawl log that suggest that an access denied or other error occurs

    4) The WSS Search and MOSS Search services are running correctly.

    5) There are no other problems with the SSP.

    Again, search results did show up using the All Sites, so this isn’t an IFilter or other problem with the index or query service. 

    The solution involved two different changes that I made:

    1) Make sure the content database has a Search Server specified.  You can set this inside Application Management –> Content Databases –> (Properties for your content database).

    2) Make sure that the URL specified as a content source matches the default URL defined in your Alternate Access Mappings (AAM).  For example, if you create a web application and do not specify a host header, the URL will become http://servername, where servername is the NetBIOS name of the computer.  Many organizations opt to create CNAME aliases inside DNS and use an internet friendly URL such as http://moss or http://portal.  If you do this, you should also set up an Intranet zone URL for the friendly name.  However, when configuring the content source, use the default URL.  (Note: There are other ways to accomplish this such as extending the Web Application which will create additional AAM entries for you, but you should still ensure that the default zone is the one you specify in your list of content sources).

    Hopefully this will help save you some time and solve a nagging problem.


    Speaking in Singapore
    Randy Williams
    Category:
    5/7/2009

    I’m on my way to Singapore for 12 days.  While there I’ll be teaching our MOSS 2007 Development course the week of May 18, 2009.  After my class, I have two events at which I’ll be presenting.

    The first is on Saturday, May 23 and is part of the Microsoft {one} Nation 2009.  (Note: As of this writing, they have not posted Saturday’s schedule yet).

    For this event, I have two sessions that I gave to Windows Connections back in March:

    9:00am: A Close Look Inside the SharePoint Engine

    10:30am: Basic Developer Knowledge that Every Admin Must Have

     

    The following Monday, May 25, I’ll be presenting at Microsoft Singapore.  My topic is on Business Intelligence, and here are the details of the session:

    Increasing Business Intelligence with SharePoint:  Making Better Decisions Faster

    In 2008, for the third consecutive year, Gartner research ranked Business Intelligence applications number 1 among technology priorities.  Most organizations realize that they need a BI system, but few realize that Microsoft Office SharePoint Server (MOSS) coupled with SQL Server can deliver a powerful solution at a reasonable cost.  In this presentation, we will demonstrate the full array of MOSS BI features including the Business Data Catalog, Excel Services, Key Performance Indicators, and Dashboard pages, and how they leverage SQL Reporting Services and SQL Analysis Services.  We’ll show practical examples of how you can use these tools to build effective and user-friendly BI systems.

    I don’t have the slides finished yet.  I’ll post these right before or after the event.

    Aloha!


    Looking for .NET Programmers in Honolulu
    Randy Williams
    Category: Development
    5/4/2009

    For .NET Developers that will be in Honolulu on May 29, 2009, I invite you to join me in becoming a preview panelist.  Your role will be to help review .NET projects that a group of Kalani High School students have been developing.  This will be a great way to give back a little to the community and ensure our next generation of talent has what it takes to succeed in this industry.  This will be held at the Manoa Innovation Center.  Each panelist will need to commit to three hours, either from 9am to noon or from 1 to 4pm.

    For more details, click here: http://www.hawaiidotnet.org/Lists/Announcements/DispForm.aspx?ID=9.  Hope to see you there!


    Hawaii .NET User Group Meeting - Using the Silverlight Toolkit
    Randy Williams
    Category:
    5/4/2009

    The next Hawaii .NET User Group meeting has been set.  Here are the event details:

    Meeting: Wednesday, May. 13, 2009, 6-8pm

    Speaker: Calvin Schrotenboer

    Topic: Using the Silverlight Toolkit

    Silverlight 2 was released in October 2008. Key improvements over Version 1 include the ability to program all code behind in C# or Visual Basic.NET (instead of only JavaScript) and a few built-in user controls (buttons, image controls, list boxes, etc.). However, there were only a limited number of these controls.  The remaining controls can be found in the Silverlight Toolkit ( http://www.codeplex.com/Silverlight/).  There are currently three parts to the Toolkit: controls, charting and theming.  Notable controls include the TreeView, AutoCompleteBox, DockPanel and WrapPanel. 

    This presentation will provide an overview of the Silverlight Toolkit followed by some detailed examples of Silverlight Charting.

    Cal's Bio

    Cal is a C# developer with experience in building application front ends for SQL Server databases. He also teaches programming classes (Advanced C#, ASP.NET, WPF, Silverlight, WCF,  SQL Server 2008) at Foothill College in Los Altos Hills and Microsoft Network Administration (MCSE) classes at Mission College in Santa Clara. Cal has written numerous articles on Silverlight for Microsoft which appear on www.devx.com. His outside interests include travel and photography (http://www.travelswithcal.com). Recently, a particular interest has been Silverlight Deep Zoom photography examples of which can be seen at http://www.travelswithcal.com/deepzoom/ Photographs of the Obama Inauguration can be seen at http://www.travelswithcal.com/deepzoom/obamainauguration/

    As always, free pizza, drinks and door prizes will be given away. Hope to see you there.

    http://www.hawaiidotnet.org


    Windows 7 RC is Available
    Randy Williams
    Category:
    4/30/2009

    For those like me that have been running Windows 7 beta for some time will be happy to know that the release candidate (RC) is now available for download.  Those that are MSDN and TechNet subscribers can download it now.  The general public will need to wait until May 5.

    Those that choose to hold off should be warned that the current 7000 beta build is set to timebomb on July 1, 2009.  The RC is set to timebomb on March 1, 2010.

    I’ve started my 64-bit download of the Ultimate version.  It’s 3.1GB, so it will be a while before it finishes.  Following Microsoft’s suggested guidance, I will be planning on a fresh install, rather than upgrading my beta install.  Such is life on the edge.  :)


    WSS 3.0/MOSS 2007 SP2 is released
    Randy Williams
    Category: Architecture;Governance;Development;Design
    4/30/2009

    I’m a couple days late getting this out, but if you haven’t heard yet, SP2 has finally been released.  As before, there are 32- and 64-bit editions and separate editions for WSS and MOSS.  For those running language packs, make sure you apply this as well.  The build number for SP2 is 12.0.0.6421.

    For those running MOSS, it is very important that you apply WSS SP2 before you apply the MOSS SP2.  Also, do not run psconfig or the Products and Technologies Wizard after the WSS update.  This guidance is the same as with SP1 and the July 08 Infrastructure Update. 

    For those looking to build a new WSS or MOSS farm, you can get the SP2 slipstreamed with the install.

    There are a number of improvements, that you can read these from the Microsoft SharePoint Team blog here:  http://blogs.msdn.com/sharepoint/archive/2009/04/28/announcing-service-pack-2-for-office-sharepoint-server-2007-and-windows-sharepoint-services-3-0.aspx

    One improvement that I do want to call attention to is the ability to have SharePoint intelligently recognize and utilize the read-only status of a SQL Content database.  This is great in recovery scenarios or other situations where you want to ensure changes to a content database cannot be made.  Let me show you what I mean.  Here is a normal announcement item that I have selected, and you can see the normal operations from the context (ECB) menu:

    image

    Here is how it looks when I’ve set the database to Read-only.  (Note: I only set the database to read-only from SQL Management Studio.  I didn’t do anything else such as issue an iisreset or recycle any app pools). 

    image

    Cool.  Prior versions would just throw an exception.  I haven’t played with it much yet, but have noticed a few web parts that do not render too well, and depending on how a custom (or third party) web part is written, it may cause the page to not render at all.  Obviously something to test.

    So, go and do some reading on the changes in SP2, and then download and start playing with it in your test/dev environments.  Have fun!


    Upcoming Design Seminars – Honolulu, Hawaii
    Chris Bayot
    Category: Design
    4/29/2009

    I’ll be speaking at a couple of seminars during the first two weeks of May, so I thought I should share the details.

    The first will be an encore presentation of a Seminar I presented in Sydney, Australia last month, to be held in Canberra, Australia this time.  Click here for those details.

    The second seminar I have the privilege to present will be at the SharePoint User Group in beautiful downtown Honolulu.  Here are the details for that one:

    Tuesday, May 12th, 2:00 PM – 4:00 PM

    Davies Pacific Center
    841 Bishop Street
    Room 118A
    Refreshments will be served   (That always gets people there.)

    Please register at the Hawaii SharePoint User Group Website: http://sharepointhawaii.com/

    Topic

    With the big news that Microsoft Office SharePoint Designer 2007 is now free, I will share some hands-on tips to help you take advantage of this powerful tool.  I will discuss using SharePoint Designer to customize Master Pages, Page Layouts, and Data View Web Parts and of course will be happy to address questions from you.  I’ll also discuss some of repercussions of using the tool so that you have the big picture of the impact on your SharePoint site.


    Upcoming Design Seminars – Canberra, Australia
    Chris Bayot
    Category: Design
    4/29/2009

    I’ll be speaking at a couple of seminars during the first two weeks of May, so I thought I should share the details.

    The first will be an encore presentation of a Seminar I presented in Sydney, Australia last month.  Dimension Data Learning Centers had their largest turnout ever with more than 100 attendees.  That just goes to show how timely Design topics are right now.  The second event will take place at the SharePoint User Group meeting in Honolulu, Hawaii.  Details can be found here.

    Here are the details for the encore event in Canberra:

    When

    7 May 2009

     

    Where

    Dimension Data Learning Solutions, Canberra
    Level 10, ActewAGL House
    221 London Cct
    ACT 2600

    Phone : 02 6263 7900
    Fax : 02 6230 4292
    training@didata.com.au

    Cost

    FREE

    Details

    DDLS would like you to attend our free seminar featuring SharePoint 2007. Whether you want to admit it or not, it all comes down to design and functionality.
    In this seminar we will discuss the evolving role of the SharePoint Webmaster and include discussions on job roles and career opportunities for the SharePoint Designer.
    Come and investigate the unique skills that are required by Webmasters working in the SharePoint space. We will be covering:
    * How Master Pages and Publishing Page Layouts work and how to go about creating and customising them
    * Site Hierarchy and Taxonomy as it relates to SharePoint
    * How to leverage Document Libraries for Document Management, Content Types, Features and Site Definitions just to name a few.
    This session will be presented by Chris Bayot from Synergy. Chris has spent more than seven years as a contract Web Designer and since the release of MOSS 2007, has become one of the top talents in the area of SharePoint branding and customization. Chris currently teaches the Synergy MOSS 2007 Design and Customization course at DDLS around Australia.
    The session will include some practical demonstrations as well as opportunities for questions and discussion.
    If you are a Web Master, a SharePoint Designer, Site Administrator, Site Contributor or are simply a SharePoint enthusiast, this seminar is for you!

    Agenda:
    5:15pm Registration
    5:30pm Welcome and Introduction
    5:35pm It's all about Design in SharePoint
    6:30pm Q & A session


    Demystifying MOSS 2007
    Milan Gross
    Category: Architecture;Governance
    4/22/2009

    Much of the difficulty that organizations have with MOSS 2007 stems from some common misunderstandings about how it should be architected and used. In this seminar I delivered in Australia, I revealed 10 of these misconceptions and attempted to clarify them for attendees. The full slide deck is here:

    Demystifying SharePoint


    Microsoft SharePoint Server 2010
    Randy Williams
    Category:
    4/17/2009

    We have been calling it v.4, v.Next, SharePoint 14, Office Server 14, and others.  While they are still not publically releasing details on feature improvements, they have at least decided on the official name for the product:  Microsoft SharePoint Server 2010. 

    Notably missing from the title is the term Office.  Rest assured that this does not mean that Office client integration is going away:  this is still a key part of the product and will no doubt improve.  According to Tom Rizzo, the reason is “lots of folks associate the name Office with the Office client.”  While that’s true to a point, it was also a selling argument speaking to the server-half of the Office client.  In any event, it will take time for me to drop the MOSS acronym from my lexicon.

    Read more details from the Microsoft team blog:  http://blogs.msdn.com/sharepoint/archive/2009/04/14/microsoft-sharepoint-14-is-now-microsoft-sharepoint-2010.aspx


    Concerns with Reporting Services and SharePoint Integration (Follow Up)
    Randy Williams
    Category: Architecture
    4/14/2009

    In my rant a couple weeks ago, I was going off on my inability to build a simple integrated SQL Services Reporting Services (SSRS) solution in a SharePoint farm.  In summary, the concern I had was that I was unable to keep a two-server SharePoint farm simple by having a dedicated application server running SharePoint and a dedicated server running SQL Server.  After getting some much needed corrective guidance from my friend Wen He, I am now able to build this.  The odd thing is that I did try to do it this way, but it wasn’t working for me at that time.

    I don’t think I would have gotten off on this track if there had been better documentation out on MSDN regarding this.  However, the fault is still mine, and I apologize if I led anyone astray with my previous post.

    Here is a summary on how the farm is initially configured:

    Server 1: SharePoint application server.  It runs all application services related to SharePoint.  This includes Web Application, Search, Central Admin, etc.

    Server 2: SQL Server 2008

    To get SSRS running, I have installed SSRS on Server 1.  On this server, I did not install any of the SQL database engine services (i.e. MSSQLSERVER), only SSRS.  When configuring SSRS, I stored the integrated Reporting Services databases (ReportServer and ReportServerTempDB) on Server 2.  The SSRS web services are also running on Server 1, allowing Server 2 to remain a dedicated SQL server and nothing else.

    Over the next few days, I will be working on an article that walks through in detail how I did this.  This should simplify the process for anyone else that needs to do something similarly.


    Troubleshooting SharePoint Connection Problems to SQL Server
    Randy Williams
    Category:
    4/8/2009

    When creating a new SharePoint Farm using the SharePoint Products and Technologies Configuration Wizard, you are prompted to enter in a SQL Server name and the name of your configuration database.  For a variety of reasons, you may be unable to connect to SQL Server to create the new farm database.  The most common issues include:

    1. The farm account is unable to login to the SQL Server.

    2. Network protocols are not configured correctly on the SQL Server.  For example, Named pipes, TCP/IP sockets, etc.

    3. Your web front end (WFE) you are creating the farm from cannot resolve the SQL Server name.

    4. A firewall in between the WFE and the SQL server is blocking packets.

    5. The farm account has insufficient permissions in SQL Server to create the farm.  (The account needs the securityadmin and dbcreator fixed server roles as a minimum.)

    If the wizard encounters an error, it aborts and stores the progress it made in the log folder (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\LOGS).  And those without a strong SharePoint or SQL background may have time trying to wade through it to find the real problem.

    Before I get into deeper troubleshooting discussion, please make sure rule out the two most obvious reasons:  1) Really make sure that the MSSQLSERVER (or whatever named instance you’re using) service is actually running.  2) Verify that you have enabled at least one network protocol in SQL Server Configuration Manager.  By the way, Shared Memory does not count since this only works for connections from the same server. 

    So with that, I’d like to share a couple of the utilities that I use that can help quickly troubleshoot these types of problems.  The first of these is the good, old-fashioned ODBC utility that’s been around for generations.  You can find it in Administrative Tools –> Data Sources (ODBC).  This is helpful as it allows you to verify if steps 1-4 above are the problem.  Here’s a quick walk through how I use it:

    To start, I log in to the WFE using the account designated as a farm admin.  (Note: This is the same account that you specify as your database access account when you tried to create the farm.)  Then, launch the ODBC utility and you’ll be greeted with this initial screen:

    image

    From here, I click on Add and then choose the SQL Server from the list of drivers as shown below.  Note, this may be listed on the bottom, and if you have installed the EN-US (English – United States) edition of SQL Server, it will be listed after all of the Spanish-sounding driver names.  ?Habla Driver para o Microsoft Visual FoxPro?  :) 

    image

    After clicking Finish, you’ll be prompted with another wizard.  It starts off looking like this

    image

    From here, I just type in anything for the name.  For example “Test SQL”.  For the Server, I usually enter in the NetBIOS name of the server.  You can also enter in the fully-qualified domain name (e.g. sql.company.com).  Testing it with the IP address will help you identify if it’s a name resolution problem (#3 in the problem list above).  Click Next.

    image

    I then usually click Next since I use Windows NT authentication almost all the same (it’s definitely the easiest and most secure way).  Note, this does assume that you’re physically logged into the WFE using an account that has a SQL login account.  As I mentioned above, this is often the farm admin account.

    image

    If all is working you should see this screen above.  Assuming there aren’t any routing or name resolution problems, it should also come up in a second or two.  If you check the Change the default database to option and click the dropdown arrow for the list, you should see all the databases on the server.  If you don’t see all databases, the login account is probably not a member of the securityadmin fixed server role.

    So what if you cannot connect with the ODBC utility?  Well, that takes us to the second tool, the SQL Server Client Network Utility.  Unfortunately, there’s no shortcut in the Start Menu for this, so I always invoke by just going to Start –> Run and typing in cliconfg and hitting Enter as shown here:

    image

    After this starts, you’ll be presented with the initial screen which looks like this

    image

    The purpose of this utility it to tell this workstation (which is the client) which network protocol it should use when establishing a connection to a SQL Server.  As with any network communication, the client and the server must agree on a protocol.   The idea is that you can create an alias and override the default settings.  I do this by first clicking on the Alias tab.  This gives me these options:

    image

    From here, I enter in the NetBIOS name (or whatever name I provide to the Products and Technologies Configuration Wizard) for the Server alias.  I’ll then usually select Named Pipes as the Network library.   The Connection parameters (i.e. the Server name and pipe name) are automatically filled in, and you rarely need to change these.  Click OK to save this Alias.  I then return back to the ODBC utility and try again.  This time, ODBC will pick up the settings for the alias and try only Named Pipes.  If that fails, I know there is a named pipes problem.  I often then go back to the Client Network Utility and then try TCP/IP.  With TCP/IP Sockets, it will default the port to 1433 (which along with 1434 are the default TCP ports that SQL Server uses…if you’ve configured a different port for SQL Server, you would need to change it here).  When the modified Alias is saved, try again using ODBC.

    Note: I recommend against using an alias as a permanent setting unless you really need it. Most of the time, I only use an alias to troubleshoot where a problem is and then remove it when I’m done and the problem is resolved.

    These troubleshooting steps are also helpful if your farm that has been working suddenly stops and gives you a cannot connect to the configuration database error.  With that, that should give you a pretty good idea how to troubleshoot where most problems occur.  For advanced troubleshooting, I have been known to bust out Network Monitor and auditing failed logins, but that’s well beyond the scope of this article.  Good luck and happy troubleshooting!


    Regaining admin access to your 2008 SQL Server
    Randy Williams
    Category: Architecture
    4/8/2009

    Of of the new additions to SQL Server 2008 is that a local administrator does not automatically become a sysadmin (system administrator) within SQL Server.  This is a significant change from many prior versions of SQL (at least back to 6.0 days and probably 4.2 as well).  The purpose is to better isolate who are the Windows admins and who are the SQL dba’s.  For production environments, this is a great feature but can cause problems in a dev environment as I’ll explain.

    When you run through a SQL Server 2008 install, you are asked to define which accounts should become a member of the sysadmin fixed server role.  This is fine in most cases, provided you are paying attention and remember to set this accordingly.

    Here’s a pickle I got myself into recently:  I had a SQL Server 2008 machine that was a member of an old Active Directory domain that no longer existed.  The SQL instance was running fine, and I just needed it to join a different domain.  Without thinking, I removed it from the old domain and joined it to the new domain.  No problems here.  Because the MSSQLSERVER service was running under a local system account, the SQL Service started up and ran just fine after this.  (Note: if my SQL Server had been running under an old domain account, I would have needed to change the service to run under local system).  However, when I tried to actually do anything in the SQL Server, I had no admin privileges.  Whether I used a domain administrator or the local administrator login, I was stuck with very limited access.

    Doing some research directed me to a not so obvious TechNet article which has two workarounds to solve this problem:

    1. Detach all current databases, reinstall SQL Server (and thereby associate new sysadmins), and then re-attach all databases.  What a pain.  Fortunately, number 2 was easier.

    2. Stop the MSSQLSERVER (or whatever the instance name is) service and start it up in single user mode.  When you do this, you are allowed a single connection, and anyone who is a local Windows admin will become a sysadmin for this one connection.  With this one connection working, you can grant whatever new domain or local accounts to the sysadmin role.  When you are done, stop and start the service as normal.  If you’re unsure how to start SQL in single user mode, check out this article: http://technet.microsoft.com/en-us/library/ms345416.aspx.

    I am now making a mental reminder for all test environments that I build to make sure that I grant the local administrator account sysadmin permissions.


    RunAs Radio Session Posted
    Randy Williams
    Category:
    3/30/2009

    Aloha.  I am back on island after a mainland circuit to Orlando, LA, Phoenix and Las Vegas.  It was a fun, but busy trip.  And coming back to Hawaii is always nice.  :-)

    The session on RunAs Radio that I recorded a few weeks ago has been posted.  You can listen to the interview at http://www.runasradio.com/default.aspx?showNum=102.  The session is a quick 30 minutes, and I answer questions such as Enterprise Search, SharePoint as an Internet-facing solution, and the business value of SharePoint.  Take a listen and let me know if you have any comments.


    Displaying a Shared Calendar Outside of the Site Containing the Calendar List
    Chris Bayot
    Category: Design
    3/26/2009

    As you probably know, the List View Web Part is limited to displaying a list that is contained within a specific site.  Therefore, if I'm working at the top level of a site collection and want to display a view of a list that exists in a child site, there is no way to accomplish that out of the box.  The Data View Web Part (DVWP) allows us to create custom Web Parts that will work to display information in a list format and can be used as a solution to this problem, but what if we want to display a calendar in calendar view outside of the site containing the calendar?

    It's common, for instance, for my clients to maintain a Shared Calendar in a Human Resources child site that tracks employee leave dates.  They then want this calendar displayed in the root site giving all employees easy access to the shared leave calendar.

    With SharePoint Designer there is a fairly simple solution.

    First, create a new .aspx page containing the Calendar Web Part:

    1. Open the site containing the list in SharePoint Designer. 
    2. Create new aspx page by selecting File then New then ASPX and click OK.
    3. Open the Web Part Task Pane by Selecting Task Panes then Web Parts.
    4. Add a Web Zone to the page by selecting New Web Part Zone at the bottom of the Web Part Task Pane.
    5. Select Calendar from the Web Part List and click the Insert Selected Web Part button.
    6. Save the page (preferably in a Document Library) and preview it in the browser.

    You will now see the calendar displayed in the Web Zone on the page.  However, you can see that the page is not formatted appropriately yet.

    image

    Next, you'll need to apply the appropriate style sheet.  For our example, we'll work with default.master.

    1. Open the associated master page.  Master pages can be found in the folder list in _catalogs/masterpage (Master Page Gallery)
      For our example, expand _catalogs, expand masterpage then double click on default.master
      Do NOT check out the master page if prompted as you will simply be copying some code from the page.
    2. In the <HEAD> tag of the master page you will see the following code:
      <SharePoint:CssLink runat="server"/>
      <SharePoint:Theme runat="server"/>
      Copy the code and paste it under the <TITLE> tag in the heading of your new .aspx page:

      image

    You'll notice red squiggly lines under the code indicating a problem.  The problem is that the required Tag Prefixes are missing since this code typically falls on a master page.  Therefore the next steps are to add the appropriate Tag Prefixes to the top of the .aspx page.

    1. Return to default.master and scroll to the top in code view.
    2. Copy the code found immediately after <%Master language=C#"%> through the final %> as shown below:

      image 
    3. Return to your new aspx page and add a closing bracket after <%@ Page Language="C#" and then replace the remaining code through the final %> with the code you copied from default.master.

       image
    4. Save your page and preview it in the browser to see the styles applied:

      image

    The final step is to display our new page at the top level of the site collection.  Because we have a simple .aspx page with no master page attached, we can easily display the page anywhere in SharePoint using the Page Viewer Web Part.

    1. Copy the URL of the page you just created from the address line in the browser where you are previewing your page.
    2. Navigate to the top level of the site collection (or wherever you want to display the calendar).
    3. Create a new Web Part Page by selecting View All Site Content from the Quick Launch (left hand) navigation then selecting the Create button.
    4. Under Web Pages select Web Part Page.
    5. Give your page a title such as LeaveCalendar, select a Layout Template such as Full Page, Vertical and a Document Library to store the page, then click Create.
    6. On the new page select Add a Web Part then scroll down to the Page Viewer Web Part (typically in the Miscellaneous section), select it and click Add.
    7. Select open the tool pane then paste the link of your new page into the URL box.
    8. In the Page Viewer Web Part Task pane expand Appearance and under Should the Web Part have a fixed height? select Yes then enter an appropriate number (approximately 600 pixels should work).

    And there you have it - a calendar display that's available anywhere you can add a Page Viewer Web Part!


    SharePoint Designer to Become a Free Product?
    Randy Williams
    Category:
    3/20/2009

    This has been a rumor for a few weeks now, but it appears to be true and now safe to publish.  As of April 1, 2009, SharePoint Designer (SPD) will become a free download.  As I’ve heard, those that have valid licenses for the product will be upgraded to Expression Web.  This doesn’t surprise me much, but does raise some interesting questions if this is true: 

    How will this affect the adoption of the product?  How will organizations address the training aspect?  Does this mean that the design and customization capabilities of the product will finally extend to users outside the IT group?  And, if so, what implications does this have to the performance and stability of the SharePoint environment?

    By this last question, what I mean is that SPD is pretty powerful and if you’re not careful, you can introduce performance (by customizing pages) and stability problems by breaking web parts or screwing up other layout issues on the page.  Fortunately, this risk is isolated to single webs in most cases, but I can see IT teams getting further inundated by help desk requests from people who have messed up their webs. 

    Or, perhaps this is all just an April Fool’s Day joke?  We’ll see soon enough.  It has made it to Wikipedia, however:  http://en.wikipedia.org/wiki/Microsoft_Office_SharePoint_Designer


    Concerns with Reporting Services and SharePoint Integration
    Randy Williams
    Category:
    3/20/2009

    (13 April 2009 Update:  I’ve had some guidance on this and am able to implement a solution that I addresses my concern.  See here for details.)

    I’ve been a big fan of SQL Reporting Services (SSRS) for quite some time.  I remember seeing it the first time during a PDC conference back in 2001 and predicted it would be the Crystal Reports killer.  That has mostly come true, and the product has evolved quite a bit through releases in SQL 2005 and now 2008.

    Beginning with the SSRS release in SQL 2005, Microsoft has provided a solution to integrate it with SharePoint (either WSS or MOSS).  For those running both SSRS and SharePoint, it makes to do this as the web GUI for SSRS is not very user friendly and does overlap quite a bit with basic functionality that SharePoint just does better.  Here is just a quick list of major benefits I see when running SSRS in SharePoint integrated mode:

    • Ability to store and secure Report Definition Language (RDL) reports directly within SharePoint document libraries
    • Ability to store shared data sources within a connection library
    • Ability to use the SSRS web parts to display reports within a dashboard, team site, or some other content page
    • Vastly improved UI complete with SharePoint content types to manage the reports, subscriptions, snapshots, etc.

    While you have these benefits, there is a real architectural concern I have when you implement your SSRS system within SharePoint.  Before I get into this, however, let me add a caveat by saying I like keep things simple.  And by this, one principle that I always try to follow is isolate services across servers in your environment.  With SharePoint, this has always been pretty easy.  With most small and medium server farms that I build, you have the opportunity to dictate which services run on which servers. 

    For example, take a small farm.  It’s common to have a single web front end (WFE)/application server and one SQL Server.  This model works well, is easy to manage, and ultimately keeps for a clean, simple environment.  For larger farms, you can even isolate more by dedicated application services such as index, search, Excel Services, etc. to a single machine. 

    Related to this, when I work with my customers and students, I have always recommend keeping SQL Server dedicated on one or more servers.  Maybe I’m just being anal here, but I’ve just found it so much easier this way.  Whether this SQL Server is dedicated to SharePoint or shared among other application needs (say CRM or other line-of-business apps), I don’t have a preference.  Most DBAs would agree with me here, I think.

    With that, let me share with you my specific concern.  Let’s say you have a small SharePoint farm as I describe above: a single WFE/application server and one dedicated SQL Server 2008.  Let’s say now that you want to leverage these integration benefits and install SSRS on your SQL Server for SharePoint Integration.  As you get into the literature on TechNet and SQL books on line on how to do this, there’s an ugly secret you’ll encounter: you must install SharePoint on the SQL Server and join it to your farm.  Ugh!

    Let me be clear.  You first install SSRS on the SQL Server.  (You do have to also install IIS for this; that’s not too bad.)  You then install SharePoint on the SQL Server, patch it to the same build, and then join it to the farm that is housed on the other WFE server.  Technically, this SQL Server now becomes another WFE in the farm, although you don’t need to actually configure network load balancing or anything like that.  Basically, it’s an inert WFE.  And only then can you get SSRS integrated properly into SharePoint.

    I should add that you do have another alternative:  You can install SQL Server and SSRS on your WFE server, but I don’t think this is a better solution.

    So, this is my gripe.  I cannot keep the nice and simple design I’ve recommended for years.  I have now created a complex environment, complicating patch management, disaster recovery procedures and further blurring the lines between OS/Web admin and SQL DBA duties.  Another annoyance, is that from an architectural point of view, I can’t see why this is necessary.  You see, SharePoint connects to SSRS through web services that are hosted on the SQL Server.  Shouldn’t this be sufficient to integrate these together.  That is, when the web part holding a report of mine needs to render, it makes the necessary web service call to have the report rendered which is then displayed.  Seems pretty simple to me.

    If I am overlooking something, or if anyone has anything to add, I’d love to hear your comments.

    (13 April 2009 Update:  I’ve had some guidance on this and am able to implement a solution that I addresses my concern.  See here for details.)


    Managing Site Collections and Content Databases
    Randy Williams
    Category:
    3/20/2009

    Even though SharePoint v3 (2007) has been out for more than two years, when I talk to customers and students, there is still confusion over site collections and content databases.  In particular, the confusion seems to be most centered around in which database will a new site collection be stored. Some have told me that it is done in a round-robin fashion whereas others have said it’s based on site collection size.  Actually, neither of these are true.

    Before I give you the right answer, let’s make sure we understand the basic relationships and rules:

    1. A content database is a container for site collections.  In fact, the content database’s only purpose is to hold site collections.

    2. A content database can store zero or more site collections. 

    3. A web application can have one or more content databases.

    4. A site collection cannot span content databases.

    5. A content database cannot span web applications.

    When a new site collection is provisioned (whether by Central Administration, STSADM, or the SPSiteCollection.Add() object model method), it selects the database that is “most available.”  Let me clarify most available by a simple example.  Let’s take a situation where four content databases exist for a web application.  We’ll call them Blue, Green, Red and Yellow.  Here is how they appear in central admin:

    image

    First note that they are ordered in alphabetical order.  This is always the case.  To calculate the most available, go through each database that is marked as started and perform this simple calculation: Site Level Warning minus Current Number of SitesIn our case, we have this:

    Blue_Content 2
    Green_Content 3
    Red_Content 4
    Yellow_Content excluded (marked as Stopped)

    Now if all of these databases have exceeded their Site Level Warning, the same operation is performed, but instead it uses: Maximum Number of Sites minus Current Number of Sites.

    At the end, the database with the highest positive number is considered the most available.  From above, we can clearly see this is Red.  Note that Yellow is skipped because this database has been taken offline (shown as Stopped in the Database Status column).  If there are ties, the one that is alphabetically first will be selected.

    As you can see, the logic is simple.  It does appear to be round robin, but this is only true if the warning and max thresholds are all set to the same value.  And since the logic has nothing to do with the size of the site collection, it is up to the SharePoint admin to monitor and adjust as needed.  With that, let me give you some tips that can help you manage these better.

    Tip 1

    You can use the STSADM –o createsiteinnewdb command to create a new site collection in a new content database.  This will first create a new content database, and then create a new site collection inside it.  Note: This cannot be used to create a site collection in an existing content database.

    Tip 2

    If you need to specify that a site collection be stored in a specific database, you can just mark all of the databases but the one you want to use as Offline (or Stopped).  Offline does not mean offline in the SQL Server sense, it just means that new site collections will not be stored there (as with Yellow above).  Any site collections that are currently located there function as normal.

    Tip 3

    In SP1, Microsoft added a handy command to STSADM.  It is called mergecontentdbs.  While it can do merging of content databases, it’s easier to think of it as allowing you to move one or more site collections from one database to another.  So, taking the example above, I could easily move a site collection from Blue to Red to balance it out.  Here is a good blog article by fellow MVP Todd Klindt that talks about how to use this command:  http://www.toddklindt.com/blog/Lists/Posts/Post.aspx?ID=53.  Note: It is recommended that you lock your site collections that are to be moved to read-only or no access prior to moving. 


    Windows Connections Orlando 2009 Materials
    Randy Williams
    Category: Architecture;Development
    3/18/2009

    Greetings.  This was a great couple of days in Orlando, and the Hyatt Grant Cypress was a beautiful venue for the event.  The Windows Connections team is fantastic, and they do run a very professional event.  One of the advantages to events like this is that they are much more intimate than something like TechEd.  I’m not putting down huge events like that, but with Connections, the interaction between speakers and attendees is so much better.  In between breakouts, I was able to have several lengthy talks. As a speaker I enjoy this, and I’m sure the attendees feel the same way.

    A funny thing happened yesterday during a session Dan Holme and I were getting ready to give a session on SharePoint strategy, management and value.  The hotel had a fire alarm, and we were “forced” to give the session on the beach.  It worked out pretty well actually as you can see:

    image

    Part of the humor (and irony) that in all my years in Hawaii delivering classes and seminars, I have never presented on the beach.  :)  And, as I was typing this, another fire alarm just went off.  But really, you gotta believe me…it is a nice hotel!

    Okay with that, here are the PowerPoint decks that I am now releasing.  For those that were unable to make it, I will be recording #1 and #2 and making them available for Connections Online.  When those are ready, I’ll let you know.

    #1.  A Close Look Inside the SharePoint Engine

    #2.  Basic Developer Knowledge That Every SharePoint Admin Must Have

    #3.  Fitting SharePoint Into Your Organization’s Disaster Recovery Plans


    Windows Connections Sessions
    Randy Williams
    Category: Architecture;Development
    3/13/2009

    I’ve had some requests, so I just wanted to provide you all with the abstracts from the sessions I’ll be doing at the Windows Connections conference next week in Orlando.  My sessions are on Tuesday (March 17) and Wednesday.

     

    WSH04: A Close Look Inside the SharePoint Engine

    SharePoint is built on a number of different products and technologies. This session will give you solid architectural overview of both the product and its IIS, SQL Server and .NET Framework foundations. We’ll cover IIS Web sites, application pools, configuration and content databases, integration with Active Directory, code access security, and understanding key configuration settings in web.config. And if that isn’t enough, we’ll also unravel the mystery of how Web site virtualization and redirection actually works.

    WSH08: Basic Developer Knowledge That Every SharePoint Admin Must Have

    You may have heard that SharePoint is both a development platform and a product. Its flexibility, while great for developers, can cause administrator heartburn as they try to manage what is becoming a mission critical application. This session will cover many of the must-know concepts such as features, solutions, site definitions and SharePoint scripting. We’ll also dive a bit deeper into the underpinnings such as IIS, and the global assembly cache. This session will provide key knowledge that administrators must have to effectively manage a SharePoint environment and be able to communicate with a development team.

    WSH05: Fitting SharePoint Into Your Organization’s Disaster Recovery Plans

    As more content gets stored in SharePoint, its importance to the organization grows. Is SharePoint part of your Disaster Recovery Plan? If it should be, and you’re not sure where to start, this is the session for you. We’ll cover numerous scenarios and make sure you have the tools and techniques to recover your data. Out-of-the-box capabilities and third-party solutions will be covered.

     

    I will be publishing my slides after the event has completed.  Stay tuned for these.


    Guest on RunAs Radio
    Randy Williams
    Category:
    3/9/2009

    On Thursday, March 12, I will recording a 30 minute spot for RunAs Radio.  For those that aren’t familiar with the program, it is a weekly Internet-based talk show geared to IT professionals working with Microsoft technologies.  They have been broadcasting for nearly 2 years.

    The broadcast date should be sometime in late March or early April.  Their web site which allows many different ways to download the programs can be found at http://www.runasradio.com.  Please check them out!


    MVP Summit Update
    Randy Williams
    Category:
    3/9/2009

    Note: I had a publishing problem and am reposting this article.  This was written March 3, 2009.

    Greetings all and aloha from Seattle.  The weather is the usual up here in the Pacific Northwest.  That is, rainy and cool.  The SharePoint team had a great paintball fest on Sunday at Ft. Lewis (south of Tacoma).  The 45 or so of us went through about 48,000 rounds of ammo!  And most of it splattered us in the face, fingers, arms, legs and other more sensitive areas.  :)  Overall it was great fun and a nice bonding experience.  Thanks to Ted Pattison, Andrew Connell, Dave Pae and many others who helped to sponsor the event.  Here is one of the many pictures that was taken (I am in the front to the left with the bright blue pullover):

      clip_image001

    For the conference itself, we are ready to start day two as I type this.  Content is mostly on Office 14 (both client and server).  Due to NDA, I cannot share many details yet.  As soon as I am able, rest assured, I will.  For now, let me say that there are some great improvements and to be honest, a few disappointments, but it’s still early alpha, so there’s hope for some changes before anything ships. 

    I’ve also had a few talks with the MSDN and TechNet teams.  As a trainer, the documentation element is so important, and Microsoft realizes the improvements they need to make for those IT Pro and Developer groups that need to either get up to speed or dive deeper into some of the product niches.  In particular, I’ve been discussing figuring out ways to provide content that is relevant to both admin and developer groups.  This has always been a concern of mine, and having a background in each, I’ll do all I can to help them address this knowledge gap.  With SharePoint, it’s very hard to be exclusively one or the other, and it’s more important than ever for us to be able to communicate with each other.

    Along those lines, I will be doing three talks at Windows Connections in Orlando on March 17 and 18.  Two are directly related to this admin/dev knowledge area at Windows Connections in Orlando.   My first topic is “A Close Look Inside the SharePoint Engine” and the second is “Basic Developer Knowledge that Every SharePoint Admin Must Have.”  I did a prelim version of these in February at the .NET User Group.  I have updated the content and hopefully polished up on the actual talk.  Lastly, I’ll also be doing a talk on Disaster Recovery.  For those that are not able to make it out to Florida, there have been discussions on providing a recorded version of these sessions.  I’ll keep you posted when I know more about this.


    Displaying Unauthorized 401 Error on Windows Server 2008 (IIS 7)
    Randy Williams
    Category: Architecture
    2/26/2009

    A client of mine asked a question that had been perplexing me for a while.  I finally decided to to some hard research on it.  By hard research, of course, I mean use Google.  :)  Seriously, it was not an easy solution to find.

    Here was the problem:  We wanted the browser client to receive some form of login error message if user did not log in correctly.  As most everyone knows, with Windows authentication set for a web application, the three-strike rule is in effect.  That is, you get three tries to login before it errors out with an HTTP 401.1 error.  Putting on my non-technical, end-user hat, if I can’t login in correctly, I would expect some type of error message displayed.  With Windows Server 2003, here is the error message you get (I’m sure this will look familiar to most of you):

    image

    The problem with SharePoint running on Windows Server 2008 (i.e. IIS 7), no such message is displayed.  You try to log in and after the third attempt, you literally get a blank screen in IE (no screen shot necessary, I think).  Examining the actual server response in Fiddler, you can see that IE is getting this response, but it is not displayed (regardless of the Show friendly HTTP error messages setting):

     

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
    <HTML><HEAD><TITLE>Not Authorized</TITLE>
    <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
    <BODY><h2>Not Authorized</h2>
    <hr><p>HTTP Error 401. The requested resource requires user authentication.</p>
    </BODY></HTML>

    I did try this on several live and test builds running IIS 7, and it was consistent across the board.  The problem was the server.  Honestly, I did notice this a few months ago, but it was just a minor annoyance, and I just ignored it.  (There are just not enough hours in the day to research every little thing that comes up.)

    What happened is that the error handling changed in IIS7.  Specifically, there is now an <httpErrors> section that you can place in your web.config that governs how HTTP errors are handled.  Note: This is separate from SharePoint’s (or more precisely ASP.NET’s) <customErrors> section found within <system.web>.

    You can read about the detailed options of this new element from this IIS.NET post:  http://www.iis.net/ConfigReference/system.webServer/httpErrors.

    Ok, so the solution to the problem is that I needed to add a new section to the web.config for the web app.  Here are the settings I added to the <Configuration> element:

    <system.webServer>
       <httpErrors errorMode="Custom" existingResponse="Auto" >
        </httpErrors>
    </system.webServer>

     

    (7 Aug 09 Update): Make sure you add this after the <configSections> element. I usually put it in between <configSections> and <SharePoint>

    When testing out the site, I now got this error (good grief).

    image

    This error means that you are trying to change settings that are locked within IIS.  To allow the override for these <httpErrors> settings, I also needed to run a small command to unlock this section.  Here is the command:

    appcmd unlock config -section:httpErrors

    (Note: appcmd.exe is located in the C:\Windows\System32\inetsrv folder)

    Finally, with these settings in place, the problem is solved.  Here is the error message I now get upon a failed login:

    image

    For reference, here is the article I found that helped me out with these web.config settings:  http://forums.iis.net/p/1152751/1883849.aspx

    If anybody knows of a cleaner/simpler workaround, I’d love to hear it.


    Managing your farm backup sets
    Randy Williams
    Category:
    2/24/2009

    Many small-to-medium-sized organizations rely on catastrophic backups using the stsadm –o backup –directory command.  This does a complete farm backup, including each web application’s content database, along with the configuration database, certain registry keys, and index files.  Most administrators use a scheduled task to automate the farm backup.  Unfortunately, one of the drawbacks to this is that it doesn't provide any way to manage the backup sets. 

    For example, imagine that your farm backup consumes 100GB of space, and that you are running full daily backups which is common for farms of this size.  After a month, you will have amassed 3TB of backups.  Each of these is stored in a folder with the naming convention sbprxxxx (e.g. sbpr0001, spbr0002) to uniquely number each backup in the set.

    Most administrators just manually go into these folders and delete old backup sets.  Ok, this is a minor annoyance since you must remember to do it. A more pressing concern is that an important XML file named spbrtoc.xml is now out of sync with the backup set folders.  You see, each backup set is referenced as an SPHistoryObject node in this xml file, and this file is processed by both STSADM (using the backuphistory operation) and the central admin GUI when trying to do a farm restore.  When you just delete folders without updating the spbrtoc.xml file, you confuse SharePoint and yourself about which backup sets are available for restore.

    Those more savvy SharePoint administrators will correctly point out that you can just manually open the XML file and identify the backup you really want to restore and grab the backup ID (stored as a GUID in the SPId element).  I agree, and if you must do this, by all means, please do it.  However, my point is that you need to know how to do this, and you must remember to do this.  Typically, when you are doing a farm restore, it is a 2am operation.  You’re tired, probably frustrated (and maybe pissed off), and you just want to get it done.  Or, worse yet, you have a novice SharePoint admin who is attempting to do the restore.  In either case, it’s not the time where you want to add more complexity to something that’s already complicated enough.

    The solution to this that I recommend is to employ a simple script that can both archive old backup folders and keep the spbrtoc.xml file in sync.  The script that I have been using recently comes by way of a nifty post from Dave Hunter that you can find here:  http://www.davehunter.co.uk/Blog/Lists/Posts/Post.aspx?List=f0e16a1a%2D6fa9%2D4130%2Dbcab%2Dbaeb97ccc4ff&ID=94

    Dave’s solution is to use a PowerShell script that allows you to specify the number of days of backup history you want to keep.  So, if you are doing weekly backups, and you want to keep 3 weeks worth, you would specify a value of 22 (21 + 1 to be safe) days.

    Two things that I’ll point out that might frustrate some of you newbie PowerShell folks:

    1. Per Dave’s blog, make sure you run the Set-ExecutionPolicy Unrestricted one time to enable unsigned scripts to run on that machine.

    2. If the script is located in a folder or a filename that contains a space, you’ll have execution problems from powershell.exe.  The solution is to use the following workaround in your batch file: 

    powershell.exe “& ‘c:\backup scripts\ArchiveFarmBackups.ps1’”

    Lastly, let me add that there are also VB Script versions of this that you can also schedule using cscript.  Microsoft provides us one here on this TechNet post:  http://technet.microsoft.com/en-us/library/cc967309.aspx

    With this, you should never have to remember to clean up your old farm backups, and you’ll always ensure that your folders and XML table of contents file remain in sync.


    File not found errors when restoring a site collection
    Randy Williams
    Category: Architecture;Development
    2/23/2009

    When working with a client recently, we had an idea to provide a test instance of a site collection.  This would be a simple backup and restore of the (root) site collection into a separate managed path.  In this case, we wanted the path /test.  Sounds pretty simple, and I’ve done this in the past without incident.

    Here is what I did:

    I first issued a site collection backup using the following command:

    Stsadm –o backup –url http://localhost –filename d:\backups\sites\root.bak

    I then created an explicit inclusion managed path for test in my primary web application.  I also created a new content database and made sure this was the only “online” content database.  This new content database was necessary as you cannot restore a duplicate site collection into the same content database as there are GUID conflicts.  Ok, I am now ready for the restore command.  Here is the command I ran:

    Stsadm –o restore –url http://localhost/test –filename d:\backups\sites\root.bak

     

    After a short wait, I am greeted with the expected command completed successfully message.  Great.  Should be ready to go, right?  Well, I hit the http://localhost/test URL and was greeted with this error message:

    image

    What happened?  At first I wasn’t sure.  I checked Event logs, SharePoint URL logs (even setting them to verbose), but there wasn’t much to pinpoint the problem.  I even took a cursory glance at the site inside SharePoint Designer, and it looked okay.  No obvious files seemed to be missing.  I also tried application pages such as /_layouts/settings.aspx and got the same error.  To validate the backup, I restored into the (root) site collection for a new web application, and it worked perfectly.

    I then decided to see if any of the sub webs were working.  This site collection was a pretty generic one based on the collaboration portal site definition (part of MOSS).  Curiously, the only sub web that worked was the Document Center.  All the others (Search Center, News, Reports, etc.) would return the same error.  What this told me was that it looked to be a publishing site problem as the Document Center site is not a publishing web (i.e. the Publishing feature is not activated).

    My guess was that there was a path problem, but wasn’t sure where.  It was here that I opened the question up to my MVP colleagues.  Vincent Rothwell and Gary Lapointe offered great advice on the exact problem. 

    The problem is that each publishing page (e.g. default.aspx) points to the wrong page layout.  This happens because the link is to the original layout in the (root) site collection.  So, for example, if I look at the configured page layout for http://localhost/test/default.aspx, it would show http://localhost/_catalogs/masterpage/DefaultLayout.aspx which is in the (root) site collection, and I would expect it to say http://localhost/test/_catalogs/masterpage/DefaultLayout.aspx.  I would expect the restore command within STSADM to handle this, but, clearly it does not. 

    So now that we understand the problem, what’s the solution?  Employ one of Gary Lapointe’s nifty STSADM add-ins.  This one in particular I used was gl-fixpublishingpagespagelayouturl.  It goes through all of the page layout settings for all publishing pages and corrects the page layout setting by setting the relative URL.  It worked like a charm with this syntax:

    stsadm –o gl-fixpublishingpagespagelayouturl –url http://localhost/test –scope Site


    If you also use the –verbose switch, you can get all the nitty-gritty details.  Here is a snippet of the output that explains what it does:

    Progress: Begin processing site '/test'.
    Progress: Begin processing web '/test'.
    Progress: Begin processing Pages/Default.aspx.
    Progress: Current layout set to http://localhost/_catalogs/masterpage/defaultlayout.aspx, /_catalogs/masterpage/defaultlayout.aspx.
    Progress: Changing layout url from "http://localhost/_catalogs/masterpage/defaultlayout.aspx, /_catalogs/masterpage/defaultlayout.aspx" 
    to "/test/_catalogs/masterpage/defaultlayout.aspx, /test/_catalogs/masterpage/defaultlayout.aspx"
    Checked in item: Home (Pages/Default.aspx)

     

    As you can see, it removes the absolute reference and stores the correct relative reference for the layout page.  Once this is done, and after you run an IISRESET, all is working perfectly.

    After thinking about this, I now realize why this worked before:  I did it in WSS which doesn’t have publishing pages.  Now we both know how to do it in MOSS, even with publishing sites.


    SharePoint Conference 2009
    Randy Williams
    Category:
    2/4/2009

    Mark your calendars.  Word has just come out that there will be a SharePoint Conference (SPC) this year.  The date will be October 19-22 and will be held in Las Vegas.  Those that attended the March ‘08 conference in Seattle know that this will prove to be jam packed with sessions covering administrative, development and CIO-level needs.

    And, do I need to remind you that “SharePoint 14”, the next release, is around the corner?   You won’t find any other event happening this year that provides you with the knowledge you need to architect, implement and manage a SharePoint solution.

    Very early-bird registration cost is $899.  And with the economic decline here in the states (and Vegas in particular), expect hotel costs for the area to be more affordable than ever!

    There aren’t a lot of details known yet, but there is a single page now posted at http://www.mssharepointconference.com/Pages/spc2009.aspx

    Hope to see you there!


    Materials from .NET User Group Session in Jan 09 are posted
    Randy Williams
    Category:
    2/2/2009

    On January 21, 2009, I spoke to a packed crowd at the Hawaii .NET Users Group in Honolulu, Hawaii.  The topic covered two important architectural subjects that are relevant to SharePoint administrators and developers. 

    Part 1 is entitled A Close Look Inside the SharePoint Engine.  Part 2 is Basic Developer Knowledge that Every SharePoint Admin Should Have.  Slides and video from the event have now been posted.  Click here for the session details and materials.


    Revised Version of SPDisposeCheck Released
    Randy Williams
    Category:
    1/29/2009

    A fresh version of SPDisposeCheck (v1.3.1) has been just released as published by Paul Andrew.  This utility helps validate that your SharePoint code follows best practices when it comes to releasing objects in the object model.

    Having a tool like this is quite a benefit as even seasoned SharePoint developers either miss a small section or have trouble interpreting all the little things to do as documented in the authoritative MSDN reference on managing disposable objects.  A related blog that is also helpful can be found here.

    For those newbie SharePoint developers, you should realize that not all objects in the object model are fully .NET managed code.  In particular, the SPSite and SPWeb class—two key classes used in SharePoint development—contain unmanaged code.  This means that there are memory management issues with garbage collection if you do not manually dispose of these.

    For example, in this harmless little section of code lurks a memory leak:

    SPSite site = new SPSite("http://localhost");
    SPWeb web = site.OpenWeb("teamsite");
    web.ApplyTheme("Belltown");
    web.Update();
    
     
    The problem is that the site and web objects are not properly released when they go out of scope (unlike regular .NET objects).  As you’ll read in the MSDN article reference above, they recommend calling the object’s dispose method or have it automatically called by the using clause.  These two forms are shown here:
    SPSite site = new SPSite("http://localhost");
    SPWeb web = site.OpenWeb("teamsite");
    web.ApplyTheme("Belltown");
    web.Update();
    web.Dispose();
    site.Dispose();
     
    using (SPSite site = new SPSite("http://localhost"))
    {
        using (SPWeb web = site.OpenWeb("teamsite"))
        {
            web.ApplyTheme("Belltown");
            web.Update();
        }
    }
     
    If it were just this easy, it would be pretty simple to remember ourselves.  Unfortunately, there are more complex situations, so the rule is that you cannot always dispose of a SPWeb or SPSite object.  (For example, if you obtain a handle to these through either SPControl or SPContext, you should not dispose of them.)
     
    So, back to the SPDisposeChecker tool.  This command-line program will go through your compiled executable and list where it thinks that a memory leak is hiding.  Keep in mind, that it’s not that smart, and there may be false positives (as the program’s output frequently reminds us.)  If you have a .pdb file located with the assembly, it can even give you the line of code where the problem may be. 

    I decided to run it against the simple application above.  Here is the verbose output:
     
    Note: This tool may report errors which are not actually memory leaks, otherwise known as false positives.
    Further investigation should be done to identify and correct real errors.
    It is designed to assist developers in making sure their code adheres to best practices for memory 
    allocation when using SharePoint APIs.
    Please see the following for more information:
    http://blogs.msdn.com/rogerla/
    http://msdn2.microsoft.com/en-us/library/aa973248.aspx
    http://msdn2.microsoft.com/en-us/library/bb687949.aspx
    ----------------------------------------------------------
    
    
    ID: SPDisposeCheckID_110
    Module: Demo2.exe
    Method: Demo2.Program.Main(System.String[])
    Statement: site := new Microsoft.SharePoint.SPSite("http://localhost")
    Source: C:\DemoFiles\Ch05\Demo2\Program.cs
    Line: 14
    Notes:      Disposable type not disposed: Microsoft.SharePoint.SPSite
         ***This may be a false positive depending on how the type was created or if it is disposed 
    outside the current scope
    More Information: http://blogs.msdn.com/rogerla/archive/2008/02/12/sharepoint-2007-and-wss-3-0-
    dispose-patterns-by-example.aspx#SPDisposeCheckID_110
    ----------------------------------------------------------
    
    
    ID: SPDisposeCheckID_120
    Module: Demo2.exe
    Method: Demo2.Program.Main(System.String[])
    Statement: web := site.{Microsoft.SharePoint.SPSite}OpenWeb("teamsite")
    Source: C:\DemoFiles\Ch05\Demo2\Program.cs
    Line: 15
    Notes:      Disposable type not disposed: Microsoft.SharePoint.SPWeb
         ***This may be a false positive depending on how the type was created or if it is disposed 
    outside the current scope
    More Information: http://blogs.msdn.com/rogerla/archive/2008/02/12/sharepoint-2007-and-wss-3-0-
    dispose-patterns-by-example.aspx#SPDisposeCheckID_120
    ----------------------------------------------------------
    
    Total Found: 2
    
    ----------------------------------------------------------
    
    Modules Checked: 2
    ----------------------------------------------------------
    Demo2.exe
    ----------------------------------------------------------
    
    Modules Ignored: 0
    ----------------------------------------------------------
    ----------------------------------------------------------
    
    Methods Ignored: 0
    ----------------------------------------------------------
    
    
     
    You can see what I mean about the disclaimer.  It did, however, pick up the two issues with the SPSite and SPWeb objects. I also like the fact that it directs you to the section to where the leak is discussed (next to More Information).
     
    Important Note:  You should only run SPDisposeCheck in your development environment and not on your production servers.
     
    The last point I want to make is you should be practical about this.  If you are building software that will be sold commercially or iterates though thousands of SPSite and SPWeb objects, of course, you want to do all you can do make your code solid.  On the other hand, if you’re just developing a simple utility that runs periodically against just a few sites, the actual risk here is very small.  My overall advice is to develop solid code as a habit, but there’s a pragmatic side of me that realizes you sometimes just need to get something out quick and dirty.  Just use your best judgment.

    You can download SPDisposeCheck here:  http://download.microsoft.com/download/B/4/D/B4D279A0-E159-40BF-A5E8-F49ABDBE95C7/SPDisposeCheck.msi


    Deploying a SharePoint Extranet Solution
    Randy Williams
    Category:
    1/19/2009

    In a recent project I had some unique requirements for an extranet solution I was building.  I am usually involved in intranet facing projects, so this taught me a few things.  Doesn’t every project?

    Here were some of the requirements:

    1. SSL (of course) is required

    2. Extranet access for a couple hundred people scattered around the country.  We decided on Basic authentication due to the mixture of client types and the need to integrate with Office (which ruled out FBA).

    3. Need to ensure enterprise search is functioning

    4. Ensure https redirection is automatic.  For example, if user accesses http://portal.synergy.com, it must automatically redirect to https://portal.synergy.com.  This portal.synergy.com domain was not the real domain, but the one I will use as the example for this article.

    These are pretty straightforward requirements, but there were a number of issues that surfaced did not have obvious solutions.  In this article, I discuss the issues I had, and how I worked around them. 

    When creating the primary web application, I configured it to use SSL upon creation.  It looked similar to this screen shot (click to enlarge):

    image 
    Figure 1: Creating Initial Web Application

     

    You’ll notice that you cannot select Basic when you create it, so I chose NTLM (Windows NT Lan Manager) for now. 

    From here, I created and bound the SSL certificate to the Web Site in IIS and set the Require SSL checkbox in IIS.  I then created a root site collection.  At this point, the web site came up just fine, and requirement #1 was in place.

    Next step is to get basic authentication in place.  This is pretty easy and can be done from the authentication providers link within Application Management.  I changed the default zone (at this point, the only zone) to now use Basic authentication.  The modified configuration now looks like this:

    image 
    Figure 2: Configuring Basic authentication

     

    Requirements #1 and #2 are now done.  Unfortunately, setting this to basic auth introduced a small problem.  Unfortunately, when crawling content, the SharePoint search engine is unable to authenticate using basic authentication.  This means that I would not be able to implement search.  Big problem, acutally.  Thanks to my colleague Milan Gross who pointed this out, this was a pretty easy workaround.  What I did is created another zone that would be used only for searching.  This would not be exposed to users since it’s just an internal mapping, and it would be configured to use NTLM.

    To do this, I first extended the https://synergy.portal.com web application to a new zone, and I configured this the intranet zone.  Here is how it looked prior to saving:

    image 
    Figure 3: Extending to intranet zone for crawling

     

    When configuring the content sources, I made sure that intranet Url http://spserver:80 was the Url crawled, not the default one (https://portal.synergy.com).  A simplified view of the content sources looks like this:

    image 
    Figure 4: Content sources

     

    Issuing a full crawl and then a few test searches, I was happy that requirement #3 was now functional.

    The final step was to make sure http to http redirection (requirement #4) was working.  Since we were using Windows Server 2008 for the WFEs, we used the nifty HTTP Redirect part of IIS 7.  However, this combination of requirements made it a tad more complex.  You see, I didn’t have an IIS Web Site that accepts port 80 requests on the http://portal.synergy.com url.  That is, my IIS web site bindings only shows port 443 as you can see here:

    image 
    Figure 5: Bindings for primary web application (IIS Web Site)

     

    I tried a number of combinations to get it to work the way I wanted, but in the end, the option that I went with was extending the web application yet another time, this time to http://portal.synergy.com.  I opted to place this into the Custom zone.  Here’s how the extended web was created:

    image 
    Figure 6: Extending to custom zone for http to https redirection

     

    I then went to the authentication settings, figuring I probably want this to also use basic auth.  So, for this new custom zone, I made the settings match that of Figure 2 above.  I then went into IIS and enabled IIS redirection.  Here’s how the redirection screen was configured:

    image 
    Figure 7: Configuring IIS redirect

     

    Note: For those looking for IIS Redirect in IIS 7, you must specifically install it as a Role Service from Server Manager.  It is not installed automatically.

    At this point, I thought I was done, but I realized a peculiar problem.  When signing in, it was redirecting properly, but was also requiring me to log in two different times.  Here is the login screen that I would always get twice:

    image 
    Figure 8: Basic auth sign in screen

     

    So I was close.  What I’m guessing was happening is that is first authenticating to the http site instance (the custom zone).  It then is redirecting per IIS to the https site instance (the default zone).  Upon this redirection, the credentials aren’t preserved; hence, I need to log in again.  After thinking about this a bit, I thought, “Hey, what if I just set the custom zone to allow anonymous?”  I really don’t want to allow anonymous users, but all I care about is getting the initial redirect to work to the default (https) zone.  Here is where I would then do the authentication.  I was a bit skeptical at first thinking I am opening up a security hole, but it seems to work just fine.  I’ve done a number of tests and can’t see a problem.

    I also realized that if I have basic auth enabled on an http connection, the username and password credentials are being delivered across the wire unencrypted.  Very bad.

    Ok, so here is how the custom zone is now configured.  Notice that I only use anonymous access and clear Integrated Windows and Basic authentication.

    image 
    Figure 9: Configuring custom zone to use anonymous

     

    From this point, all four requirements are met, and the solution works like a charm.  Hopefully this post gives you some ideas and pointers on how you can do something similar.  Good luck to you all.


    BDC Application Definition Import Failed
    Randy Williams
    Category:
    12/21/2008

    There are a number of reasons why a BDC Application Definition File (ADF) may fail to import.  Sometimes you don’t even get a useful error message as to why which can be frustrating to troubleshoot.  However, one would think that if you export a working ADF and then import it back in, all should be fine.  Think again.

    Every time I have exported an ADF, it fails to write out the complete XML.  Actually, it just fails to write out a single character which is easy to overlook and will cause an error when you then import it back in.

    The import error message you get will be something like this:   Application definition import failed. The following error occurred: Unexpected end of file has occurred. The following elements are not closed: LobSystem. Line 613, position 12.  Fortunately, in this case, it is a good error message and easy to find the source of the problem.

    If you look closely at an exported ADF shown below in Visual Studio, you’ll notice the export process fails to write out the final > (greater-than) character at the end of the file.  This causes the XML to be malformed and not import correctly. 

    image

    Simply adding the missing character resolves the problem.


    Auto Populating a List that Has a Business Data (BDC) Column
    Randy Williams
    Category:
    12/20/2008

    One of the many features of the Business Data Catalog (BDC) is the ability to pull data from external databases or Web Services and cache this data within columns in a SharePoint list.  This is accomplished using a Business Data column.  While this does offer many advantages, one of the drawbacks is how to populate the list with items that point to the corresponding row in your external system.

    Let me walk through what I mean.  Let’s say I have a contact list in SharePoint that stores some basic information about customer points of contact.  In it I want to store the contact’s name, the company name, phone number and address.  It idea is to have it look something like this:

    image

     

    Let’s say that much of this information lives in a CRM system, so it would be a lot of duplicate work to maintain both sets of information.  Specifically, I want to pull the company name, address, city and state from CRM and align it with my contact and his/her phone number.  This is where a Business Data column comes in very handy as it allows you to merge in data from an external system and marry up with SharePoint content.

    So, we proceed in adding a Business Data column to the list and removing our duplicate columns.  (For more details on how to do this, check out the second half of my article on SharePoint magazine linked here.)  After adjusting the All contacts view, here is the empty list that is ready to populate:

    image

    This is where the trouble lies.  For me to work with this, I need to create a new item for every contact, and this can be tedious.  And for each contact add, I have to then match it up to the company.

    What would be great is if the empty list of customers could pre-populated with current customers from CRM.  All I would then need to do is quickly edit each one to add the contact name and phone number.  That’s what we’re talking about in this post: a simple console app to pull the current customers defined in BDC, create and link each one up in this contact list.

    I have already written the code, so let’s see how it works.  First off, we need to get our project references set.  This solution will require three specific references: Microsoft.Office.Server.dll, Microsoft.SharePoint.dll, and Microsoft.SharePoint.Portal.dll.  I have also added these using clauses to the top of my C# application:

    using Microsoft.SharePoint;
    using Microsoft.Office.Server.ApplicationRegistry.Runtime;
    using Microsoft.Office.Server.ApplicationRegistry.Infrastructure;
    using Microsoft.Office.Server.ApplicationRegistry.MetadataModel;
    
    Once this is place, we can start to code. We start off by connecting to the SharePoint list using an SPList object.  This basic code to do this is shown here:
    SPSite site = new SPSite("http://portal.synergy.com");
    SPWeb web = site.OpenWeb("teamsite");
    SPList customerList = web.Lists["Customers"];
    

    Once I have my SPList handle, I then need to connect to BDC and execute the method instance which will return all customers.  Here is the code for that:

    //Connect to named SSP
    SqlSessionProvider.Instance().SetSharedResourceProviderToUse("DefaultSSP");
    
    //Connect to our LOBSystemInstance
    LobSystemInstance synergyData = ApplicationRegistry.GetLobSystemInstanceByName("SynergyData");
    
    //Connect to our customers entity
    Entity customers = synergyData.GetEntities()["Customers"];
    
    //Connect to our finder method for customers
    MethodInstance getCustomers = customers.GetFinderMethodInstance();
    
    //Execute finder method
    IEntityInstanceEnumerator results = (IEntityInstanceEnumerator ) customers.Execute(getCustomers, synergyData);
    

    The results variable shown in the last line above is our returned collection of rows.  This IEntityInstanceEnumerator object works like an ADO.NET DataReader, and it is very easy to iterate through the rows.  What we now need to do for each row is create the item and link it to the matching row for this entity.  Here is the code to do that:

    //iterate through each row returned and add a new item
    while (results.MoveNext())
    {
        SPListItem item = customerList.Items.Add();
        item["Customers_ID"] = EntityInstanceIdEncoder.EncodeEntityInstanceId(new object[] { results.Current["CustomerID"].ToString() });
        item.Update();
    }
    
     
    For the new item, I set the value for the Customers_ID field.  This is an additional field added by the Business Data column that refers to the Identifier for the entity.  The contents of this field is an encoded form of the columns used as the identifier.  This may not be clear, so let me try to detail this out.  Below is the identifier for the customer entity as spelled out in the ADF.  It’s just a single column called CustomerID.  This is also the primary key column in the database.  An identifier can be multiple columns, but for this simple example I only have one.
    <Identifiers>
        <Identifier TypeName="System.String" Name="CustomerID" />
    </Identifiers>

    For an item in SharePoint to match up to the corresponding row in the database, it need an specially encoded form of the identifier’s value.  We use the EncodeEntityInstanceId method to encode the CustomerID column value into the correct format.  If you’re curious, here is how the encoded form looks: __bk4100c4001400a5009500b400.  There is also a decode method called DecodeEntityInstanceId, but we don’t need to use it here.  If we had multiple columns for the identifier, we would just need to list each one for the object[] array that the encode method uses as its input parameter.  Overall, it’s pretty simple.

    The last bit of code is just our usual housekeeping for the SPSite and SPWeb objects.

    //release memory for site and web objects           
    site.Dispose(); 
    web.Dispose();
    

    Now that the code is done, we run the program, which creates the new items.  Here is how it initially looks:

    image

    That doesn’t look good—it looks like we have no data loaded.  This is expected since we only populated the Customer_ID link field.  If we click the refresh icon next to the Company column header, it looks much better since this is what copies and stores the current data through the BDC into the list.

    image

    At this point, we can just edit the list in datasheet mode as shown here to quickly fill in the contact name and phone number:

    image

     

    With that, I hope you have a better understanding of how Business Data columns are added to a list and how you can automatically populate a list based on content from your Business Data Catalog.  For those running this application, keep in mind that it must run directly on a SharePoint Web Front End since it uses the object model to connect.

    Happy Holidays!


    Developing a Web Part to Automatically Login using Single Sign On
    Randy Williams
    Category:
    12/10/2008

    During SharePoint deployments, one of the requests I get from time to time is how to leverage Single Sign On (SSO) capabilities to automatically sign in to external web applications.  For example, perhaps you have an web-based time keeping system that your company uses.  Every time you log into the system, you must supply the obligatory username and password in the login like this sample form here:

     

    image
    Figure 1: Typical forms authentication web page

    Most organizations have many of these internal or external applications where this is an inconvenience.  The annoying part is that you might be in an out of the system several times a day, and each time you must log in.  Wouldn’t it be great if you could host a page within SharePoint that automatically signs you in to these systems?  Well, that’s exactly what we’ll do in this article. 

    Let’s first see how it looks. 

    Taking our Time Reporting System system, here is how our Time Reporting System looks like within a custom developed Web Part.  This is the initial view as credentials are pulled from the SSO database and passed to the time reporting application.

    image
    Figure 2: Custom Web Part – automated sign in

    Once authentication is complete, you are presented with the default page for the application:

    image
    Figure 3: Custom Web Part – login complete

    The concept here is not much different than the Page Viewer Web Part.  The one big difference, however, is the automatic login.  Here are two other examples using ebay and Amazon (click images to enlarge):

    image
    Figure 4: Automatic login to ebay

    image
    Figure 5: Automatic login to Amazon

    Solution Architecture

    The basic idea is that the custom code generates an HTML form that is then programmatically posted using JavaScript to the application’s login page.  The user’s credentials, which are pulled from the Single Sign On database, are embedded into the form.  Here is a sample HTML form that is generated:

    <HTML>
    <body onload='document.login.submit();'>
    <form name='login' id='login' method='post' action='http://localhost/login.aspx'>
    <input type='hidden' name='txtUsername' id='txtUsername' value='testuser' />
    <input type='hidden' name='txtPassword' id='txtPassword' value='password' />
    </form>
    </body>
    </HTML>

    As you can see, this form contains the username called testuser that is automatically passed to the login.aspx page.  Depending on the web application, there may be additional hidden variables that may be needed.  I’ll address this in just a bit.

    The custom code for this solution consists of a Web Part and a SharePoint application (.aspx) page.  The Web Part is basically a shell that generates an IFRAME (just like the Page Viewer Web Part) and sets the source (i.e. src attribute) to the application page.  The application page (stored within the _layouts virtual directory) is what calls into the SSO database, pulls the current user’s credentials and generates the HTML form.  The Web Part also contains a few shared personalization settings as shown here:

    image
    Figure 6: Web Part settings

    These settings are delivered from the Web Part to the application page via the querystring.  As you can see, they make the Web Part more generic so that is can be used across a number of systems.

    Solution Code

    Now that you have an idea of how the solution works, let’s take a look at some code.  We’ll start with the Web Part, but there is not much to look at here.  Let’s start by introducing one of the six personalization settings.  This one shown here is for the login URL:

    [Personalizable(PersonalizationScope.Shared),
     WebBrowsable(true),
     WebDisplayName("Enter URL for the Login page"),
     WebDescription("Enter URL for the Login page")]
    public string Url
    {
        get { return _url; }
        set { _url = value; }
    }
    

    Here is the code within CreateChildControls. 

    //Generate querystring to pass data to application page
    StringBuilder querystring = new StringBuilder();
    querystring.Append("?url=" + HttpContext.Current.Server.UrlEncode(_url));
    querystring.Append("&uc=" + HttpContext.Current.Server.UrlEncode(_userIdControlName));
    querystring.Append("&pc=" + HttpContext.Current.Server.UrlEncode(_passwordControlName));
    querystring.Append("&msg=" + HttpContext.Current.Server.UrlEncode(_errorMessage));
    querystring.Append("&app=" + HttpContext.Current.Server.UrlEncode(_ssoApp));
    if (_ssoHiddenVars.Length > 0)
        querystring.Append("&hid=" + HttpContext.Current.Server.UrlEncode(_ssoHiddenVars));
    
    //Generate iframe src for pointing to SSO.aspx application page
    StringBuilder html = new StringBuilder();
    html.Append(@"<iframe src='/_layouts/SSODemo/SSO.aspx" + querystring.ToString() + @"' id='frame1'
    width='100%' height='100%'>Your browser does not support iframes</iframe>");
    this.Controls.Add(new LiteralControl(html.ToString()));
    
    As you can see, the six personalization settings are delivered to the SSO.aspx application page via the querystring.  The first five are pretty self-explanatory, but let me introduce the last one since that one is not so obvious. 
     

    Many systems (like Amazon and ebay) require additional form variables to be present when authenticating the user.  These control things like whether you should automatically remain logged in or which page should you be redirected to after login.  Of course, each system is different.  Without providing this necessary input, the login process may fail.  To address this, the sixth setting allows you to enter in any custom form variables that are needed.  These will be converted into hidden html controls. 

    The only way to know which of these variables you need is to take a look at the HTML source page for a login screen.  From here you can determine which variables you need.  You just need to enter them in one at a time separated by a pipe (|) character.  For example, to correctly log into to Amazon, I must pass these additional values: useRedirectOnSuccess=1|path=/gp/css/homepage.html|action=sign-in|protocol=https.  This line is then translated into this html which is included in the form that is automatically submitted:

    <input type='hidden' name='useRedirectOnSuccess' id='useRedirectOnSuccess' value='1' />
    <input type='hidden' name='path' id='path' value='/gp/css/homepage.html' />
    <input type='hidden' name='action' id='action' value='sign-in' />
    <input type='hidden' name='protocol' id='protocol' value='https' />
    Let’s now take a look at the SSO.aspx application page.  It’s more interesting than the Web Part.  This page is what generates the HTML form that is posted to the web application.  When the page initializes, it loads the six settings as shown here in the Page_Load event:
    //load querystring values passed over from web part
    string url = Request.QueryString["url"];
    string userCtrl = Request.QueryString["uc"];
    string passCtrl = Request.QueryString["pc"];
    string errorMsg = Request.QueryString["msg"];
    string ssoApp = Request.QueryString["app"];
    string hiddenVars = Request.QueryString["hid"];
    From here, I have the code to pull the user’s credentials and generate the first part of our HTML form:
    //Pull credentials for this user from SSO database
    GetCredentials(ssoApp, out username, out password);
    
    //Generate HTML form
    StringBuilder html = new StringBuilder();
    html.Append(@"
        <HTML>
        <body onload='document.login.submit();'>
        <form name='login' id='login' method='post' action='" + url + @"'>
        <p/><p/><p/>
        <center>
        Logging in...
        <br/>
        <br/>
        <img src='/_layouts/images/GEARS_AN.GIF' />
        <input type='hidden' name='__VIEWSTATE' id='__VIEWSTATE' value='' />
        <input type='hidden' name='" + userCtrl + "' id='" + userCtrl + "' value='" + username + @"' />
        <input type='hidden' name='" + passCtrl + "' id='" + passCtrl + "' value='" + password + @"' />");
    The second part is where the extra hidden HTML controls are created along with the closing part of the form.
    //generate out additional hidden form variables
    if (hiddenVars != null)
    {
        foreach (string str in hiddenVars.Split('|'))
        {
            //split out key and value pair within variable
            string[] var = str.Split(new char [] {'='},2);
            html.Append("<input type='hidden' name='" + var[0] + "' id='" + var[0] + "' ");
            html.Append(" value='" + var[1] + "' />");
        }
    }
    html.Append(@"</center>
        </form>
        </body>
        </HTML>");
    
    this.Controls.Add(new LiteralControl(html.ToString()));
    
    In the first part above, you’ll notice that that I have a helper method called GetCredentials.  This is where the user’s actual username and password are pulled from the SSO database.  Here is the code:
    public void GetCredentials(string ssoApp, out string username, out string password)
    {
    
        //connect to default SSO provider
        ISsoProvider provider = SsoProviderFactory.GetSsoProvider();
    
        SsoCredentials creds;
        try
        {
            //get credentials for currently logged in user
            creds = provider.GetCredentials(ssoApp);
        }
        catch (SingleSignonCredsNotFoundException ex)
        {
            string msg = "User " + HttpContext.Current.User.Identity.Name;
            msg += " does not have credentials stored in the Single Sign On database";
            throw new Exception(msg, ex);
        }
    
        //convert credentials into a string
        IntPtr pUserName = IntPtr.Zero;
        IntPtr pPassword = IntPtr.Zero;
        try
        {
    
            //NOTE: After this has been converted to a String object, it remains in 
            //memory until the garbage collector collects it.
            pUserName = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(creds.UserName);
            username = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(pUserName);
    
            pPassword = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(creds.Password);
            password = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(pPassword);
        }
        finally
        {
            // Free zero out and free the BSTR pointers.
            if (pUserName != IntPtr.Zero)
            {
                System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(pUserName);
            }
    
            // Free zero out and free the BSTR pointers.
            if (pPassword != IntPtr.Zero)
            {
                System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(pUserName);
            }
        }
    }
    
    This code was only slightly modified from the sample code found on MSDN hereThere is additional code in other sections to handle errors, but I’ll leave that to your study if you download the code.
     

    Configuring Single Sign On

    Of course, all of this code requires that you have the SSO service installed with an application configured.  I’ll not go into detail on how to do this and instead direct you to this TechNet article and a nicely summarized list of steps from Dave Wollerman’s blog.  Once the SSO service is configured and a SSO database has been created, you need to create an application definition.  This is done through the third link in the Manage Single Sign-On Settings as shown here highlighted in red:

    image
    Figure 7: Setting up an application definition in SSO

    This takes you to this screen where you set up each of your application definitions.  Each definition will contain username and password combinations for a specific system.  In this screen shot, I have three set up for Amazon, ebay and Time Reporting. 

    image
    Figure 8: List of Application Definitions

    Once the Application Definition is configured, you need to populate the SSO database with credentials for each user.  SSO works by using a mapping system where the user’s SharePoint credentials map to a username and password stored in the SSO database.  You have two basic ways to populate the SSO database with these credentials.  One way is to manually add username and passwords using these Manage SSO screens.  This is done with this link shown highlighted in red:

    image
    Figure 9: Storing credentials in SSO for a user

    You then choose the Application Definition and enter in the SharePoint user account name and click the Update account information radio button as shown here:

    image
    Figure 10: Choosing the Application Definition and SharePoint user

    Finally, this will then take you to this screen where you can store the username and password for this user:

    image
    Figure 11: Storing the new username and password within SSO

    This option works well for just a few users; however, it gets tedious if you’ll be adding lots of them.  Also, you must also edit them if the external system’s credentials ever change. 

    For the second way of storing credentials in the SSO database, I won’t cover that in detail this article.  If there is enough interest, I’ll cover this in a follow up blog.  The basic idea, though, is that if credentials for the external system do not exist, you prompt the user to provide the username and password.  These are then securely stored in the SSO database.  This could all be done within the custom application page.  A similar design would be used when the credentials have changed and you need to store the current ones.

    Caveats

    One drawback to this design is that it requires the web application that you are signing into to allow a form to be directly posted without validation. This can be a problem with some applications, especially newer ASP.NET systems.  If you have control over the web application, you may be able to disable this by using the <pages enableEventValidation=”false”> setting in Web.Config.  I cannot promise that this solution will work in all situations, however.

    For ASP.NET web applications, you may still need a __VIEWSTATE form variable present.  You can add this to the additional form variables section when configuring the Web Part. 

    Some systems log you in using the credentials passed in the querystring to the web application.  This is not currently supported in this code, but you could download the source and easily modify it to support this feature.

    There are issues if the browser’s security zone for the SharePoint site and for the web application mismatch.  For example, if the SharePoint site is in the trusted zone, but the web application is in the internet zone.  This solution works best if both sites are in the same zone.

    Downloading the Code

    I have developed this solution using VS 2008 with Visual Studio Extensions for WSS (VSeWSS) v1.2.  The Web Part and application page are stored in one project and is deployable through a single WSP solution.

    Click here for those interested in downloading the source code.

    Click here for those only interested in the WSP solution.  You will need to deploy this using STSADM commands.

    Conclusion

    In this article, you have seen how to develop a custom Web Part and application page that can automatically log users in to their commonly used web applications.  The advantage to this design is that you can use one Web Part for multiple applications.  In this article, I have the one Web Part used to auto-authenticate into the Time Reporting System, ebay, and Amazon.

    Hopefully this will simplify some of your web application access and also encourage staff to use SharePoint as a single portal for all application needs.  Enjoy.


    SharePoint User Group - Real World SharePoint Video is Now Online
    Randy Williams
    Category: Architecture;Development
    11/23/2008

    Last week, my friend Wen He and I spoke for the Hawaii SharePoint User Group.  Our topic was Real World SharePoint: 25 Practical Business Solutions.  We had a great turnout, with standing room only and a line a people out the door just trying to listen. 

    The video for our session is now posted and can be viewed here.  For those wondering what was covered, below is a brief overview of the 25 solutions that we covered.  This was presented in a way so that it would appeal to both technical and non-technical people.

    Since we didn’t have time to get into much detail (25 demos in less than 2 hours), I will be re-recording these as individual video files.  Not only will I cover how the solution works, I will also be walking through the code.  Stay tuned to my blog, and I will let you know when these are available.

    Session Topics:

    Part I - Web Parts, Web Services, and InfoPath

    1. Data-Driven Web Part

    2. Web Part Connections (Show Weather)

    3. Client side connected Web Parts

    4. Create Info Path form that creates a new Announcement List

    5. InfoPath Form that surfaces fields in a SharePoint column

    6. Profile Editor (Windows Application – SME User Profile property)

    Part II - Ajax and Silverlight

    7. AJAX Find User

    8. AJAX Search

    9. Silverlight Charting

    Part III - Site Provisioning

    10. Programmatically provision a site collection and customize the root web

    11. Create a new site based on a custom site definition

    12. Site Action menu item (Custom Action) that links to a custom app page

    13. Hide Delete Site link (HideCustomAction)

    14. Print View Feature from CodePlex

    Part IV - Custom field, event handler, and Workflow

    15. Delegate Control (World Clock)

    16. Rating Stars custom field

    17. Validating Custom Field (generic)

    18. Custom event receiver for classification of an announcement

    19. Upload document and set content type (apply metadata)

    20. Resume handling workflow

    Part V - Business Intelligence

    21. Publishing Excel file into Excel Services and exposing parameters

    22. Demonstrate a Windows app to calling in to Excel Web Services

    23. BDC Business Data List, Related Item, Business Item web part

    24. BDC Search

    25. Reporting Services


    First BDC Article Has Been Published
    Randy Williams
    Category: Development
    11/21/2008

    Greetings.  As I blogged about a few weeks ago, I am working on an 8-part BDC series for SharePoint Magazine.  The first article has been published and the link is here:  http://sharepointmagazine.net/technical/administration/everything-you-need-to-know-about-bdc-part-1-of-8

    Successive articles should be available about once a week through the end of the year.  Thanks go to Wen He for the series logo (he will also be writing articles #5 and #7).  Thanks also go to Wen, Irene Lui, and my Synergy colleagues for their proof reading.


    View PDF Files within a Web Part
    Randy Williams
    Category: Development
    11/21/2008

    I had a request the other day on how can you display a PDF file within a single web part.  That is, among other content on the SharePoint page, there is a web part that just displays the contents of a PDF file.  This requestor also wanted the ability to just select the file in a drop down list box so that you could quickly flip through a list of files quickly and easily. 

    The concept that I went on is something similar to the Page Viewer Web Part (PVWP).  This Web Part creates an IFRAME object and sets the src attribute to the requested web page.  So, the HTML looks something like this:

    <iframe id=”frame1” src=”default.aspx”>

    Even though the PVWP does not support displaying PDFs this way, you can develop a custom Web Part that does.  The custom Web Part I looks like this (click image to enlarge):

    image

    Changing the file from the drop down list will display a new file.  This is done through JavaScript to prevent the whole page from reloading.  The list of files for the viewer are defined in a document library.  Here are the documents that show up for this library:

    image

    Keep in mind that the PDF files render nicely because of Adobe PDF browser plug-in that I’m using.  Web pages also display just fine.  If you choose a file such as a Word document, however, this file will be downloaded instead of displayed in a IFRAME.  This is because there is no browser plug in for MS Word files, and you cannot have a MIME content type other than text/html in an IFRAME.

    A single document library determines which files are shown in the drop down list.  This is set by a shared personalization property defined in the Web Part.  Below is how this is set.  Make sure you provide the full path to the document library.

    image

    Web Part Code

    The Web Part was developed in Visual Studio 2008.  First off, here is the code for the personalization property:

    [Personalizable(PersonalizationScope.Shared),
    WebBrowsable(true),
    WebDisplayName("Document Library"),
    WebDescription("Enter in the Url to the document library")]
    public string LibraryUrl
    {
        get { return _docLib; }
        set { _docLib = value; }
    }
    

    Here is the CreateChildControls method for the Web Part:

    protected override void CreateChildControls()
    {
        base.CreateChildControls();
    
        iframeObjectID = "iframe_" + guid;
    
        string siteUrl;
        string webUrl = string.Empty;
        string fileContents = string.Empty;
    
        //Define our DropDown List
        dl = new DropDownList();
        dl.Attributes.Add("onchange", "LoadFile_" + guid + "();");
        dl.Items.Add("Select a document");
        
        SortedDictionary <string,string> files;
    
        try
        {
            //Is our document library path set?
            if (this._docLib != null)
            {
                //decode any %20 spaces in URL
                siteUrl = this._docLib.Replace("%20", " ");
    
                //Open site collection
                using (SPSite site = new SPSite(siteUrl))
                {
                    //this block of code allows us to extract the relative Url of a subweb
                    if (site.Url.Length + 1 <= siteUrl.Length)
                    {
                        webUrl = siteUrl.Remove(0, site.Url.Length + 1);
                    }
    
                    //open web
                    using (SPWeb web = site.OpenWeb(webUrl))
                    {
                        //get handle to our document library
                        SPDocumentLibrary library = (SPDocumentLibrary)web.GetList(_docLib);
    
                        //create a generic sorted dictionary to store the files
                        files = new SortedDictionary<string, string>();
    
                        //loop through each file in root folder and add to sorted list
                        foreach (SPFile file in library.RootFolder.Files)
                        {
                            files.Add(file.Name, web.Url + "/" + file.Url);
                        }
    
                        //add each sorted file name to our drop down list
                        foreach (KeyValuePair<string, string> key in files)
                        {
                            ListItem item = new ListItem(key.Key, key.Value);
                            dl.Items.Add(item);
                        }
                    }
                }
                //Add drop down list and break tag to web part
                this.Controls.Add(dl);
                this.Controls.Add(new LiteralControl("<br/>"));
    
                //Define a literal control to hold generated HTML  (This will become our iframe)
                iframe = new LiteralControl();
                //Uniquely stamp this IFRAME
                string frameGuid = new Guid().ToString();
                iframe.Text = "<iframe id='" + iframeObjectID + "' width='100%' height='100%' style='visibility:hidden'>Your browser does not support iframes</iframe>";
                this.Controls.Add(iframe);
            }
            else
            {
                //Set literal text to configure this web part
                LiteralControl html = new LiteralControl("Click <a href=\"javascript:MSOTlPn_ShowToolPane2Wrapper('Edit', this, '" + this.ID + "')\">open tool pane</a> to set path to Document Library");
                this.Controls.Add(html);
            }
        }
        catch (Exception ex)
        {
            //Display any error that comes up
            this.Controls.Clear();
            this.Controls.Add (new LiteralControl ("An error occurred: " + ex.Message.ToString()));
        }
    }
    


    There is nothing too fancy here.  I store each file into a SortedDictionary generic list.  This will sort the files found in the Document Library.  As you can see, I currently pull all files from the root folder in the document library.  This could be easily changed to use another personalization property if you wanted to only list files in a sub-folder.

    As you can see near the end of CreateChildControls, I add an iframe HTML tag to the Web Part’s control’s collection (via a LiteralControl).  The code to display a new file is handled by a JavaScript method.  I chose JavaScript to keep the whole page from refreshing, so it’s a nicer user experience. 

    One other useful snippet that you might find helpful is that when you first add the Web Part to a page, it will prompt you to configure it.  This is similar with many of the OOB web parts, and this concept was pulled from Cliff Green’s blog post here.  Here is how it looks:

    image

    Lastly, here is the JavaScript that handles the onchange event for the drop down list.  This is dynamically created to reference the dynamic IDs that are given.  (Note: Since you may want multiple instances of this WebPart on the page, I have appended a GUID to all HTML object IDs and this JavaScript LoadFile method.  This ensures all names are kept unique).

    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
    
        if (!Page.ClientScript.IsClientScriptBlockRegistered ("script_" + guid))
        {
            //dynamically generate our JavaScript
            string script = @"function LoadFile_" + guid + @" () { 
    var iframeobj = document.getElementById ('" + iframeObjectID + @"');
    var selectobj = document.getElementById ('" + dl.ClientID + @"');
    if (selectobj.value.toLowerCase().indexOf ('http') != -1)
    {
    iframeobj.src = selectobj.value;
    iframeobj.style.visibility = 'visible';
    }
    else
    {
    iframeobj.src = '';
    iframeobj.style.visibility = 'hidden';
    }
    }
    ";
            //register our client side script that is an embedded resource
            Page.ClientScript.RegisterClientScriptBlock (typeof (Page),"script_" + guid, script,true);
        }
    }
    


    For those that want to tweak the code, feel free to download the code available here.  This was written in Visual Studio 2008 along with Visual Studio Extensions for WSS (VSeVSS) v1.2.

    For those who just want to use it as is, here is the WSP solution that can be downloaded and installed.  For those unfamiliar with deploying SharePoint solutions, here is the basic syntax on installing and deploying it into your farm:

    stsadm –o addsolution –filename <full path to WSP file>
    stsadm –o deploysolution –filename <WSP filename> –url <path to Web application>
    stsadm –o activatefeature –name FileViewer –url <path to site collection where you want to use this>

    Enjoy!

     


    Creating a BDC ADF for a Standard (non-trusted) login to SQL Server
    Randy Williams
    Category:
    11/6/2008

    As I was doing research for my upcoming BDC series in SharePoint Magazine, I finally had time to experiment with something that had been nagging at me for quite some time.  What I wanted to do was set up a LobSystemInstance within a MOSS Application Definition File (ADF) to authenticate into a SQL Server using a standard (or non-trusted) login. 

    Typically when working with database connections through BDC, you authenticate to the database using some type of Windows account, whether this is an application pool account (using RevertToSelf) or the actual user’s credentials (using PassThrough or SingleSignOn options). Clearly this is the most secure approach, but what if your needs are simple?  And, there may be “double-hop” delegation problems with this is you’re using the user’s credentials without Single Sign On or Kerberos in place.

    For example, let’s say you have a database that is currently used by some dedicated application in your organization.  With ADO or ADO.NET, it is quite common to have a simple connection string that looks something like this:

    Data Source=<MySQLServer>;Initial Catalog=<database>;user id=<login>;password=<password>

    This means all users will be sharing a specific SQL Server user name and password to log in.  One advantage to this approach is that you can pool the connections, which saves memory and increases performance on your SQL box.  The big drawback is that this username and password goes across the wire unencrypted (unless you’re using IPSEC or something else to secure the line).  Well, my opinion is if #1 it’s on a private network; #2 the database doesn’t contain any real sensitive data; and #3 the credentials only give you read access, it’s not that big of a security risk.  Since we’re talking about BDC from your SharePoint farm, it’s very likely all three of these are non-issues.  Just my opinion, though.  (Of course, security is a complex subject, and there are more considerations than this, so I am intentionally keeping it simple here.)

    So then, how would you configure an LobSystemInstance to connect this way?  As it turns out, it’s quite simple and much more intuitive than I thought.  Here below is how it would work.  Notice that the basic values are close to our connection string above.

    <LobSystemInstance Name="Instance Name">
       <Properties>  
          <Property Name="AuthenticationMode" Type="Microsoft.Office.Server.ApplicationRegistry.SystemSpecific.Db.DbAuthenticationMode">PassThrough</Property>  
          <Property Name="DatabaseAccessProvider" Type="Microsoft.Office.Server.ApplicationRegistry.SystemSpecific.Db.DbAccessProvider">SqlServer</Property>  
          <Property Name="RdbConnection Data Source" Type="System.String">servername</Property>  
          <Property Name="RdbConnection Initial Catalog" Type="System.String">databasename</Property>  
          <Property Name="RdbConnection Integrated Security" Type="System.String">False</Property>  
          <Property Name="RdbConnection User ID" Type="System.String">UserID</Property>  
          <Property Name="RdbConnection Password" Type="System.String">Pwd</Property>  
      </Properties>  
    </LobSystemInstance>

    With this, you now have another option when authenticating to your back-end data sources.  And, for simple needs, it works quite well!

     

    Programmatically Adding to and Removing from a Person or Group Column
    Randy Williams
    Category: Development
    11/1/2008

    One of the out-of-the-box field types that SharePoint supports is Person or Group.  It easily allows you to assign users or groups from your site collection to that item.  This is most noticeable with the Assigned To column in the Tasks list.  Here is a sample row from the Tasks list (click for a full-size view).

    image

    When creating a new item, it looks like this: