SharePoint 2010 and Office Web Apps: System.Data.SqlClient.SqlException: Cannot open database “WSS_Content” requested by the login. The login failed.

When trying to open a word document in Office Web Applications in a fresh install of SharePoint 2010 the word web application might just say that it could not open the document and something went wrong provided with a correlation ID.

The correlation ID gives the following stacktrace when checking the ULS log:

System.Data.SqlClient.SqlException: Cannot open database “WSS_Content” requested by the login. The login failed.  Login failed for user ‘DOMAIN\ACCOUNT’.
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
at System.Data.SqlClient.SqlInternalConnectionTds.CompleteLogin(Boolean enlistOK)
at System.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, Boolean ignoreSniOpenTimeout, Int64 timerExpire, SqlConnection owningObject)
at System.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(String host, String newPassword, Boolean redirectedUserInstance, SqlConnection owningObject, SqlConnectionString connectionOptions, Int64 timerStart)
at System.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(SqlConnection owningObject, SqlConnectionString connectionOptions, String newPassword, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, Object providerInfo, String newPassword, SqlConnection owningObject, Boolean redirectedUserInstance)
at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnection owningConnection, DbConnectionPool pool, DbConnectionOptions options)
at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
at Microsoft.SharePoint.Utilities.SqlSession.OpenConnection()

The solution is straightforward. The account mentioned does not have access to the content database, and this can be verified by checking the content database logins in SQL Management Studio. However, one should never touch SharePoint databases directly, so use the following PowerShell-script to grant content database permissions to the account:

Add-PSSnapin Microsoft.SharePoint.PowerShell

$webApp = Get-SPWebApplication “http://team.janmwk.steria.com”

$webApp.GrantAccessToProcessIdentity(“DOMAIN\ACCOUNT”)

When you try to open the word document in the word web application again, the error should now be gone and it should display the word document instead.

Automatically Retract, Remove, Add and Deploy SharePoint 2010 WSP Solution Files with PowerShell

Deployment of SharePoint 2010 solutions could be a tiresome process especially if you have to do it often. In a recent project, I had to do weekly deployments of solutions throughout the development phase against our staging environment. This task was to be performed regularly and you could risk feeling like a robot typing the PowerShell commands in PowerShell. Why not try to automate such a mundane task?

Below I have included the PowerShell script I developed in order to automatically retract, uninstall, deploy and install SharePoint 2010 solution files. The PowerShell script is based on Reza Alirezaei’s script for installation of solutions from KWizCom. My script does not support upgrade of SharePoint 2010 solutions.

Basically, the script works in the following manner. First, it checks if there are any SharePoint 2010 solution files present in the current folder. If there is, it continues. For each of the solutions found, it checks whether they are deployed and installed in the current SharePoint 2010 farm. If they are found, they are retracted and removed from the farm. Last, the PowerShell script adds the solutions found to the farm, and then installs it.

To run the script, just type in the PowerShell console:

.\<SCRIPTNAME>.ps1

Just copy and paste the following section to a ps1-file:

function WaitForJobToFinish([string]$Identity)
{   
    $job = Get-SPTimerJob | ?{ $_.Name -like "*solution-deployment*$Identity*" }
    $maxwait = 30
    $currentwait = 0

    if (!$job)
    {
        Write-Host -f Red '[ERROR] Timer job not found'
    }
    else
    {
        $jobName = $job.Name
        Write-Host -NoNewLine "[WAIT] Waiting to finish job $jobName"        
        while (($currentwait -lt $maxwait))
        {
            Write-Host -f Green -NoNewLine .
            $currentwait = $currentwait + 1
            Start-Sleep -Seconds 2
            if (!(Get-SPTimerJob $jobName)){
                break;
            }
        }
        Write-Host  -f Green "...Done!"
    }
}

