Entries in SharePoint (44)

Monday
Feb282011

SharePoint central administration tip - use those resource links

Some of the service application administration pages in SharePoint 2010 are incredibly hard to get to.

Hands up who knows - in their head right now, without checking their central administration: how to get to User Profile Service Application, or Search Administration page?

For those of you that don't want to be hunting for the link - find them once, and add them to the Central Administration Resources links on the right hand side of the landing page.  There's a big empty links web part there waiting to be used!

 

image

 

I should probably give them better names.

Wednesday
Jan192011

Silverlight + SharePoint - add to web part gallery

This article covers how to go about packaging a webpart for the Silverlight XAP file and deploy it to Web Part Gallery.

In the previous article I described the steps to create a SharePoint project and deploy the XAP file via a site feature.

Silverlight + SharePoint 2010 - package XAP file in a sandbox WSP Solution

But the user still needs to manually:

  1. Find the XAP file URL
  2. Manually insert a Microsoft out of box Silverlight Web Part
  3. Paste the XAP URL
  4. Save the Silverlight Web Part (may have to configure InitParams too).

Let's simplify this a little.

Go back to the <Elements> Module, and lets add a webpart

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="SilverlightCamera">
    <File Path="SilverlightCamera\SilverlightCamera.xap" Url="Style Library/SilverlightCamera.xap" />
    <File Path="SilverlightCamera\SilverlightCamera.webpart" Url="_catalogs/wp/SilverlightCamera.webpart" />
  </Module>
</Elements>

 

The webpart file itself is very simple: go to Web Parts Gallery, find and export Microsoft's Silverlight.webpart

<?xml version="1.0" encoding="utf-8"?>
<webParts>
  <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    <metaData>
      <type name=
"Microsoft.SharePoint.WebPartPages.SilverlightWebPart, Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
      <importErrorMessage>Cannot import this Web Part.</importErrorMessage>
    </metaData>
    <data>
      <properties>
        <property name="Title" type="string">Silverlight Camera Web Part</property>
        <property name="Description" type="string">A web part to display a Silverlight Camera.</property>
        <property name="Url" type="string">~sitecollection/Style Library/SilverlightCamera.xap</property>
        <property name="Height" type="int">300</property>
      </properties>
    </data>
  </webPart>
</webParts>

 

You may have noticed that the Url is a SiteCollection relative (~sitecollection/) path, so that no matter whether it's a root site collection or a managed path, we want the user's experience to be perfect.

Unfortunately - that syntax doesn't work, not without one extra hack via the Feature Event Receiver.

Feature Activated Event Receiver

 

Right click on the feature and add a new event receiver.  VS.NET will generate the CS file.

clip_image002

Figure: right click on the feature (.feature) and add an event receiver. 

 

Waldek has a magical event handler code that fixes this problem

http://blog.mastykarz.nl/inconvenient-content-query-web-part-server-relative-urls/

So I'll just post my bit of code here

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    // one day when I meet Waldek in person I will buy him beer
    // http://blog.mastykarz.nl/inconvenient-content-query-web-part-server-relative-urls/
    SPSite site = properties.Feature.Parent as SPSite;
    if (site != null)
    {
        SPList webPartsGallery = site.GetCatalog(SPListTemplateType.WebPartCatalog);
        SPListItemCollection allWebParts = webPartsGallery.Items;
        SPListItem webPart = (from SPListItem wp in allWebParts
                              where wp.File.Name == "SilverlightCamera.webpart"
                              select wp).SingleOrDefault();
        if (webPart != null)
        {
            string siteCollectionUrl = site.ServerRelativeUrl;
            if (!siteCollectionUrl.EndsWith("/"))
            {
                siteCollectionUrl += "/";
            }
            string fileContents = Encoding.UTF8.GetString(webPart.File.OpenBinary());
            fileContents = fileContents.Replace("~sitecollection/", siteCollectionUrl);
            webPart.File.SaveBinary(Encoding.UTF8.GetBytes(fileContents));
        }
    }
}

 

During Feature Activated - find the webpart and fix the ~sitecollection marker with the real site collection URL.

 

Deploy and activate the feature again.

clip_image002[5]

 

Success!  Our .webpart now appearing in the web part gallery.

