Add to My Yahoo! | Google Reader or Homepage | Add to Windows Live | Add to Windows Live Alerts

Wictor Wilén

Microsoft Certified Master (MCM) - SharePoint 2010 | Microsoft Most Valuable Professional (MVP) - SharePoint Server MVP | Author

Latest postings

Do you want to know more about the Microsoft Certified Master or Architect programs?

Posted at 2012-01-26 10:03 by Wictor Wilén in SharePoint , SQL Server , Windows Server 2008 R2 with 0 comments.

I bet you will!

Microsoft LearningThe Advanced Certification Team at Microsoft Learning will start a new Live Meeting series where you can learn more about the Microsoft Certified Master and Microsoft Certified Architect programs. It will be regularly held meetings where they will go into details about the programs. The program managers will make you understand the program mission and vision, how to prepare for a certification, how to apply for participation and the value of the programs. If you're interested in one or more of these programs I recommend you to attend one of the live meetings or watch the recordings. Of course attending the live meetings will allow you to directly ask questions to the program managers!

There will be live meetings for each product category (SharePoint Server 2010, Lync Server 2010, Exchange 2010, SQL Server 2008 and Active Directory).

To register for one of the live meetings head on over to the Microsoft World Wide Events site and get your slot. Currently there are two planned sessions:

Encrypted e-mails causes corrupted Crawled Properties in SharePoint 2010 Search Service Applications

Posted at 2012-01-18 05:45 by Wictor Wilén in SharePoint 2010 with 1 comments.

For a couple of weeks (ahem, months) I've been struggling with a strange Search Service Application issue. Some time back I went to check out on some Crawled Properties when making a tool to help copying settings between SSA's (more on this tool in another post). Then I noticed that there were tons of Crawled Properties with just garbled binary data(!) as the property name.

Corrupt Crawled Properties