function RetractSolution([string]$Identity)
{
    Write-Host "[RETRACT] Uninstalling $Identity"    
    Write-Host -NoNewLine "[RETRACT] Does $Identity contain any web application-specific resources to deploy?"
    $solution = Get-SPSolution | where { $_.Name -match $Identity }
    if($solution.ContainsWebApplicationResource)
    {
        Write-Host  -f Yellow "...Yes!"        
        Write-Host -NoNewLine "[RETRACT] Uninstalling $Identity from all web applications"            
        Uninstall-SPSolution -identity $Identity  -allwebapplications -Confirm:$false
        Write-Host -f Green "...Done!"
    }
    else
    {
        Write-Host  -f Yellow  "...No!"        
        Uninstall-SPSolution -identity $Identity -Confirm:$false    
        Write-Host -f Green "...Done!"
    }

    WaitForJobToFinish

    Write-Host -NoNewLine  '[UNINSTALL] Removing solution:' $SolutionName
    Remove-SPSolution -Identity $Identity -Confirm:$false
    Write-Host -f Green "...Done!"
}

function DeploySolution([string]$Path, [string]$Identity)
{
    Write-Host -NoNewLine "[DEPLOY] Adding solution:" $Identity
    Add-SPSolution $Path
    Write-Host -f Green "...Done!"

    Write-Host -NoNewLine "[DEPLOY] Does $Identity contain any web application-specific resources to deploy?"
    $solution = Get-SPSolution | where { $_.Name -match $Identity }

    if($solution.ContainsWebApplicationResource)
    {
        Write-Host -f Yellow "...Yes!"        
        Write-Host -NoNewLine "[DEPLOY] Installing $Identity for all web applications"    
        Install-SPSolution -Identity $Identity -AllWebApplications -GACDeployment

    }
    else
    {
        Write-Host -f Yellow "...No!"        
        Write-Host -NoNewLine "[DEPLOY] Globally deploying $Identity"    
        Install-SPSolution -Identity $Identity -GACDeployment
    }
    Write-Host -f Green "...Done!"

    WaitForJobToFinish
}

$snapin = Get-PSSnapin | Where-Object { $_.Name -eq "Microsoft.SharePoint.Powershell" }
if ($snapin -eq $null) {
    Write-Host "[INIT] Loading SharePoint Powershell Snapin"
    Add-PSSnapin "Microsoft.SharePoint.Powershell"
}

Write-Host "[INIT] Locating WSP files to be deployed"
$wsps = Get-ChildItem . *.wsp | where-object { !($_.psiscontainer) }

foreach ($wsp in $wsps)
{
    $identity = $wsp.Name
    $path = $wsp.FullName
    Write-Host "[INFO] ----------------------------------------"
    Write-Host "[INFO] Installing $Identity"
    Write-Host -NoNewLine "[INFO] Determining if $Identity is already installed"

    $isInstalled = Get-SPSolution | where { $_.Name -eq $identity }
    if ($isInstalled)
    {
        Write-Host -ForegroundColor Yellow "...Yes!"
        (RetractSolution $identity)
        (DeploySolution $path $identity)
    }
    else
    {
        Write-Host -ForegroundColor Yellow "...No!"
        (DeploySolution $path $identity)
    }

    Write-Host -NoNewline "[INFO] Installation and deployment of $Identity"
    Write-Host -ForegroundColor Green "...Done!"
}

NDC 2011 was Awesome and Speaking There was a Great Experience

And there, the Norwegian Developers Conference 2011 (NDC2011) was over for this year. It was the first time I attended this conference, and I was only able to attend the last day of the conference. I have spent the majority of my free time preparing for my talk with my colleague Anders Ganes (@_anders) right before lunch at NDC2011. Guess I have a lot of videos to watch in the coming weeks. The rest of the conference lived up to my expectations: It was great! The latter part of the day was spent catching up with old friends, hanging out at the coolest booth at the conference floor (the Steria booth), and listening to Stephen Forte’s great talk on agile estimation.