Wednesday
Jan192011

Silverlight + SharePoint 2010 - package XAP file in a sandbox WSP Solution

This is a long series of blog posts on developing, debugging and deploying Silverlight and SharePoint solutions.

http://johnliu.net/blog/2010/6/18/develop-and-deploy-silverlight-sharepoint-2010-solutions.html
http://johnliu.net/blog/2010/6/22/develop-and-deploy-silverlight-sharepoint-2010-solutions-par.html
http://johnliu.net/blog/2010/6/28/develop-and-deploy-silverlight-sharepoint-2010-solutions-par.html
http://johnliu.net/blog/2010/10/18/silverlight-sharepoint-2010-did-you-just-deploy-customizatio.html

 

Assuming by this point, you have built a XAP file from a Silverlight project, and can deploy it manually to SharePoint by uploading to a SharePoint document library and link up Microsoft's Silverlight web part to "play" your XAP file.

Now let's see how we can build a WSP package.

Create a SharePoint Project in your solution

 

clip_image002

Figure: Add a new Empty SharePoint Project

 

clip_image002[5]\

Figure: Provide a debug site, and choose Sandboxed solution

 

clip_image002[7]

Figure: Add a module to this project - you should give it a good name

 

clip_image002[9]

Figure: Select Properties of this module…

 

The following is very special.  If you blink you will miss this!

 

From the Module's properties, find Project Output References and open this dialog.
Then from the dialog

  • select "ElementFile" for deployment type
  • select the project output of your Silverlight project

This step ensures that the Silverlight project output (XAP file), is automatically included as an element file in your SharePoint module. 

Magical!  But very well hidden UI.  Most people don't know it's there!

clip_image002[11]

Figure: Add the Project Output to this module.

 

Open up the module.xml file and check:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="Module1">
    <File Path="Module1\SLSPConf.xap" Url="Style Library/SLSPConf.xap" />
  </Module>
</Elements>

I set the destination URL to be Style Library.  You can put it elsewhere but you'll need somewhere where people can actually have read-access.

 

Deploy to Solution Gallery

 

clip_image002[13]
Figure: Deploy the Silverlight solution to Solutions Gallery - you can activate the sandbox solution here.

 

clip_image002[15]

Figure: Activate the site feature

 

VS.NET debugging tip

 

Go to the properties for the SharePoint project.  Select the SharePoint tab, and scroll right down.

  • Tick "Enable Silverlight debugging"
  • Untick "Auto-retract after debugging" - this one makes VS.NET deploy and activate when F5.  But as soon as you stop debugging VS.NET will retract the solution - so your Silverlight stops working!

 

clip_image002[17]

Figure: VS.NET SharePoint project settings.

Friday
Aug132010

SharePoint enable iFilter for TIFF OCR

In some companies, paper documents are scanned into TIFF formats and stored electronically.  To search for them, you'll need to enable the TIFF OCR iFilter to allow SharePoint to index TIFF documents.

1. Install Windows Server feature Windows TIFF IFilter:

clip_image002

 

2. Enable OCR filter

clip_image002[7]

 

clip_image002[10]

 

3. You may need to restart the machine

4. Force SharePoint to perform a full crawl from Search Administration

5. Search for your file - here, I'm searching for "Therefore"

tiff-ifilter2

Friday
Aug132010

SharePoint Saturday Sydney

Hi again.  This is a rather delayed blog post summarizing SharePoint Saturday Sydney #SPSSydney that was held last weekend on 7th August 2010.  This was organized by @BrianFarnhill and Lewis

SILVERLIGHT AND SHAREPOINT APPLICATIONS

Again, I brought along my little demo on Silverlight and SharePoint applications, again heavily tweaked from my previous presentation in the SharePoint user group.

The new agenda was:

  1. SharePoint + Silverlight Application
  2. XAP Deployment and Sandbox Solutions
  3. Debugging
  4. Light up SharePoint - Out of Browser

I never did have enough time - it all finished so fast at 50minutes.  And I didn't get to show my really awesome Silverlight Camera demo. 

The strict timing was actually great - gave me good ideas about re-organizing the content.  I should start quickly onto the demos, and then switch back to the PowerPoint summary points at the end as a summary, after people have seen the demo.  That would have worked really well, and consolidated my time, as well as giving the talk a suitable finishing touch.