I searched like crazy for a while to find where these came from, there was nothing in the logs of any kind related to this. I could not locate any documents related to the Crawled Properties. I could not delete them, somehow they are connected to some content (at least that's what the system says), but there were no document samples. I created a new SSA and crawled the same corpus and the same (almost) corrupted junk crawled properties appeared.

A couple of days back I finally found out where they came from. With the grace from Microsoft support I did some queries on the SSA databases and found another crawled property that was inserted at the same time as these junk properties. This property had document samples! And those samples were e-mail .msg files. And specifically it was e-mails with encrypted content! I copied these files onto a brand new farm without any content and was able to reproduce the corrupted properties.

How to reproduce the corrupted Crawled Properties

Encrypted e-mail messageTo verify that this had to do with encrypted e-mail messages, and just not the ones I found; I encrypted an e-mail, sent it to myself and exported it as an .msg file. I took this .msg file and added it to a document library in a hot new VM (yea, I only got new ones since I had to rebuild all my VM's last weekend due to a corruption issue on one of my base images). Then I fired of a full crawl, with full logging enabled, and watched the Crawled Properties of the SSA. And as expected they showed up after just a minute.

Corrupt Crawled Properties

So, be careful about having encrypted e-mail messages in your farm! Or prevent the issue...

How to prevent the issue

So, how do I get rid of these corrupted properties? Unfortunately there is no good (supported) way, at the time of this writing, except deleting your SSA and create a new one and before crawling the data remove the files or create a Crawl Rule.

If you already have these corrupted properties or if you want to prevent new corrupted properties you can create a Crawl Rule that excludes .msg files. That will help the situation - but you will not be able to search the .msg files (if they are encrypted you cannot search them anyways!).

Crawl Rules

Summary

These corrupted properties does not do any harm. You cannot use them and you don't notice anything else on the SSA except that they are there and annoys you. Only thing I can think of is that if you have a lots of them, you can run into trouble. There is a limit of 500.000 crawled properties per SSA! Sounds a lot, but for two .msg files I saw about 1.600 corrupted properties!

I hope this helps someone and I hope there will be a fix for this in the future - if that happens I'll update the post.

Visual Studio 11 Developer Preview with the new SharePoint Developer tools

Posted at 2012-01-10 05:25 by Wictor Wilén in Visual Studio , SharePoint 2010 , Office 365 with 3 comments.

imageVisual Studio 11 Developer Preview is now available for download für alles and it does not only include the Windows 8 stuff like the previous preview did - this one contains the thing we all want - the SharePoint Developer tools.

Overall the performance of Visual Studio 11 is blazingly fast! I regret I tested it - since I will go back to 2010 tomorrow (or even tonight). They team has done a great job and included a lot of the PowerTools natively; such as the new Solution Explorer, the improved search feature etc.

But, back to the SharePoint Developer tools 11! What's new for all the kool kids! Here's a few highlights.

Content Type and List Designer

We all love our CAML, FieldRefs etc. But it isn't that productive. VS11 contains the long awaited Content Type Designer and also a very similar designer for Lists.

This is how the designer looks like when you're creating a Content Type:

The Content Type Designer


When creating a list you have a great view to create Views:

Create a list view

Sandbox and Office 365 support

New features in the Office 365 space for Visual Studio was an easy bet. They have incorporated the things from the SharePoint Power Tools, such as better compile time support for the Sandbox etc. The best feature here is the Publish feature, which allows you to publish your package to a URL or local directory. You can now publish a SharePoint WSP directly to the sandbox in Office 365 - but you can't activate the solution from within Visual Studio.

Publish!

Other improvements

There are much more improvements such as profiling support, better JavaScript debugging support etc. Read all about the new stuff here: http://msdn.microsoft.com/en-us/library/ee290856(VS.110).aspx

But...you really need to test it out. I'm really looking forward to start working with projects in VS11!

Scheduled incremental crawls suddenly stopped due to a stale Timer Service in SharePoint 2010

Posted at 2012-01-02 09:36 by Wictor Wilén in SharePoint 2010 with 0 comments.

It is always fun to get back on site after a couple of days off work. SharePoint 2010 is like an annoying little critter, if you're not there to cuddle with it it will do the most strange things.

I currently have a support case open regarding some issues with crawled properties (I hope that will be another story to tell another day) and went into the Search Service Application admin pages in Central Admin to check some things. When poking around I noticed that the incremental crawl hasn't been run for a few days - actually it stopped working on the 31st of December last year (sounds like ages ago now :-). In this farm we have three Search Service Applications and only this one hadn't been incrementally crawled - the other two worked just fine. I fired up an incremental crawl manually and that worked, waited for the next incremental crawl to start - and it didn't. Also tried a full crawl manually - which worked fine, but the scheduled crawls never started.

Crawl History

I searched through the trace logs and event logs and found nothing that I didn't expect to see.

I tried to Synchronize() the Search Service Instances - which I've previously done when similar stuff happened by running some PowerShell snippets on the servers in the farm. Nothing happened!

Ok, what is actually triggering the incremental crawls then? It is triggered by timer jobs called Indexing Schedule Manager on XXX, and there is one job per server. In this case we have two servers running search and I took a look at them and noticed that one of these jobs hadn't been run since the last scheduled crawl - while the other one had been running all the time (every 5 minutes).

Index Schedule Manager Timer Job

I tried starting the timer job both through the Central Admin web UI and through PowerShell -but it just refused to start. Now this is strange! Now I took a look at the Timer Job History on this specific server and noticed that no timer jobs had been executed on that specific machine since that time when the scheduled crawl last was executed. Thankfully the trace logs were there and I could see that just after 2:00 AM on the 31st of December the Timer Service stopped working (no references to owstimer.exe at all since then). There's no warning or error or nothing that indicates that it would have stopped working (and the sptimerv4 service was still running on the machine). The only thing in there was a warning about a Forefront conflict. Nevertheless I needed to get it working and currently don't have time to spend on why this happened (if it happens again, then let's dig deeper).

Timer Job History

I tried to do a restart-service sptimerv4 on the failing machine, without luck, it couldn't be gracefully shut down. So I actually had to kill the owstimer.exe process and then start the timer service.

I will not stop!

Once the timer service was killed and started everything spun up and the incremental crawled kicked in after a couple of minutes and have been working perfect since then.

Interesting thing here was that I did not see any early warning signs, errors in the logs or similar, and the only way we found out that the Timer process had gone into a stale state was that the scheduled crawl for ONE of the Search Service Applications was not running.

Summing up the year of 2011 and embracing 2012

Posted at 2011-12-27 03:43 by Wictor Wilén in Personal , SharePoint 2010 , SharePoint 2010 Web Parts in Action with 1 comments.

It's that time of the year, when you're thinking about what you've done and accomplished the last twelve months. I've been writing a summary for the last five years (2006, 2007, 2008, 2009 and 2010) and I always think it's fun to look back at the year gone and do some predictions for the upcoming one.

This year has been totally crazy - I've been enjoying my work and clients/projects at Connecta and I totally love that we have such a strong team and offering. I can really feel the momentum we have in our team and projects, and nothing is stopping us now...

Writing

As usual I've been jotting down a couple of blog posts, some better than others (IMO) and unfortunately there are several that I just haven't had time to publish. I have on average 1.000 subscribers to my feed and a whole lot of other users finding my writings through the search engines - thank you all readers! These are the top ones for the last 12 months.

  1. Calling a WCF service using jQuery in SharePoint - the correct way
  2. Working with URLs in SharePoint 2010 JavaScripts
  3. SharePoint 2010 Ribbon Controls - Part 4 - The TextBox control
  4. SharePoint 2010 Ribbon Controls - Part 5 - The Button control
  5. Improve performance of your SharePoint 2010 applications using Windows Server AppFabric caching

Interesting to see jQuery and JavaScript posts topping the list - might give us a hint on what's been popular this year... The post that still is #1 is the Fix the SharePoint DCOM 10016 error on Windows Server 2008 R2 (remember where you read this first :-).

SharePoint 2010 Web Parts in ActionI also finally got my book SharePoint 2010 Web Parts in Action published in April. It took over a year of writing, re-writing, testing, reviewing etc etc to get it done. And when the books finally arrived in printed form it was such a great feeling. It's a tough competition on SharePoint books nowadays, and I'm glad to see quite good sales figures and especially great reviews (if you haven't already - head on to Amazon and tell me what you think).

MVP again...

In April I was re-awarded the Microsoft Most Valuable Professional - SharePoint Server award. This is an award for your on- and offline community contributions. Being a part of the SharePoint MVP community is great and gives you a lot of amazing contacts with some great people.

The Master!

The MCM - Microsoft Certified Master - program was the highlight of the year! In April/May I attended the R8 rotation of the SharePoint 2010 MCM program which was three long and tiresome weeks with best-in-breed SharePoint training by the best of the best. I passed all three written exams and the qualification lab on first attempt and was allows to call my self a SharePoint 2010 MCM in the end of May. Since that rotation I've really felt that my SharePoint skills and confidence has improved - and I do think that also my customers feel the same. I did a post about my experiences of the MCM program a couple of months back - and if you're interested go ahead and read it.

MCM

Conferences and travels

This year has also been filled with a lot of conferences and travelling. First of all in march all MVP's met up in Redmond, at the Microsoft campus, for the annual MVP Summit. This was my first visit to Redmond and the summit and I met a lot of the people I've only met through the online world previously. I had a blast with paintball, late nights and beers talking to some really great friends. A couple of months later I went back to Redmond for the MCM - the weather was the same as in March! October and November was quite hectic with another trip over the pond to the SPC 2011, a trip to the European SharePoint Conference in Berlin and finally the Southeast Asia SharePoint Conference in Singapore. I also managed to do a couple of conferences on home turf as well.

The International SharePoint Conference 2012I've already planned a couple of trips for 2012 - at least two trips to US again, one is the SPC 2012 in Las Vegas where I hope to meet a lot of you. I have also planned a trip to London in late April for the International SharePoint Conference. This will be an extraordinary conference with two really cool tracks - one IT-pro and one dev, where we'll build one big solution during three days. I promise to get back to you with more information about it as soon as it's available.

SharePoint

Yea, as usual this year has been all about SharePoint for me. I've seen the product mature, I've learnt more about it (again) than I ever could expect and I see a huge and increasing demand for the platform. If you're new in IT - bet on SharePoint!
We've also seen the birth of Office 365. I'm running both my work and personal e-mail in the hosted Exchange solution and I'm very satisfied. This fall I've spent a lot of time with SharePoint Online trying to do real work and deployments. To put in in nice words I should say that I'm more of an on-premise guy!

Predictions

In these recap posts I've done some predictions for the upcoming year. I had three last year and I was right about two of them: Windows 8 is communicated and with Hyper-V support. 
I've been thinking quite hard on what predictions to have this year, trying not to reveal anything or stating anything obvious. So here are my predictions for 2012.

  • Silverlight will die! - yeah, Microsoft haven't put it in those words, but that's what's going to happen. We'll probably see Silverlight doing it lasts breaths on the Windows Phone 7 platform though. HTML5 and JavaScript will take over.
  • Second Browser World War - for a couple of years browsers have tried to strive for a common standard, and Internet Explorer has finally caught up. Since the HTML5 standard is far from standardized we will see Firefox, Chrome, Safari and IE add its own proprietary "interpretations" of the standard which will diversify the browser world once again. It's already happening, unfortunately...
  • Windows Phone momentum - I do think that the movement of Windows Phone 7+ will finally accelerate 2012. Great hardware, Nokia, great apps, unlimited marketing money and people getting bored of icons in a row are a few of the reasons. And I never ever had my WP7 phone crash - but for the Android devices we have in the family it's a part of the daily routine...
  • Less cloudy - this is more of a wish than a prediction but I do hope that 2012 will be less cloudy. I'm so fed up with the term "cloud"! Of course hosted services will still be a major option but I do think that more and more customers are going to look at internal hosting and/or hybrid solutions.

What do you think?

Thank you and a happy new year

So, I do not think I will be posting anything more this year! It's been a fantastic year but I'm sure 2012 will beat 2011 big time. Thank you all readers and followers and thank you to all new friends I've met throughout this year and thank you to everyone supporting me and has to put up with late night IM's or e-mails (you know who you are!).

Now, enjoy your last days of 2011 and have really great New Years Eve - I know I will (even though enjoy incorporates some work!).

Suddenly getting Access Denied on your SharePoint 2010 User Profile Sync

Posted at 2011-12-17 11:57 by Wictor Wilén in Security , SharePoint 2010 with 3 comments.

The last week I stumbled upon a really interesting new and shiny User Profile Synchronization issue - one of these things that just make your day! We had to manually initialize a full synchronization, after doing some updates to one of the user profile properties, and the user profile synchronization would not just start...

Timer Job - Access DeniedEverything looked fine (on the surface) and we tried the incremental sync, which also looked like it was starting but nothing happened. The sync service was up and running and the FIM services was started, the MIISClient showed no activity. We took a look at the timer jobs, which are responsible for kicking of the synchronizations and saw that they all failed with the error message Access Denied.

No more than this simple error message. Since the timer jobs are executed using the Farm Account this sounded very peculiar. Oh, and you who still have your Farm Account in the local administrators group would probably never see this error, you'll be aware of this in a minute!

Next resort was to dig in to the trace logs (ULS), using my favorite SharePoint tool: ULSViewer. And there we had a Critical and an Unexpected entry, related to this Access Denied error message. ULS Logs

The accompanying stack trace showed me that it was some problems getting the instance of the Management Agents.

Stack Trace

Time to fire up my second best SharePoint tool: Reflector! Peeking into the failing method in the User Profile assembly revealed that the Access Denied was thrown while trying to retrieve the MA's using WMI. Now, this sounds really weird. As usual nothing has been changed in the farm (and this time I knew it for a fact) - but you should always check with the admins, which I did and no new policies or similar had been applied to any machines recently.

On the machine that hosted the sync service/FIM Services I started a Management Console and added the WMI snap-in and took a look at the Security tab for the local machine. And this is what I found:

Weird WMI permissons

The security settings for the MicrosoftIdentityIntegrationServer looked not just right, it more or less looked liked the default WMI security settings. (And as you can see the Administrators group is there - so that's why you who still have the farm account in the administrators group, probably never see this error...). A quick comparison with the identical staging environment showed a whole lot more permissions.

Correct WMI permissions

To be exact the following permissions did not exist for the environment that showed the Access Denied:

  • WSS_ADMIN_WPG group - Execute Methods, Provider Write, Enable Account, Remote Enable
  • FIMSyncOperators group - Execute Methods, Provider Write, Enable Account, Remote Enable
  • FIMSyncBrowse group - Execute Methods, Provider Write, Enable Account, Remote Enable
  • FIMSyncPasswordSet group - Execute Methods, Provider Write, Enable Account, Remote Enable

I fixed the permissions using the WMI management console, went back to Central Admin and started the synchronization manually and within a minute the synchronization was running beautifully!

I do not know about any supportability on this one - and you should NOT be doing this unless you really have to. A safer way might be to unprovision and reprovision the User Profile Synchronization Service - this should correctly set this permissions.

So, what caused this then? I've not yet found the actual source of the problem (which is frustrating to me at least), but I now how to fix it if it appears. Safe sources tell me that this might happen when you're doing a backup of the UPSS (and this is done in the correct way, which stops and starts the UPSS so no ongoing syncs are interfering with the backup). Question remains open...

Happy Christmas everyone!

SharePoint Online and External Data using JSONP

Posted at 2011-11-11 01:22 by Wictor Wilén in SharePoint 2010 , Office 365 with 1 comments.

It was some time since I did a real blog post and I have been fiddling with a specific topic, which I'm going to write about, for quite some time now. I've been working an Office 365 Intranet and been doing two conferences lately where I've demonstrated Office 365 and Windows Azure integration. One of the challenges (and boy, there are many) of Office 365 and SharePoint Online are access to External Data or services. In a few blog posts I will describe how you can work around these issues using some very simple techniques. All that is to it is that you have to "think outside the box" and not always go down the traditional SharePoint way of doing things.

So let's get started! How do I in my SharePoint Online solution access remote/LOB data in a SQL Server database, web service or what not? The first and obvious candidate most think of is Business Connectivity Services - didn't they announce that in Anaheim!? Yea, it can be done and it works - but not as you (and I previously) expected. Steve Fox (MSFT) did show it at the SharePoint Conference 2011 and also wrote a blog post about it. The caveat is that you have to go through the Client Object Model to access the data in the external list, not using the Sandboxed server side API - that dog won't hunt.

I'm going to do basically the same thing as Steve did but using a slightly different technique - which I find more easy and more straightforward, considering I'm not using the asynchronous Client Object Model but instead uses standard jQuery, jQuery templates JsRender, JSONP and WCF.

This is how we'll build this little sample. First of all we have a database stored in SQL Azure. This database is surfaced through a WCF endpoint in a Windows Azure Web Role. This WCF service will be consumed by a JavaScript using jQuery and JSONP as transport in a Web Part (I'll use a Sandboxed Visual Web Part for this) and rendered using JsRender (not jQuery templates which I recently shown in a few sessions).

The data flow

The secret sauce - JSON-P

First of all before digging into how this is actually implemented we need to sort out how we're actually going to transport data from the WCF endpoint to SharePoint Online.

The best and easiest way is to use JSON notation to transport the data; jQuery has great support for that and it's very easy to program using JSON structures in JavaScript. The only problem is that SharePoint Online and the WCF service is going to be hosted on different domains - and therefore it will be a cross-domain scripting issue. To overcome this issue JSONP (JSON with Padding) can be used. JSONP is a very clever method. Instead of returning a string from the remote domain and then being parsed by the caller, a JavaScript method is returned, which returns the JSON structure when evaluated, and this returned response is dynamically appended to the calling document as a script tag. Smart huh? Only problem is that we need to fiddle somewhat with our WCF endpoints, and that's what we'll discuss next...

Setting up the WCF endpoint

In this sample we need a database with one or more tables and then generate an ADO.NET Entity Data Model from that. That data model is then exposed through a WCF Data Service. WCF Data Services uses the OData protocol and supports JSON format but not JSONP. Fortunately I was not the first one lacking this feature and there is a simple extension you can download to accomplish this. This extension is an attribute that you add to your Data Service class and makes the service support the $format=json and $callback=? query string parameters.

Once you have downloaded and included the class into your project you decorate your DataService class with the JSONPSupportBehavior attribute and it should look something like this:

[JSONPSupportBehavior()]
[System.ServiceModel.ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class Users : DataService {
    public static void InitializeService(DataServiceConfiguration config) {
        config.SetEntitySetAccessRule("Users", EntitySetRights.AllRead);
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
    }
}

Now we're all set to consume this from SharePoint Online.

Consuming the JSONP enabled WCF endpoint from a Web Part

Create a new Empty Sandboxed SharePoint project and then add a Sandboxed Visual Web Part (make sure that you have the Visual Studio SharePoint Powertools installed to get this Sandbox enabled Visual Web Part). We're only going to use HTML and JavaScript for this one, so you could do the same thing using a Content Editor Web Part, SharePoint Designer or whatever you prefer.

Note: I'm using the new JsRender technique here, instead of the just recently abandoned jQuery Templates. The JsRender is not even in beta yet so the syntax might/will be changed over time. Read more about the change here.

First of all in our user control we need to import the jQuery 1.7 file. Instead of uploading it to our SharePoint site we'll use a CDN for this (which will boost your overall performance and save you one file to maintain).

<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.min.js"></script>/<

The JsRender.js file is not yet available on any CDN's so we have to add that JavaScript file into a new Empty Module SPI. You can deploy it to any folder or library, in this case I'm deploying it to the SiteAssets library of the site. Since we're talking about SharePoint Online here and we cannot guarantee that the file will be in a specific site this JavaScript file must be included dynamically or by using server side code to get the correct Web Url. We're doing the former one, and you will see the code in just a bit.

The next thing is to define some markup where we would like to show our data from the WCF service. We'll define a table with an id equal to "list" and add a nice default row, which just says loading (makes it a bit more nice to the user).

<h1>Users</h1>
<table>
    <tbody id='list'>
        <tr><td><img src="/_layouts/images/loadingcirclests16.gif" />Loading data.../</td></tr>
    </tbody>
</table>

After that we need to define the template that JsRender will use when applying the data to the table. This is done in a script tag using the type="text/x-jquery-tmpl" like this:

<script id="UsersTemplate" type="text/x-jquery-tmpl">
    <tr>             
        <td><b>{{=Name}}</b></td>              
        <td>{{=Company}}</td>         
    </tr>     
</script>

The final thing is to add the script that will load the data from the WCF service and then when it retrieves the response it will use the JsRender template to populate the table.

<script type="text/javascript">
    SP.SOD.executeOrDelayUntilScriptLoaded(doTheRemoteStuff, 'SP.js');
    var rootWeb;

    function doTheRemoteStuff() {
        var clientContext = new SP.ClientContext();
        var siteColl = clientContext.get_site();
        rootWeb = siteColl.get_rootWeb();
        clientContext.load(rootWeb);
        clientContext.executeQueryAsync(succeeded, failed);
    }

    function succeeded() {
        var elm = document.createElement('script');
        elm.type = 'text/javascript';
        elm.src = rootWeb.get_serverRelativeUrl() + '/SiteAssets/JsRender.js';
        document.getElementsByTagName('head')[0].appendChild(elm);

        $.getJSON("http://mycloudapp.cloudapp.net/Users.svc/Users?$filter=email ne ''&$format=json&$callback=?",
            function (data) {
                $("#list").empty();
                $("#list").html($("#UsersTemplate").render(data.d));
            });    
    }
    function failed() {
        SP.UI.Notify.addNotification('Something failed...');
    }
</script>

The script starts with using the Script-On-Demand features of SharePoint 2010 to delay execute the doTheRemoteStuff() function. Once the SP.js file is loaded the function is executed. The function will use Client Object Model to retrieve the Url to the root web, to ensure that this Web Part will work on sub webs as well. This is needed so that we dynamically can add the JsRender.js file that was added to the SiteAssets library in the root web.

Once we have the root web loaded the succeded() method is going to execute. This is where we first dynamically insert the JsRender.js file into the head element, referencing our own JsRender.js file. Once that is done we will use the jQuery getJSON method to get all users from the Data Service (in this case all users that has an e-mail address). To make the response a JSONP response it is important to add $format=json&callback=? to the query string in the getJSON method.

When the response is returned the table is cleared and the rendered data is added as inner HTML of the table. The jQuery extension method $(template).render(data) is the JsRender method that generates the HTML from the template and the JSON strucutre.

Once this project is deployed and activated in the Sandbox and the Web Part is added to a page it will first show you the loading message and then after just a second a nicely table with the data from your SQL Azure backend.

A SharePoint Online Web Part displaying data from a SQL Server Azure database

Summary

This post intends to demonstrate how to solve a very common problem in SharePoint Online - fetching data from LOB systems. I used SQL Azure and a Windows Azure Web Role hosted WCF service, but it can be any kind of JSONP supported WCF service. The holy grail in this case is to JSONP enable the WCF service.

Watch this space for a continuation of similar posts...

Recap of the European SharePoint Conference 2011

Posted at 2011-10-20 10:53 by Wictor Wilén in Windows 7 , SharePoint 2010 , Presentations , AppFabric with 1 comments.

European SharePoint Conference 2011Back home after a few days in Berlin for the European SharePoint Conference 2011. It was a great conference with good speakers and really nice attendees. It was three days full of sessions, expert panels, shoot-outs and SharePoint fun! Thanks to everyone who was there (especially those who came to my sessions :-) and the team behind the conference! And as always it great to meet up with the SharePoint MVP's, MCM's and now even MCA's!

During the attendee dinner the conference team announced the dates for the next European SharePoint Conference, which is set to the first week in December 2012. This one will not be in Berlin, but more likely in Barcelona, Paris or Copenhagen (Barcelona is the one everyone cheered for, so my guess is that the other two are out of question :-)

For this conference I did two development presentations. I've done similar sessions before but this time I changed them into be even more based on best practices and experiences from the field, since we're quite a bit into the product cycle. I got good feedback on it and in some of the sessions I attended I noticed the same approach from the speakers. For you who either didn't attend my sessions or didn't have time to write down all the code samples in your notebooks - you can find the presentations on the conference web site and you can find the code samples here:

I'm planning (note planning - no promises) on doing a couple of follow up posts on specifics in the demos.

Now it's only two more conferences this year; Singapore and Stockholm...

SharePoint Conference 2011 wrap-up

Posted at 2011-10-11 06:39 by Wictor Wilén in SharePoint , SharePoint 2010 with 2 comments.

I've now been home for about 48 hours since visiting Anaheim, California, for this years edition of the Microsoft SharePoint Conference. It has been a great week in California with colleagues, friends, clients and new acquaintances.

Superman at Six FlagsThis year, eight people from my company, Connecta, travelled over for the conference. We all had a blast with some spare time before and after the conference, which included a visit to Six Flags - Magic Mountain and a drive along the Pacific coast. We also met up with a few old friends and colleagues and had a good time with our clients, who also attended the conference.

Even though nothing new actually was shared during the conference (saving all the fireworks for next year in Las Vegas) it was a really great conference. I focused on the sessions where I knew the speakers would put on a great show, which I think was a clever choice - you can never experience that from the recordings or by downloading the decks. The keynote was pretty dull and just a big marketing show. The only highlights was the big fail-over demo and the MCA announcement. The MCA - Microsoft Certified Architect - is now available for SharePoint 2010 as well, read more on the Masters blog. Congrats to Spence and Kimmo - our two very first MCA's!

I got a lot of questions regarding the MCA program and two essential things were not mentioned in the keynote. First; MCM is a pre-requisite for the MCA and secondly; you need to be MCM on the same version as you're trying for MCA on.

Meet the Masters!?On Wednesday I sat in the Perficient booth for the Meet the Masters panel together with three MCM colleagues. I had a great time talking about my MCM experience and asking questions from the audience. It's great to see the that the recognition of the MCM program is increasing.

SharePoint conferences are more than just attending sessions! Compared to a lot of other technical conferences the SharePoint conferences is very much about the social activities. There are multiple vendor activities and community activities going on 24/7, ranging from SharePints to early morning runs. The Monday night I had four parallel parties going on! These activities are in my opinion one of the most important aspects of the SharePoint conferences. You meet your old friends and make new ones and broaden your network. You'll learn who's an expert in what which makes it more easier for you to get help or reach out when in doubt. Know what you know and know what you don't know - and never confuse those two! 

Now I'm looking forward to next week with a conference in Berlin, then Singapore a couple of weeks later...and of course - Las Vegas next year!

Changes in the SharePoint 2010 Cumulative Update packaging since August 2011

Posted at 2011-09-08 12:34 by Wictor Wilén in SharePoint 2010 with 1 comments.

A couple of days ago the SharePoint 2010 Cumulative Update for August 2011 was released. Always a good time to see some things fixed and some things break. Installing a Cumulative Update is always a risky business, and you should only install them if you any experience problems that the CU resolves and only when you thoroughly tested it.

One CU to rule them all!

Without going into details about the content and fixes in the August 2011 CU there is one other thing that is of real interest - and that is how MIcrosoft has changed the packaging process for the Cumulative Updates. Since the release of SharePoint 2010 there has been talk and discussions about über-packages. That is Server Cumulative Packages that contains both the Server hotfixes as well as the Foundation hotfixes, which makes the update process a bit easier and faster - you only need to install one package. Up until now there has been mixed messages on the über-packages and caused some confusion. The recommendation has been that you need to install both SPF and SPS CU's on a SPS installation and all three if you're using Project Server.

Since yesterday (that's when I noticed it at least) the SharePoint Updates page on MSDN has been updated with new information regarding this packaging with this:

The packaging of cumulative updates changed as of August 31, 2011. [...] As a result of the new packaging, it is no longer necessary to install the SharePoint Foundation cumulative update and then install the SharePoint Server cumulative update.

It looks like we have a new guidance in town!This has been "promised" before and I hope that it will work as planned this time, only time will tell. For more history and information read Spencer Harbars post on the SP1 and June CU discussion.

What this essentially comes down to is that you only need to download one of these patches (links to August 2011 CU within parenthesis) from now on...

  • SharePoint Foundation 2010, contains SPF CU (KB253050)
  • SharePoint Server 2010, contains SPF + SPS CU (KB253048)
  • SharePoint Server 2010 with Project Server 2010, contains SPF + SPS + Project Server CU (KB253049)

This will save you a couple of minutes/hours downloading and you'll save a few minutes installing multiple CU's on each server.

Note: The correct version of this CU should be 14.0.6109.5002, if you were really quick you might have downloaded the 14.0.6109.5000 build.

But...there's always a but. Please, please, please test all CU's, SP's, patches, hotfixes, shoes and whatever very thoroughly!

Conference and presentation season - fall 2011

Posted at 2011-09-01 04:58 by Wictor Wilén in SharePoint 2010 , Presentations with 0 comments.

This fall is going to be pretty busy in terms of conferences and presentations and I'll have my fair share. Here's what I've planned for this fall, so far.

Webinar: No Farm Solution in sight!

On Tuesday the 6th of September I will do a webinar discussing SharePoint Online and Office 365 and how you can build solutions using SharePoint Online, Silverlight, Windows Azure and more without creating any farm solutions:

When and where: 6th of September at 11:00 CET. The interwebz

Register online at http://www.sharepointeurope.com/upcoming-webinars/webinar-week-no-farm-solutions-in-sight.aspx

SharePoint in the cloud!? Does it work?

This is a breakfast seminar that my company Connecta is arranging with Cornerstone where I will present Office 365 and SharePoint Online specifically. I will show you how SharePoint Online works and what you need to do to get it to work, and I will also share our experiences moving from an on-premise solution with SharePoint and Exchange to the Office 365 platform.

When and where: 16th of September at 8:00 or 13:00. Stockholm at the Connecta office

More information at http://cornerstone.se/sv/Event/Frukostseminarium-SharePoint-i-molnet-Funkar-det/

European SharePoint Conference, Berlin

European SharePoint ConferenceFor the European SharePoint Conference I will have two sessions, which I already written about.

When and where: 17th - 20th October. Berlin, Germany

More information: http://www.sharepointeurope.com/

SharePoint Conference Southeast Asia, Singapore

SharePoint Conference Southeast AsiaFor the second year I will go down to the beautiful Singapore for the SharePoint Conference in Southeast Asia. This year I will also have two sessions.

  • Mastering customizations of the SharePoint 2010 Ribbon Menu
  • Enhancing Office 365/SharePoint Online using Windows Azure

I'm sure that the conference will be as great as last year!

When and where: 8-9 November. Singapore.

More information here: http://www.sharepointconference.asia/

SharePoint and Exchange Forum 2011, Stockholm

SEF 2011The SharePoint and Exchange Forum is the SharePoint and Exchange conference in Scandinavia and of course if you're in the vicinity you should head on over to Stockholm. This year Göran Husman and the crew has managed to get a really good line of presenters - it will be a blast! I will present one session at this conference, and it will not be a development topic, but instead a session about Service Application Federation - the good, the bad and the ugly!

When and where: 14-15 November. Stockholm, Sweden

More information here: http://www.seforum.se/

 

I hope to see you on the road somewhere!

Yet another object to dispose correctly in SharePoint 2010 - SPUserSolution

Posted at 2011-08-24 11:37 by Wictor Wilén in SharePoint 2010 with 0 comments.

If you've been in the SharePoint business for a while (at least a couple of days) you should be aware of the SharePoint objects that needs to be properly disposed; SPSite and SPWeb in particular. Objects that need disposal inherits from the IDisposable interface and requires that you call the Dispose() method when you're done with the object  - this is to ensure that the object frees up resources that the .NET managed garbage collector cannot free up automatically. This includes objects such as non-managed SQL connections, resource handles, file handles etc. Disposing objects is nothing unique for SharePoint - all (real) .NET developers know how to dispose of a SQL connection. You can read more about the best practices around disposing SharePoint objects in the MSDN Disposing Objects article. Not doing this properly will eventually lead to application crashes, high memory usage and/or bad performance.

The SPUserSolution object requires disposal

If you are working with sandboxed or user solutions in code you've probably used the SPUserSolution object. This is another of these objects that needs your disposal-attention. A solution package (farm or user code) is essentially a cabinet file (compressed file) containing all the solution artifacts and assemblies. When activating a user code solution programmatically in the solution gallery you will get this SPUserSolution object which internally will contain a number of stream objects (also inheriting from IDisposable) and a non-managed file handle. These object must be disposed manually to avoid any resource or memory leaks. Here is a proper way to add and activate a user code solution

byte[] bytes = ...;
// grab the solution gallery
SPDocumentLibrary solutions = (SPDocumentLibrary)newSite.GetCatalog(SPListTemplateType.SolutionCatalog);
// add the solution to the gallery
SPFile solutionFile = solutions.RootFolder.Files.Add("mysolution.wsp", bytes);
// activate Solution
using (SPUserSolution solution = newSite.Solutions.Add(solutionFile.Item.ID)) {
// do your thing...
}

Summary

This was just a sample and a reminder that you need to be aware of what's happening when working with some of the SharePoint objects - make sure that you do your "Disposal dance" the correct way. The list goes long on what objects need to be disposed correctly - just check your objects if they inherit from IDisposable using Visual Studio or Reflector. Not all objects do any specific disposing though and some can be ignored - but better be safe than sorry.

Tip: products such as CodeRush from DevExpress has some great built-in tools to directly identify objects inheriting from IDisposable and helps you make sure that they are properly disposed.

I'm on the SharePoint Pod Show talking about Web Parts

Posted at 2011-08-15 10:45 by Wictor Wilén in Personal , Web Parts , SharePoint 2010 with 2 comments.

The 65th SharePoint Pod Show is out featuring...tada...me :-)

The SharePoint Pod ShowThe SharePoint Pod Show is THE podcast about SharePoint and is done by Rob Foster, Nick Swan and Brett Lonsdale and has featured a lot of great SharePointers from all around the world throughout the years. If you haven't already listened to the podcasts, then you got 65 episodes to catch up on! There are some epic ones, such as my favorite one #50 - which is about performance tuning. And make sure that you subscribe - you don't want to miss their SPC11 Road-trip...

This episode was recorded at the MVP Summit earlier this year in Redmond between two sessions. It was my first time meeting most of the MVP's in real life and Rob was the one interviewing me. He's one heck of an interviewer asking questions like an ice-hockey radio commentator in some weird southern accent... It was great fun and we discussed SharePoint development and Web Parts development in particular. We talked through how to get started with SharePoint development, how to build Web Parts and why I wrote my book (SharePoint 2010 Web Parts in Action).

Until next time.

Improve performance of your SharePoint 2010 applications using Windows Server AppFabric caching

Posted at 2011-08-13 11:02 by Wictor Wilén in SharePoint 2010 , AppFabric with 2 comments.

Besides SharePoint my very dear topics is performance optimizations and new technologies, so here's a post mixing all these together.

Background

Caching is one way to improve the performance of any application, there are several ways to do it in-memory, disk etc etc. SharePoint 2010 has a set of caching capabilities, most of them are in-memory caches and some involve disk or even SQL based. One problem with (especially) in-memory caching is that if you have a farm different servers may display different results, which is due to the fact that the different servers cached information at different times. Another problem with in-memory caching is that it's per process, that is that you have different caches for different web applications and application pools.

Windows Server AppFabric is an extension to Windows Server. There's one cloud version of AppFabric in Windows Azure but there's also an on-premise installation of AppFabric that contains hosting and caching capabilities. AppFabric is a middle-tier service platform (the real middle-tier, not the other middle-tier :-) and can be used in all kinds of scenarios. The caching features of AppFabric is based on the Velocity project, which was one of my favorite acts for the PDC08 conference. It contains an easy to set up and configure distributed caching framework that can use SQL Server or disk as storage. In this post I will show you how to leverage the caching features of the on-premise version of AppFabric.

Using a distributed cache such as AppFabric can solve many problems. I've already mentioned a few such as the problems with in-memory caching. Other interesting things is that you can easily set up cross farm caching or even cross domain caching. You can have the caching on separate servers in the application tier. You can share the cache between web applications and service applications. The cache isn't tied to the application pool so any recycles of that will not clear the cache and so on...

Setting up and configuring AppFabric v1.1 CTP

AppFabric v1.1 CTP is really easy to setup. You install the binaries (download 1.0 via Web Platform installer or 1.1 directly here) on the first machine to host the distributed cache and configure the cache. Then you add new servers to that cache cluster. Very much like you do when setting up a SharePoint farm. Follow these instructions on MSDN, you can't fail (which you can't say with SharePoint).

Installing AppFabric

Configuration is used either using the configuration application or using PowerShell (what else did you expect). In this case I configured it to use SQL Server as backend. Using the disk based would ideally be used in cross farm/domain scenarios (think about that - having data up to date cross farms, that's cool!). Once AppFabric is installed you need to start the AppFabric caching  using the following PowerShell commands. First use Use-CacheCluster to set the context and then just Start-CacheCluster to start the cache. There is one final configuration that is needed and that is to allow the application pool account to access the cache. This is done using the Grant-CacheAllowedClientAccount cmdlet. If you forget to set this you will see an ERRCA0017 error. AppFabric contains tons of configuration options. You could setup different clusters, named caches etc etc.

Using the cache in a Web Part

Now on to the SharePoint bits. In this scenario I'll build a Web Part that fetches quotes from Yahoo, that is doing an HTTP request to get a quote. This is a common scenario where you would build some kind of cache to avoid HTTP latencies. Another problem with HTTP requests is that they might time out or take a long time. You need to call it at least once so the poor bastard that's loading your page first might suffer from it. In this case we could actually create a timer job that makes the requests and put the data in the AppFabric cache before it's requested. But for this simple demo let's settle with a Web Part.

Preparing your solution

Before building the actual Web Part we need to set up the project to use the AppFabric cache. First two references must be added; Microsoft.ApplicationServer.Caching.Core and Microsoft.ApplicationServer.Caching.Client. They are found in the c:\Windows\System32\AppFabric\ folder (even though some documentation says otherwise). I could not directly add them as reference in Visual Studio, it could not find the directory, so I copied the file from that folder to a custom folder first.

After adding the references we need to set up the configuration of our custom cache. Normally you do this using the application configuration file, but in SharePoint scenarios this doesn't work that well, so I'll do it all in code. In this sample I use hardcoded values for servers and ports - in a real world scenario you should of course make this configurable using for instance the P&P SharePoint Guidance Hierarchical Object Store. To access the cache we need to create a cache factory and retrieve our cache from that. Creating the cache factory object is an expensive operation so I'll implement this in a singleton thread-safe object to avoid creating the factory that many times. It looks as follows:

sealed class CacheUtility {
    private static DataCacheFactory _factory;
    private static DataCache _cache;
    private static readonly object _lock = new object();

    CacheUtility() { }

    public static DataCache CurrentCache     {
        get {
            using (SPMonitoredScope scope = new SPMonitoredScope("DataCache.CurrentCache")) {
                lock (_lock) {
                    if (_cache == null) {
                        List<DataCacheServerEndpoint> servers = 
new List<DataCacheServerEndpoint>(); servers.Add(new DataCacheServerEndpoint("SP2010", 22233)); DataCacheFactoryConfiguration config =
new DataCacheFactoryConfiguration() { Servers = servers }; _factory = new DataCacheFactory(config); _cache = _factory.GetDefaultCache(); } return _cache; } } } } }

As you can see in this class I have the DataCacheFactory object and the actual cache object (DataCache) as static variables. They are only created on the first request to the CurrentCache property. The DataCacheFactory object is instantiated with a configuration, in this case I'll just add one AppFabric cache server using the server name and the cache port.

Then let's add the Web Part to the project. In the Web Part class implement the function to get the stock quotes as follows:

public class Quote {
    public string Name;
    public double LastTrade;
    public DateTime DateTime = DateTime.Now;
}

public Quote GetQuote(string ticker) {
    using (SPMonitoredScope scope = new SPMonitoredScope("GetQuote")) {
        using (WebClient client = new WebClient()) {
            string tmp = client.DownloadString(
String.Format("http://finance.yahoo.com/d/quotes.csv?s={0}&f=nl1", ticker)); string[] arr = tmp.Split(new char[] { ',' }); if (arr.Length == 2) { return new Quote() { Name = arr[0].Trim(new char[] { '"' }), LastTrade = double.Parse(arr[1]) }; } } return new Quote() { Name = "Not found" }; } }

It's a simple method, GetQuote(), that retrieves the stock quote using the Yahoo Finance API. If the quote is found it returns a Quote object with correct values and if not an "empty" Quote object.

Also add a property to the Web Part so that we can turn on and off the caching:

[Personalizable(PersonalizationScope.Shared)]
[WebBrowsable]
[WebDisplayName("Use Cache")]
public bool UseCache { get; set; }

Now it's time to implement the actual Web Part, and as always it's done in the CreateChildControls, like this:

protected override void CreateChildControls() {
    using (SPMonitoredScope scope = new SPMonitoredScope("CachedWebPart.CreateChildControls")) {
        Quote quote = null;
        string ticker = "MSFT";
        if (UseCache) {
            DataCacheItem cacheItem = CacheUtility.CurrentCache.GetCacheItem("quote" + ticker);
            if (cacheItem != null) {
                quote = (Quote)cacheItem.Value;
            }
        }
        if (quote == null) {
            quote = GetQuote(ticker);
            if (UseCache) {
                CacheUtility.CurrentCache.Add("quote" + ticker, quote, new TimeSpan(0, 1, 0));
            }
        }
        this.Controls.Add(new LiteralControl(
            String.Format("Last trade for {0} is {1}, retrieved at {2}", 
                quote.Name, quote.LastTrade, quote.DateTime)));
    }
}

This method is also pretty straight forward. It checks if the cache is enabled and if it is it tries to retrieve the quote from the cache using the GetCacheItem method. If it's not found it uses the GetQuote method to retrieve the quote and if the cache is enabled it stores the quote in the cache. Finally it just prints out the quote value. That's it!

Test and evaluate

So let's take a look at this Web Part now using the Developer Dashboard (notice the SPMonitoredScopes I added to the code). Here's how it looks without the cache enabled. The call to the Yahoo Finance API takes about half a second - a real performance killer.

No caching

Once we turn on the caching, the first call to the CacheUtility class will initialize the cache and for subsequent calls use that cached factory and cache. Notice how the first hit which creates the cache actually takes some time and in this case the HTTP request takes a really long time!

Caching started

Then once the cache is up and running, retrieving the quote takes almost no time.

Caching in full effect

Improve performance a little bit more...

But it still takes about 10ms! This 10ms comes from that this is not an in-memory cache, it is actually stored in SQL Server. But hey, it's better than a couple of seconds. But I want to save an extra couple of cycles here. Ok, let's enable the client cache! Add the following row when configuring the cache factory and you will also have an in-memory cache that has a maximum number of object, a timeout and an invalidation policy.

config.LocalCacheProperties = 
    new DataCacheLocalCacheProperties(
        100, 
        new TimeSpan(0, 3, 0), 
        DataCacheLocalCacheInvalidationPolicy.NotificationBased);

In this case I set the invalidation policy to use notifications. To get this up and running you need to shut down the cache cluster and configure notifications for the cluster as follows:

Stop-CacheCluster 
Set-CacheConfig -CacheName "default" -NotificationsEnabled $true 
Start-CacheCluster

And now retry the Web Part and we'll see that this is more efficient:

Client cache enabled

Monitoring

The AppFabric cache also contains a lot of features for monitoring and logging. The simplest command is the Get-CacheStatistics that show you stats of the cache:

Cache stats

Summary

Next time you are thinking about caching in SharePoint (or any other .NET application for that matter) consider using AppFabric caching. It's a great and versatile middle-tier caching framework with near endless configuration possibilities. I know that this simple yet powerful framework can make a big difference in any of your projects. And why invent some own caching framework when we have something beautiful as this!

Stale Managed Metadata Databases in SharePoint 2010

Posted at 2011-08-08 12:32 by Wictor Wilén in SharePoint 2010 with 3 comments.

This is a short story about how you can get and resolve stale Managed Metadata Service (MMS) databases in SharePoint 2010. I've been working with Managed Metadata quite much and done some backup/restore juggling from production to test and to dev environments. Which by the way works really smooth. I've also recreated the MMS databases a couple of times.  After applying Service Pack and the re-released June 2011 CU I went into Central Administration to take a look at the databases and their upgrade status. This is what I found: four MMS databases, of which two didn't upgrade, and I only have two MMS service applications in this particular environment.

Database status

As you can see two of the databases reports "Database is in compatibility range and upgrade is recommended". There's no link to click to upgrade and there's no PowerShell command either to update them. These two databases were not connected to any MMS service application so it's no big deal, but who wants these kind of "warnings" in their CA.

To create these stale MMS databases is an easy task; just go to Properties of the MMS SA and change the name of the database. This will provision a new and empty database for you, leaving the old database still registered in the configuration database of SharePoint. I don't know if this should be considered a bug or not, of course the database should not be deleted automatically, but should they remain registered as databases in the configuration database?

So, in order to remove these databases, the easiest way is to fire up your favorite command line tool - PowerShell, and use a few lines of commands. This is how it's done:

First of all the Get-SPDatabase command will return all registered in your farm.

Get-SPDatabase

By using the Id of the database it's easy to get one explicit database into a PowerShell variable like this:

$db = Get-SPDatabase cb825c9d-8494-46fc-9ffc-3f81cffdfafc

Now that we have one of our stale MMS databases we can use the Delete() method of the Database object to delete the actual reference in the configuration database, like this:

$db.Delete()

This will only delete the reference (the persisted object) and not the database. If you would like to remove the database as well, you can use the Unprovision() method prior to the deletion:

$db.Unprovision()

If you do just an Unprovision of the database, and don't delete the database, the database status in the upgrade status page will say "Not responding":

Not Responding

That was it, a quick and short post about stale Managed Metadata Service databases - how they become stale and how you remove them.