The talk was a success, and lots of people showed up to listen to our experiences with SharePoint 2010 for Internet. A video recording of the talk will be available sometime in the coming weeks at the NDC2011 web page. A pleasant surprise was the amount of questions asked about different aspects of our SharePoint 2010 solution. For the interested, I have attached the slides we used in the talk at the bottom of this post.

Thank you to all who came to listen to us, and made this talk a great experience for me! I am definitely going back next year!

I am speaking at Norwegian Developers Conference 2011 (NDC 2011)

There has been a reason why I have not updated this blog in a while. I have been selected, together with my colleague Anders Ganes (@_anders) at Steria, to speak at the Norwegian Developers Conference 2011 in Oslo, Norway. I am very excited about this, as this is my first talk featured in the agenda of a major conference.

We are going to hold a talk regarding SharePoint 2010 for Internet, and the adaptions and issues we faced when developing Forsvaret.no for the Norwegian Armed Forces. Even though we solved these issues and adaptions in a SharePoint-setting, most of them are still valid for any web application. We have spent the last weeks extracting and distilling knowledge and experience from the project, which we hope you will benefit from in your next SharePoint for Internet project.

I hope to see you at our talk at NDC 2011. Our talk will be at Friday 10th of June, Track 6: SharePoint, BI, and web at 11.40 AM. See you there, and be sure to visit Steria’s booth during the conference!

Force Reinstall of SharePoint 2010 Solution through Visual Studio 2010 or PowerShell

An annoying error might happen when deploying SharePoint 2010 solutions. The feature will refuse to install itself, and the following error message will be shown post-deployment:

Error occurred in deployment step 'Add Solution': A feature with ID 00000000-0000-0000-0000-000000000000 has already been installed in this farm.  Use the force attribute to explicitly re-install the feature.

This error happens if you deploy a solution which contains a visual web part to a different web application on the same farm as the web application where it is already installed. In other words, you have two web applications, A and B on the same SharePoint farm. You want to deploy solution S which contains a visual web part to web application B, but it is already deployed to web application A. If you deploy the solution S to web application B, you will receive this error. The MSDN article Troubleshooting SharePoint Packaging and Deployment mentions this problem is caused by a visual web part. This is imprecise. It is caused by the user control (a visual web part contains a user control). You may face this error in any package which contains a user control. The article also menthions a possible fix to the problem by simply running the deployment process again. However, in certain situations (and in all situations I have faced this problem), this fix will not work.

The fix to this problem is actually mentioned in the error message, though it is well hidden. You can do this fix in both Visual Studio 2010 or PowerShell. I will leave STSADM.EXE out of this as it is deprecated, and should be used as little as possible. The fix in Visual Studio 2010 is to double-click on the feature in question and open the feature window. From there, use the properties window and set the value of Always Force Install to true.

If you are hardcore and still prefer notepad (like certain people still do), you can edit the Feature elements of your solution. To force installation of a feature through editing code, open the Feature.xml file add the AlwaysForceInstall attribute with the value TRUE to the Feature element:

<Feature AlwaysForceInstall="TRUE">
...
</Feature>

In PowerShell, you can use the -Force parameter of the Install-SPSolution commandlet in order to force the installation of a solution:

Install-SPSolution -Identity <solution_file> -GACDeployment -Force

If you follow any of the advice described above, you should have no trouble next time you face this error after a SharePoint 2010 deployment gone wrong.

SharePoint 2010 Development Environment Installation and Upgrade