SHAREPOINT SATURDAY SYDNEY

With my talk out of the way I juggled the rest of the day between: helping out people wandering around looking slightly lost, or wanted to catch up on some examples of Silverlight applications.  Ducking into sessions (usually at the 10minute mark where there's no one wandering outside anymore), to either learn something new, see how others present, or just to heckle another speaker and cheer them on!  Winking smile

  • @laneyvb - Workflow in SharePoint 2010
  • Roger Carran - The Managed Metadata Service - Exposed!
  • Ishai Sagi - New SharePoint 2010 features for End Users
  • Brian Farnhill - Exploring Office Web Applications and Services
  • Ivan Wilson - Building a public blog on SharePoint 2010
  • Eric Cheng - Developing and Deploying SharePoint Customisations Using Visual Studio 2010

Between different sessions most people managed to stayed on until the very end (to win some prizes), and from the guys that I've talked to most of them are heading home with new ideas of using their SharePoint 2010.

All in all a day full of lots of fun and laughter.  Thanks for organising this.

I took some panorama pictures with my iPhone and stitched them.

MORNING INTRODUCTION

IMG_3206 Stitch

 

AFTERNOON PANEL


IMG_3212 Stitch

More pictures for SharePoint Saturday Sydney 2010

Friday
Aug062010

SharePoint 2010 GlobalNavigationNodes Moved

This is a very short blog, but it appears that the GlobalNavigationNodes member on the PublishingWeb class has moved in SharePoint 2010.

http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.publishing.publishingweb.globalnavigationnodes(office.12).aspx

In SharePoint 2007, this was under Microsoft.SharePoint.Publishing.PublishingWeb.GlobalNavigationNodes

http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.publishing.navigation.portalnavigation.globalnavigationnodes.aspx

In SP2010, this has moved under Microsoft.SharePoint.Publishing.PublishingWeb.Navigation.PortalNavigation.GlobalNavigationNodes

 

This particular property is used to read a publishing site's navigation settings - I've used this to export site navigation as XML to accompany a site export.  Since site exports doesn't seem to include any customized site navigation information.  (It still doesn't in SP2010).

 

Friday
Jul232010

SharePoint 2010 with IIS URL Rewrite 2.0

Or, how do you remove /Pages/ from SharePoint URL.

Almost all the hard work is done by Waldek Mastykarz (@waldekm)
http://blog.mastykarz.nl/friendly-urls-sharepoint-site-4-steps-iis7-url-rewrite-module/

These are just my extra notes for SharePoint 2010, I'm going to assume you are reading Waldek's article with this blog as a supplement.

How to install IIS URL Rewrite

The easiest way is via the MS Web Platform Installer

clip_image002

On a good connection you are good to go within 30 seconds - faster if you already have MS Web Platform Installer on the server.

Installed, IIS URL Rewrite 2.0 lives here

clip_image004

IIS URL Rewrite 2.0

I seriously think there's a bug with IIS Url Rewrite 2.0's Regex

Waldek's regex pattern for step 3 is perfect:

^(.*/)?Pages/([^/]+)\.aspx$

and so is step 4:

^(.*/)?Pages/default.aspx$

BUG: IIS URL Rewrite matches badly - see screenshot:

clip_image006

Regex will try to maximize to match as many characters as it can. But this simply does not explain why group 1 match includes Pages/ - Why was Pages/ included in the match? This doesn't make any sense.

You can test the pattern with any other regex library, including .NET (via PowerShell), and you still won't get the stupid buggy match that is IIS URL Rewrite's regex…

(Sorry I'm annoyed that this caused a lot of problem for something that shouldn't have existed...)

$pattern = [regex] "^(.*/)?Pages/default.aspx$"

$result = $pattern.match("Publishing/Pages/default.aspx")

$result.Groups[1]

Success : True

Captures : {Publishing/}

Index : 0

Length : 11

Value : Publishing/

Anyway, to fix this we need to tweak the pattern

^(.*?/)?Pages/([^/]+)\.aspx$

^(.*?/)?Pages/default.aspx$

This will finally force IIS URL Rewrite to work properly.