SharePoint 2010 shipped with the ability to install a stand-alone installation for development environment purposes. However, in order to do an installation on Windows 7 or Windows Vista a couple of tricks are needed in order to accomplish this (from Setting Up the Development Environment for SharePoint 2010 on Windows Vista, Windows 7, and Windows Server 2008):

  1. Extract the SharePoint 2010 Foundation or Server setup executable file with
    <setup_file> /extract:<path_to_extract_to>
  2. Modify the config.xml file located at <path_you_extracted_to>\Files\Setup\ and add the following line to the configuration file inside the <configuration>-tag:
    <Setting Id="AllowWindowsClientInstall" Value="True"/>
  3. Activate the following services through the command line:
    start /w pkgmgr /iu:IIS-WebServerRole;IIS-WebServer;IIS-CommonHttpFeatures;
    IIS-StaticContent;IIS-DefaultDocument;IIS-DirectoryBrowsing;IIS-HttpErrors;
    IIS-ApplicationDevelopment;IIS-ASPNET;IIS-NetFxExtensibility;
    IIS-ISAPIExtensions;IIS-ISAPIFilter;IIS-HealthAndDiagnostics;
    IIS-HttpLogging;IIS-LoggingLibraries;IIS-RequestMonitor;IIS-HttpTracing;IIS-CustomLogging;IIS-ManagementScriptingTools;
    IIS-Security;IIS-BasicAuthentication;IIS-WindowsAuthentication;IIS-DigestAuthentication;
    IIS-RequestFiltering;IIS-Performance;IIS-HttpCompressionStatic;IIS-HttpCompressionDynamic;
    IIS-WebServerManagementTools;IIS-ManagementConsole;IIS-IIS6ManagementCompatibility;
    IIS-Metabase;IIS-WMICompatibility;WAS-WindowsActivationService;WAS-ProcessModel;
    WAS-NetFxEnvironment;WAS-ConfigurationAPI;WCF-HTTP-Activation;
    WCF-NonHTTP-Activation

All this information can be found in the MSDN article I linked to at the top, including a step by step guide on how to install SharePoint 2010 on a development machine. This will allow the setup to run and install SharePoint 2010 Foundation or Server on your client operating system. There is one caveat with the SharePoint 2010 setup on Windows 7 that I know of: The prerequisite checker will not work. It kept stopping because it were not able to locate certain files. Therefore, you need to manually check and install the required prerequisites if required.

I did this installation of SharePoint 2010 Foundation by following the guide at MSDN in early September 2010 to prepare for my SharePoint MCTS certifications on application development and configuration. The process was not free of pain, but I eventually managed to complete the configuration wizard. Keep in mind, SharePoint 2010 will always install without errors (I thought, details will come below), and most likely, the sadism of the installation process with show itself when you run the configuration wizard. The main problems I faced when trying to run the configuration wizard were related the Microsoft SQL Server 2008. I did not notice I had SQL Server 2008, and not SQL Server 2008 R2 installed. After a quick uninstall of SQL Server 2008, and installation of SQL Server 2008 R2, the configuration wizard ran fine. Obviously, this was my mistake, as I did not check the installation requirements throughly enough. No hard feelings SharePoint 2010!

Now, a six months have passed and I discovered I required the services which comes with SharePoint 2010 Server for a presentation I’m going to hold. I though about upgrading my SharePoint 2010 Foundation to Server. I did a quick google search and I found no sources which did the upgrade path I wanted. However, Microsft Technet article Review supported and unsupported upgrade paths (SharePoint Server 2010) mentions my upgrade path as a supported upgrade path. I decided to go ahead and try to upgrade my stand-alone SharePoint 2010 Foundation to a stand-alone SharePoint 2010 Server.

The required steps where the same as installing SharePoint 2010 Foundation. Just follow step 1 and 2 for the setup file of SharePoint Server 2010. Keep in mind, there are two prerequisites for SharePoint 2010 Server which are not required for SharePoint 2010 Foundation: Chart controls and SQL Server Analysis Services – ADOMD.Net. These need to be installed before you can continue. Then proceed with the installation of SharePoint 2010 Server. The installation process should complete gracefully, and the configuartion wizard should run. If you are lucky, the configuartion wizard will complete without much trouble.