clip_image008

the extra ? tells regex to try to match as little as it can, while still making a match.

clip_image010

Final result – the order is important – see Waldek’s article

 

TRICKS: Debugging URL Rewrite by enabling trace

When things don't work - this is your only hope. Read trace logs.

clip_image012

clip_image014

clip_image016

clip_image018

clip_image020

Fortunately it's not very hard to read, I mean we read SharePoint logs and survived. It's just tedious to read logs in general.

Open the log in Internet Explorer - which picks up the XSL and gives you a nicer looking UI. Head over to the compact view tab, and look for URL_REWRITE_START

clip_image022

 

HORRIBLE PITFALL: URL Rewrite Cache

I've noticed that when you reshuffle a rule (or add a condition to a rule), it doesn't force the cache to bugger off. So you thought you tweaked the rule but it doesn't seem to have any effect. The trace log will tell you that it actually is ignoring your rule reshuffle because it is listening to the "Url Rewrite Cache".

clip_image024

This is OK, until you have a bad URL cached, then suddenly it's annoying. IIS Reset doesn't cut it.  My tip that I ended up with is to toggle a rule's disable/enable state to trigger the URL Rewrite cache to refresh.

clip_image026

 

SharePoint Authenticated

WARNING: I've had SharePoint on various unknown occasions suddenly raise a login dialogue. I can't reproduce this on demand, but it happens frequent enough that I think it's no accident. It also sometimes goes away when I hit F5 refresh and Windows Authentication just works and I don't see any login prompt at all.

The experience reminded me highly of the days in 2007 where sometimes SharePoint will mysteriously ask you to sign in when you are supposedly browsing the site anonymous.

Please test thoroughly.

 

SharePoint Anonymous

For a public anonymous website, this works absolutely great - no authentication to worry about either.

clip_image028

I didn't do much testing with the postbacks and the ribbon. They do work, but I think I'll need a lot more testing to work out if everything is still OK.

My gut feeling is that SharePoint 2010 relies a lot more on AJAX-based client side calls without a full page postback. While the URL rewrite would have affected the postback somewhat, AJAX calls would be largely immune to this problem.

Summary

Definitely try this out on your SharePoint site and I think you'll be surprised how well it worked (once you get it to work). Thanks Waldek for sharing!

Tuesday
Jul202010

Sydney SharePoint User Group 20 July 2010

Presented an updated version of my Silverlight and SharePoint solutions talk in the Sydney user group tonight.  I don't think I timed the presentation well and lost way too much time in the beginning in XAML - which made everything seemed harder, and getting to the fun part much later.

  • Will improve - won't type XAML again, will highlight what's interesting but avoid fiddling live.

Honestly lots of room to improve but I think it was still interesting to a lot of people.  If you were there tonight and feels otherwise please let me know!

Feedback I've received:

  1. Demo at least "worked" even though really slow going in the beginning
    • Will improve, in fact given 1hr I don't think I'll type out the XAML again in the future - this will give me far more time to spend in the code, as well as getting to the fun part a lot quicker
  2. Need more time spend to show end-user Silverlight debugging (no modification to the server required)
    • Which I think would be a lot better use of the time
  3. Need more time to show some nice integration examples
    • Such as my Silverlight Camera which definitely raised eyebrows.
    • And if I can ever get my Silverlight PivotViewer to a decent, presentable state…
    • But basically, people need to see the features that Silverlight and SharePoint brings to the table separately, and why they are suddenly super awesome together.  Have an idea to draw a chart that'll blow everyone away - wait for it on SharePoint Saturday.
  4. Something went wrong at the one-hour mark, where my IE decided to go offline, which made further demo really difficult.  My suspicion is that Fiddler2 died somehow and IE thinks everything has gone funny and offline. 
    • Might have fixed itself by restarting IE.
  5. Definitely need more question time, and end with more links

 

 

Lots of links for news:

A bunch of links I promised Brad Saide, to add to the SharePoint news for the past month:

Productivity Hub 2010
http://www.microsoft.com/downloads/details.aspx?familyid=4AAA9862-E420-4331-8BC3-469D7BAE0FF1&displaylang=en