The first time I did this upgrade process, the configuration wizard crashed. I received a generic SPUpgradeException, and no other specified details in the log files. A google search revealed nothing of interest, and I decided to rollback to SharePoint Foundation. After uninstalling the fresh install of SharePoint Server, I ran the configuration wizard again. It crashed as it could not find the SQL server instance for SharePoint. I fired up SQL Management Studio and tried to connect to the instance. No success. This lead to forcing me to uninstall SharePoint 2010 Foundation. My second attempt was to just install SharePoint Server 2010 with a fresh install. The configuration wizard would still not run, and forced me to do another uninstall. My last attempt, I reinstalled SharePoint 2010 Foundation. After the reinstallation, the configuration wizard completed without any trouble to my surprise. Last, I decided to give the upgrade to SharePoint 2010 Server. I ran the installer and the configuration wizard, to my great surprise, finished without any errors.

I could not believe this, so I tried to fire up my SharePoint 2010 site in the web browser. I waited for a couple of minutes before receiving a request time out. After a quick refresh, I had my working SharePoint 2010 site on a SharePoint 2010 Server installtion. The upgrade will most likely work best on a fresh install of SharePoint 2010 Foundation, and is possible, if you have some patience.

Arctic SharePoint Challenge 2011

This is a write-up of my experiences from Arctic SharePoint Challenge 2011. A non-profit conference. I attended as the team leader for the Steria team “Steria Cheetahs” (from now: Cheetahs), along with 4 SharePoint 2010 rock star developers Terje, Kjetil, Amr and Nina, which are my colleagues. In total, there were 8 other teams from other companies in the Oslo area in Norway. The challenge lasted for 3 days of intensive SharePoint 2010 hacking, with breaks consisting of talks, food or SharePints.

The Concept and the Flying Start

The challenge was for the fictive corporation Lynx, Inc.. The case description and personas were released prior to the conference so the teams had time to prepare themselves for the challenge. Cheetahs had two planning sessions before the conference, but no detailed plans were made. When you have approximately 20 hours to develop a solution, you need to have a clear idea of what you want to accomplish. Due to geographical differences between some of the team members, we had a brainstorming session the first hour of the conference room where any idea were a good idea. We used a task board to create an affinity diagram of related ideas. This planning session were really successful, and we left with a good feeling and a clear idea of what we were going to create the next 19 hours: An image wizard for a publishing site in SharePoint 2010 which could aid editors in cropping images for their articles.

Development Methodology

My team decided to use “lust-driven development”, that is, we only develop what we really wanted to. This was a conference where we were supposed to have fun, learn, and get to know other figures in the Norwegian SharePoint community. Therefore, we decided we should only do what we thought was fun.

This worked out really well, and every team member managed to be productive and participate on the final solution. Every team member created their own tasks, while letting the others know what they were currently doing. The limited time available made us focus on efficiency over a fully fledged project management tool. As for equipment, we only had our laptops, and no staging environment to test our solutions. Next year, I think we really should have a staging environment as time were spent integrating the different solutions on one machine.

The Gamification

The event utilised a concept called gamefication. That is, a mean provide gameplay mechanics for non-gameplay applications in order to reward users for adoption. Arctic SharePoint Challenge had badges which every team could earn. Some badges like “Best in Show” were exclusive. Our team did an outstanding job collecting badges, and we won 6 badges and an honorary mention for excellent user experience at the award ceremony. The badges we won were:

  • SharePoint Craftsman (Deployment Experience / Development best practice / Clean code / Standards compliance)
  • Excellent User Experience
  • Community Champions (Sharing and contributing with no regards to own well-being)
  • Remarkable Team Spirit (Teams that go above and beyond to keep spirits up during challenge times!)
  • Morning Glory (Best attendance at morning sessions (graveyard shift factor is considered))
  • Test Driver (Outstanding display of testing practices in a SharePoint setting)

In other words, our performance were outstanding, and we really managed to deliver high quality solutions which some of these badges are evidence of.

The gamifications concept was new and worked great. However, it had its flaws. There were no way of distinguishing unique badges from badges which could be awarded to any team. And if we look to other implementations of this systems in video games, we should have had some meta-badges too. My suggestion is that this system is revised for next year with a distinction between awards and badges.

The Talk

The last day of the conference I held a talk about Forsvaret.no. The talk was in a lightning talk format and covered how we created and our experiences doing so. Forsvaret.no is one of the largest Norwegian SharePoint publishing sites for internet to date. I was happy that I received quite a few questions at the end of my talk. Great success!

The Surprise

The last day of the conference was special. Before the award ceremony, we were picked up by army trucks and they drove us to an unknown location. At this location, we tried skeet shooting and shooting with a pistol. The highlight was a ride with a Leopard tank through a bumpy track. This served as a much-needed break from our computers. Some of us had not been outside since our arrival at the hotel.

Conclusion

In my eyes, the conference was a great success, and I hope it will be a tradition and a cornerstone in the Norwegian SharePoint community. I hope I’m allowed to participate next year. It was fun from the start till the end. You certainly missed out on something big if you decided to not attend.

The conference homepage is http://www.arcticsharepointchallenge.com. You can find pictures from the event can be found at http://www.facebook.com/pages/Puzzlepart-Business-Apps-for-SharePoint/188190941208946.

Videos of our submitted solutions:

I will write a post about how we created the “Lynx Easy Image Wizard (Steria Cheetahs Final Edition)” when I find some time for it.

Book Review: Rockstar Presentations

Lots have happened the last months. A highlight was my attendance as a participant at Artic SharePoint Challenge 2011, and I even held a talk about a project I’ve worked on the last 3 months. I will provide a write-up of the event later. I like to hold talks, and I’m always looking at aspects on how to improve my presentations. Because of that, I decided to read “Rockstar Presentations” by Joseph Lewis.

The book was very short, and I completed it after one evening of reading. It was very easy to read, however, the content was lacking. This is very interesting as the author claims that keeping an audience’s attention is 90% content and 10% presentation technique. The basic receipe of a great presentations were: outline, draft, rehearse, polish and practice.  I have heard these mantras from every presentation technique course I have attended so far. I do not want to read them again in a book.

The book contains guidelines for designing powerpoint slides at the end. They are somewhat useful, but better resources can be found elsewhere. My favourites slide design books  so far has been Presentation Zen by Garr Reynolds and Slide:ology by Nancy Duarte. Which I would highly recommend over this one if you are looking for that.

I would only recommend this book to anyone who has not attended any presentation technique course or read any books. It has the basics, but nothing more. For a beginnerbook, I hoped Lewis would tackle the speaking anxiety problem many beginners face more in-depth. However, it is barely touched upon. Otherwise, stay away from this book, your money is better spent elsewhere.

Next books I will read in presentation techniques: Resonate by Nancy Duarte. I’m looking forward to that one as I loved Slide:ology.

Book Review of Professional SharePoint 2010 Branding and User Interface Design by Randy Drisgill et al.

One great consquence of working with Steria is the 100 hours you can spend yearly on freely learning new stuff at your own will. The project I am currently working on had a light break during Christmas, in other words, a perfect moment to read up on exciting stuff. I spent my hours between Christmas eve and new years eve reading Randy Drisgill’s new SharePoint 2010 book on branding which was released in November 2010. I have been eagerly awaiting this release since I started working with SharePoint 2010, hoping to pick up a trick or two within SharePoint-branding.

The books starts with a general overview of SharePoint 2010, leading into basic branding done through the user interface and SharePoint Designer 2010. Beyond this point, the books difficulty curve ramps up linearly with advanced branding concepts. Drisgill does a good job explaining the branding process of SharePoint 2010. (Un)fortunately, there are process are very similar to existing front end development processes. One chapter I might suspect many aspiring SharePoint 2010 branders will appreciate is the deployment of branding chapter. This chapter throroughly explains how the front end developer should deploy the branding to the SharePoint 2010 farm. This is certainly nice to know in order to be independent from back end developers (I think they will be happy too).