SPF2010 Update via @dougleung http://sharepointsix.blogspot.com/2010/07/sharepoint-2010-sharepoint-2010-just.html 
http://support.microsoft.com/kb/2032588

Windows Update broke WSS3 (with Windows Internal Database)
http://blogs.msdn.com/b/sharepoint/archive/2010/06/22/installing-kb938444.aspx 
Lesson - don't use automatic windows update on your production SharePoint farm

Friday
Jul162010

SharePoint ClientContext.List is missing?

The SharePoint Object Model has:

  • SPContext Members
  • SPContext.Current (static)
  • SPContext.Site
  • SPContext.Web
  • SPContext.List

By comparison, the SharePoint Client Object Model only has:

  • ClientContext Members
  • ClientContext.Current (static)
  • ClientContext.Site
  • ClientContext.Web
  • ClientContext.List (AWOL missing!)

Here's one trick I've started using - the current list exists on the page in javascript (ctx.listName)

So using Silverlight's Javascript bridge I'm able to test and pull that value back into Silverlight - without any looping through the ClientContext.Web.Lists.

string listName = string.Format("{0}", HtmlPage.Window.Eval("ctx.listName"));
// using string.Format to take care of null problems
// the ctx.listName looks like a guid

List list = _clientContext.Web.Lists.GetById(new Guid(listName));

 

So taking a step back, this would be the first time I wrote something that uses both client object model at once!

Friday
Jul162010

SharePoint 2010 and Silverlight 4.0 Webcam

Tonight's Silverlight play involves Silverlight 4 Web Cam API, and SharePoint 2010 Client Object Model.

SILVERLIGHT 4 WEBCAM API

Silverlight 4's WebCam API is relatively simple:

_captureVideoDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
_captureSource = new CaptureSource();
VideoBrush brush = new VideoBrush();
brush.SetSource(_captureSource);

WebCameraCapture.Fill = brush; // fill rectangle "render" area

var device = _captureVideoDevice.FriendlyName; // check device name during debug
if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
{
    _captureSource.Start();
}

The most interesting part is probably the RequestDeviceAccess call. This call must be initiated in an UI event (click) and will raise the following dialog

clip_image002

 

TAKING SNAPSHOTS

Once the camera is rolling, clicking the button takes a snapshot and saves it back to the document library.

WriteableBitmap bmp = new WriteableBitmap(WebCameraCapture, null);
MemoryStream stream = new MemoryStream();
// didn't want to save as bitmap - convert to JPEG first
EncodeJpeg(bmp, stream);

var fileCreationInfo = new FileCreationInformation();
fileCreationInfo.Content = stream.ToArray();
fileCreationInfo.Url = string.Format("pic_{0}.jpg", DateTime.Now.Ticks);
var _documentLibrary = _clientContext.Web.Lists.GetByTitle("ListName");
var uploadFile = _documentLibrary.RootFolder.Files.Add(fileCreationInfo);
_clientContext.Load(uploadFile);
_clientContext.ExecuteQueryAsync(delegate{}, delegate{});

In this screenshot I've added the Silverlight web part on top of the asset library list.

clip_image004

 

WHAT ABOUT VIDEO?

This is where we'll probably get stuck. Silverlight 4 has API to access camera, and we're able to save bitmap data from the camera, but Silverlight 4 lacks the client side encoding libraries capable of saving the bitmap stream back into any meaningful format such as MPEG.

Until Microsoft provides one, or some 3rd party writes one, saving video back to SharePoint document library is going to get put on hold.

REFERENCE

The code for converting to JPEG I copied from http://stackoverflow.com/questions/1139200/using-fjcore-to-encode-silverlight-writeablebitmap.

DOWNLOAD

The Silverlight Camera XAP binaries are in this XAP file 

The Silverlight Camera Sandbox Solution and read me file 

 

INSTALLATION

  1. Upload the XAP file to a document library, copy the URL to this XAP file.
  2. Create a document library to host all the pictures, open the web part zones on the view page and insert a Silverlight Web Part - use the URL to XAP from step 1.
  3. Remember to refresh the page to see new pictures - the list doesn't refresh automatically.  You can switch on async properties in the web part editor for the pictures and it will update itself on a timer basis.

UPDATE

20 July - Added sandbox solution WSP and a simple read-me file