The big disappointment for me was the navigation chapter. This is the part of SharePoint 2010 branding I wish I was more fluent in writing custom navigation providers.  This part was for unknown reasons left out of the scope of the book, even though the technique to do this is mentioned. I really hoped Drisgill or whoever was responsible for writing this chapter left this in.

The last part of the book gives a okay overview of SharePoint 2010’s client object model and integration with Silverlight. Personally, I do not like to employ techniques which relies on Flash or Silverlight. Especially with the currently increased adoption of HTML5 and advanced JavaScript UI libraries available today.

If you are already an experienced branding wizard, the book does not in my opinion bring anything new to the table compared to existing sources. The main problem with this book is not due to the author, but how branding role in SharePoint is. The person who is experienced with branding SharePoint, is a jack-of-all-trades of web development. You need to be experienced with creating HTML, JavaScript and CSS, know how ASP.NET ticks, know how SharePoint internally renders requests to responses, know the SharePoint Client Object Model API for JavaScript or Silverlight, know how to be a wizard with XML and XSLT to a lesser degree, and last, have great communication skills and coordinate communication with project mangement, back-end developers, information architects and graphical designers. The topics outlined above are all covered by this book, except communication (However, how branding fits into the software development life cycle is described). Each of the topics mentioned above is worthy of their own books, covering them in-depth in one book is a dauting task.

Drisgill has to a certain degree succeeded with covering all the aspects and the book itself is a pleasant read. I would recommend this book to anyone (back end developers, projects management..) who wants to know how branding in SharePoint is performed. However, if you are a SharePoint 2010 branding rock star already, chances are that you might not find anything new in this book.

The correct way of hiding SharePoint-elements from the user interface

I have worked with branding of SharePoint 2010 for several months now. However, I am no novice to the world of web applications. I’ve spent a great deal of time reading up on SharePoint 2010 branding blog posts, and I am awestruck that no one have mentioned how to correctly hide SharePoint elements.

The most common practice I have seen is to use Cascading Style Sheets (CSS) to hide elements from the view of the user. This is done by using the CSS attribute display with the value none. This approach is sufficient visually, and is elegant and simple, but the solution comes short due to several reasons. Another solution is to use HTML comment tags in order to hide elements from view (luckily, I have not seen any SharePoint blog post recommend this practice).

The major shortcoming of these solutions is that the markup of the element is still generated in the page. A user is still able to view the functionality which is hidden by either disabling the style sheet of the web site, or by using the browsers built-in functionality to view the source code of the web site. In a worst case scenario, hidden functionality from the user interface could be a major security flaw of a system. There are numerous examples of web sites which have been the victim of malicious users using hidden functionality

However, SharePoint have a built-in permissions system which might cover your ass if you have this problem. One might argue that the actual problem is improper set permissions in SharePoint if a malicious attack using exposed functionality against the web site is successful. However, it is still a problem as users are exposed to functionality they cannot use. A user should never see functionality he cannot use.

My solution to this problem is to attack the problem where it starts. The solution I use is to make sure the markup of the functionality in question is never rendered in the web browser. In SharePoint 2010, HTML markup is injected through content placeholders, delegate controls or web parts. A content placeholder should be hidden through the use of a ASP.NET Panel with the attribute Visible set to False. This will ensure that the HTML markup from the content placeholder is never rendered at the client side. This solution is due to SharePoint 2010 requiring a set of content placeholders to be present in the master page. With regard to user controls and web parts, I create a customized verison by extending the original user control or web part to use in my SharePoint site. The customized version does not render the HTML markup which exposes the functionality which should not be visible. The last way I would suggest to hide elements, is to remove the element from the DOM by using, for instance, jQuery.