Skip to main content
SharePoint Evolved, Small Steps for a Big Solution

Blog

Go Search
Home
Blog
Wiki
Contact
Themes
  

SharePoint Evolved > Blog
Fixing a 404 Error on CKS:EBE Blog Post

I was troubleshooting a colleague's blog, the blog in question had a post that would throw a 404 error whenever browsed to the full name of the post. If you're familiar with Community Kit for SharePoint, the Enhanced Blog Edition, you'll know that when you open a url to a post that doesn't exist or has been deleted, it redirects you to the main page of the blog, which makes this error even more intriguing. CKS:EBE was recognizing the post, but somewhere along the line, was not able to display the post.

I tried changing the title of the blog post to no avail, as well as created other posts that I thought would end up throwing the 404 error. What I ended up doing is changing the "BlogTitleForUrl" field on the post. It went from the original title,

To this title with an update prepended to the post.

And this fixed the problem that you can see here.

Announcing SharePoint Saturday Copenhagen

It is my pleasure to announce the first European conference of the SharePoint Saturday Series. The event will happen on August 22nd in the Copenhagen, Denmark. Come join SharePoint professionals in a day of learning and interacting in all aspects of SharePoint. Come hear talks on SharePoint Administration, Development, Architecture and more. There will be presentations that will engage anyone works with SharePoint. SharePoint Saturday is free to all attendees and a not for profit event.

Visit the SharePoint Satuday Copenhagen site: http://www.sharepointsaturday.org/copenhagen

Interested at speaking at SharePoint Saturday in Copenhagen? Contact spscph@live.com to receive a speaker submission form.

If you would like to sponsor Sharepoint Saturday Copenhagen, please send an email to spscph@live.com and we will send you a sponsorship package.

Microsoft to Spin Off Software and Licensing Services

I just received an email from Microsoft saying that they were transferring their Software And License Protection Service to their IP Venture which is called "InishTech". This is the email I received:

Dear Valued SLP Services Customer:

We are writing to share with you some important information about the Software Licensing and Protection Services (SLP Services) offered by Microsoft Corporation ("Microsoft").  Microsoft plans to transfer the SLP Services business to Inish Technology Ventures Limited ("InishTech"). InishTech is a new venture set up to focus on developing the global market for SLP Services. Microsoft is a shareholder in InishTech and will also continue as a customer of the SLP Services.

We are sharing this information with you ahead of time so that you receive this information from us first, not the press.  Since the official announcement of this transaction will not be until June 9, 2009, we ask that you keep this information confidential until that public launch date  InishTech will operate the SLP Services business and you will continue to be able to take advantage of the unique products and services that you are already enjoying.  Any agreement between you and Microsoft related to SLP Services will be assigned to InishTech as a result of this transaction.

We at Microsoft value our relationship with you, and we are confident that you will continue to receive great products, services, and support from InishTech. To ensure a smooth transition for all of our customers, we will continue to offer SLP Services support through our Customer Service and Support Division until September 24, 2009.  Microsoft will remain a partner and collaborator with InishTech, so rest assured we are vested in the success of this endeavor.  If you have any questions regarding this transition, please don't hesitate to contact me at slpsinfo@microsoft.com.   

Sincerely,

Bob Cadd

Global Account Executive

It seems that Microsoft will continue to support the current version with their customer support till the end of September, though beyond that InishTech will be responsible for the product. If you have not used the service, it is a great way to use license activation and obfuscation when paired with Dotfuscator. It seemed like a powerhouse when It came to knocking out some of their competitors, but in September of last year they stopped adding new customers to the Microsoft SLP System. Microsoft still has a stake in InishTech and will hopefully work with them to evolve this service. According to a MarketWatch article, Microsoft still has hopes for the product:

While Microsoft acquired the SLP business in 2007 to "take its core technology and develop it," Mansour said, the Redmond, Wash.-based company has since decided "to find a home where it can flourish." The SLP business quietly stopped accepting new orders late last year.
Source: MarketWatch

Here is hoping they can take a good product and make it even better.

A Perspective on Cloud Computing

I had the opportunity to attend a talk by David Chappel (http://www.davidchappell.com) of David Chappell & Associates on Friday about his perspective on Cloud Computing. The talk occurred Friday May 26th at the Microsoft Development Center in Copenhagen(http://www.mdcc.dk), otherwise known as the MDCC. At first I thought this was going to be a talk aimed at a small group of people, but a large group of probably 150 ended up attending. While the majority of the attendees were Microsoft employees, there were a large amount of people from outside of Microsoft.

He started off with a warm up generally covering the services that are out there such as Google's AppEnginge, Amazon's EC2 and Microsoft's Azure. After an overview he started getting deep into a comparison of the services that are out there, and here are some highlights that I thought were worth mentioning.

  • Google's AppEngine gives you 10 seconds to handle a request before spinning down the instance chosen to handle the request.
  • The two buckets these services fall into are now archaiac, Platform as a Service and Infrastructure as a Service are two restrictive and don't adequately categorize the services that are starting to mature.
  • The Azure Services are all individually built by separate teams at Microsoft… for now.
  • There is a difference between platform lock in and portability, mainly in custom development languages such as force.com.
  • SQL Services has a hard limit of 10gb, so scaling beyond that would take some finesse.
  • Table Storage in Azure is meant for very scalable applications
  • Queues in Azure are meant as an intermediary for data between web roles and worker roles
  • Each instance of a Web Role and Worker role is a "VM" within Azure

This is just a short example of the information that David was presenting, to find out more information about Cloud Computing from David Chappell, check out his blog where at lot of this information is featured. http://www.davidchappell.com/blog/index.php

 

Update: A slide deck very similar to the one that was presented at the MDCC can be found here: http://www.davidchappell.com/CloudPlatformsToday--APerspective--Chappell.pdf

Generating Test Tables with Azure Development Storage Fails

I ran into the following error when trying to create the Test Storage Tables from Within Visual Studio 2008.

Unhandled Exception: System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

         at System.Reflection.Module._GetTypesInternal(StackCrawlMark& stackMark)

         at System.Reflection.Assembly.GetTypes()

         at Microsoft.ServiceHosting.DevelopmentStorage.Table.DatabaseGenerator.GenerateDataBase(String server, String dbName, String[] assemblyPaths, Boolean forceCreate, ValidationHandler validationHandler)

         at Microsoft.ServiceHosting.DevelopmentStorage.Table.Program.Main(String[] args)

Took me forever to figure out what the problem was, but essentially the Azure tools try to generate entities from every dll referenced in your project, and it expects the dlls to be in either the GAC or the Bin folder of the WebRole. Now if you've integrated other projects into your Azure project, this might not be the case. The solution then is to run DevGenTables Manually using parameters similar to below.

"c:\Program Files\Windows Azure SDK\v1.0\bin\DevtableGen.exe" /forceCreate "/database:YourDatabaseNameHere" "C:\pathtoproject\Azure_WebRole\bin\Azure_WebRole.dll;C:\pathtoproject\Azure_WebRole\bin\StorageClient.dll;C:\pathtoproject\Azure\AzureWorker\bin\Debug\AzureWorker.dll"

 

You'll need to change the command to specify the dlls you are using in your project, but once that is done, you should see a message like this:

Windows(R) Azure(TM) Development Table database generation tool version 1.0.0.0 for Microsoft(R) .NET Framework 3.5
Copyright (c) Microsoft Corporation. All rights reserved.

DevTableGen : Generating database 'Azure'
DevTableGen : Generating table 'TableStorage' for type Azure_WebRole.TableStorageEntity'

Simple SharePoint URL Shortener

Based on a request in Linked IN Discussion, I wanted to show how you can create a simple URL shortener using a SharePoint's Links list as well as a custom aspx page.

Step 1

To start off you should create a simple links list in SharePoint.

Once You've created the links list and populated it with the links that you want to share, open up SharePoint Designer.

Step2

Create a blank ASPX Page in SharePoint Designer, place the page at the root directory of your SharePoint site, and name it something appropriate.

You can see here that I've created a blank ASPX page and put it in the root directory as well as given it a name of "redir.aspx".

Step3

You will need to insert a single item view of the Links List you are using on the current page. Find the links list in the Data Source Library in SharePoint Designer.

Select the drop down triggered by the down arrow to the right of the list name, and select "Show Data".

Select only the URL field and Where it says "Insert Selected Fields as" click and select "Single Item View".

This should be your end result when you create the single item view. Go ahead and save your page so you don't lose your progress.

Step 4

Specify The details of the web part. Select the third option from the top where it says "Paging: 1 item(s) per set".

Change it so it only displays one item from the list, mainly because we don't want to send the client multiple places if the ID specified is incorrect or gets deleted.

Next select the third option from the bottom, "Parameters"


Select the "New Paramter" Button.


You'll want to specify a name such as "LinkID". You'll also want to specify the Paramter Source which is Query String, and the Query String Variable is "ID", and you have the options of specifying the default value if no ID is provided, I went ahead and provided the first item of my list.

Now that we have the parameter set up, we need to filter based on the parameter in the url. Select the first option in the properties named "Filter".


Create a filter rule that compares the ID Field to the LinkID parameter as outlined in the picture, and select OK.

Step 5

Now that we have the URL that we want, we need to tell the browser to redirect to the present URL. Find the section that looks like below:

<xsl:template name="dvt_1.rowview">

<tr>

<td>

<table border="0" cellspacing="0" width="100%">

<tr>

<td width="25%" class="ms-vb">

<b>URL:</b>

</td>

<td width="75%" class="ms-vb">

<a href="{substring-before(@URL, ', ')}">

<xsl:value-of select="substring-after(@URL, ', ')"/>

</a>

</td>

</tr>

<xsl:if test="$dvt_1_automode = '1'" ddwrt:cf_ignore="1">

<tr>

<td colspan="99" class="ms-vb">

<span ddwrt:amkeyfield="ID" ddwrt:amkeyvalue="ddwrt:EscapeDelims(string(@ID))" ddwrt:ammode="view"></span>

</td>

</tr>

</xsl:if>

</table>

</td>

</tr>

</xsl:template>

Replace it with the following code:

<xsl:template name="dvt_1.rowview">

<tr>

<td>

<xsl:text disable-output-escaping="yes">&lt;script type=&quot;text/javascript&quot; language=&quot;javascript&quot;>window.location=&quot;</xsl:text>

<xsl:value-of select="substring-before(@URL, ', ')"/>

<xsl:text disable-output-escaping="yes">&quot;;&lt;/script&gt;</xsl:text>

</td>

</tr>
</
xsl:template>

Step 6

Save and test it out. You can check out my version here:

http://www.sharepointevolved.com/redir.aspx?ID=2 should redirect to http://volitionservices.com/pages/sharepooch.aspx


 

Using Twitter and Skype for Portal Presence Information

This is a follow up to the webcast I presented for SharePoint Saturday in DC May 2nd 2009. The goal is to enable presence information on usernames within a SharePoint site. This works well when you don't have Office Communication Server to leverage, and while it is not a replacement, it can be useful still. You can launch chat sessions or call the user from the presence dialog from within SharePoint. You'll also be able to see the users latest status from twitter, and you could go a step further by enabling a reply to that user. While this script is in essence a prototype, its not far off from being very useful to those who wanted to take it to the next level. So without further ado, here we go.

Step 1: jQuery Your SharePoint Site

The first step is to get jQuery and put it somewhere on your site. Visit http://www.jquery.com to find the latest version of the script and download a copy to your computer.

Once you have it downloaded drag it to the images directory, or a directory of your choosing on your SharePoint site. You can see here that I've uploaded both the development versions and the minified versions for different purposes.

Step 2: Create Your Presence List

Create a custom list and add the following fields:

Column (click to edit)

Type

Required

Twitter

Single line of text

ADUser

Person or Group

Skype

Single line of text

Phone

Single line of text

 

You'll end up with a list that looks similar to this: Don't forget to populate it with our own data.

Step 3: Prepare Your Script

Copy the following script into notepad or a text editor:

<script src="http://www.sharepointevolved.com/images/jquery-1.3.2.js" type="text/javascript"></script>

 

    <script type="text/javascript">

      

 

    /*

    * Configuration settings for the Twitter Presence List

    */

    var twitterNameField     = "Title";             //Name of the field used for the twitter name

    var twitterNameFieldInt = "Title";             //Internal Name should be the same, but just in case its different or has spaces

    var adNameField          = "ADUser";         //Name of the Field with the Active Directory User

    var adNameFieldInt          = "ADUser";         //Internal Name should be the same, but just in case its different or has spaces

    var skypeNameField        = "Skype";            //Name of the field used for the Skype Name

    var skypeNameFieldInt    = "Skype";            //Internal Name of the field used for the Skype Name

    var phoneNameField        = "Phone";            //Name of the field used for the Skype Name

    var phoneNameFieldInt    = "Phone";            //Internal Name of the field used for the Skype Name

    

    var listName         = "{B5B2B296-9B79-4950-862E-5163DFDA3BC5}";        //Name/Guid of the list you're storing the values in

    /*    

    *    Url, Relative to the SharePoint site with the list.

    *    This link should not be terminated with a "/" forward slash

    *     Since "/_vti_bin/lists.asmx" will be appended;

    *    IE: "http://www.sharepointevolved.com" would be ""

    */

    var urlToSite         = "/presence";    

    

    /*

    * Script by Isaac Stith http://www.sharepointevolved.com

    * Modify below this line at your own risk

    */

    var lastLookupId = "";

    var lastLookupName = "";

    var curTweeter = null;

    var curElement = null;

    var curSkype = null;

    var curPhone = null;

    var foundTName = false;

    var readyToClose = false;

      

$(document).ready(function() {

 

 

//Lets put some javascript here!

        $("a[href*='userdisp']").hover(

function () {

setNotReadyToClose();

var loc = $(this).attr("href");

var name = $(this).html();

        var id = loc.substring(loc.indexOf("=")+1,loc.length);

        curElement = $(this);

        getTwitterName(id,name);

},

function () {

    setReadyToClose();

}

);

 

});

function getTwitterName(id,name)

{

if(lastLookupId != id)

{

removeOldBox();

    var soapEnv =

"<?xml version=\"1.0\" encoding=\"utf-8\"?> \

<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'> \

         <soap:Body> \

         <GetListItems xmlns='http://schemas.microsoft.com/sharepoint/soap/'>\

         <listName>"+listName+"</listName> \

         <query><Query><Where><Eq><FieldRef Name='"+adNameField+"' /><Value Type='User'>"+name+"</Value></Eq></Where></Query></query> \

         <viewFields><ViewFields><FieldRef Name='"+adNameField+"' /><FieldRef Name='"+twitterNameField+"' /><FieldRef Name='"+skypeNameField+"' /><FieldRef Name='"+phoneNameField+"' /></ViewFields></viewFields> \

         <rowLimit>0</rowLimit> \

         <queryOptions><QueryOptions/></queryOptions> \

         </GetListItems>\

         </soap:Body>\

        </soap:Envelope>";

        lastLookupId = id;

        lastLookupName = name;

        foundTName = false;

     $.ajax({

     url: urlToSite + "/_vti_bin/lists.asmx",

     type: "POST",

     dataType: "xml",

     data: soapEnv,

     complete: getTwitterNameCallback,

     contentType: "text/xml; charset=\"utf-8\""

     });        

     }

     else

     {

         //Same information being retreived, check and see if the div is closed

         if($("div#tweeter").html() ==null)

         {

             popupFromJson();

         }

     }

}

function removeOldBox()

{

    if($("div#tweeter").html() !=null)

    {

        $("div#tweeter").remove();

    }

}

function getTwitterNameCallback(xData, status)

{

     $(xData.responseXML).find("listitems").children().children().each(function(){

             if(foundTName ==false){

                  var title = ($(this).attr("ows_"+twitterNameFieldInt));

                  var usr = ($(this).attr("ows_"+adNameFieldInt));

                  curSkype = ($(this).attr("ows_"+skypeNameFieldInt));

                  curPhone= ($(this).attr("ows_"+phoneNameFieldInt));

                  var curid = usr.substring(0,usr.indexOf(";"));

                  if(lastLookupId == curid)

                  {

                      getTwitterStatus(title);

                      foundTName = true;

                      return;

                  }

             }

     });

      

}

function getTwitterStatus(username)

{

        $.getJSON("http://twitter.com/status/user_timeline/"+username+".json?count=1&callback=?",getTwitterStatusCallback);

}

function getTwitterStatusCallback(json)

{

        curTweeter = json;

        popupFromJson();

}

function popupFromJson()

{

        //Need to get all the parameters we want to display and put them ina nice little tooltip

        var outdiv = "<div id='tweeter'><img src="+$($(curTweeter).attr("user")).attr("profile_image_url")+" height='25'/>"+$(curTweeter).attr("text")+"<br/><a href='skype:"+curSkype+"'><img src='http://mystatus.skype.com/smallicon/"+curSkype+"' style='border:0px;'/></a> <a href='skype:"+curSkype+"?call'>Skype Call</a> | <a href='skype:"+curSkype+"?chat'>Chat</a> | <a href='skype:"+curSkype+"?call'>Skype Call</a> | <a href='skype:"+curSkype+"?add'>Add</a> | <a href='skype:"+curPhone+"?call'>Call Phone</a></div>";

        $(curElement).after(outdiv);

        var pos = $(curElement).position();

$('div#tweeter').css("top", pos.top+10);

$('div#tweeter').css("left", pos.left+25);

}

function setReadyToClose()

{

readyToClose = true;

window.setTimeout(finallyClose,2000);

}

function setNotReadyToClose()

{

     readyToClose = false;

}

function finallyClose()

{

     if(readyToClose==true){

          $("div#tweeter").remove();

     }

}

        function EnsureIMNControl()

        {

        

        }

        

        

    </script>

<style type="text/css">

    div#tweeter{

        background-color:#FFFFCC;

        border:3px black groove;

        margin: 5px;

        padding-right: 5px;

        padding-top: 5px;

        padding-left: 5px;

        padding-bottom: 5px;

        position:absolute;

        }

    div#tweeter img{

        

        vertical-align:text-top;

        border: 1px black solid;

        padding: 2px;

        margin-right:5px;

        float:left;

    }

    div#tweeter a {

    text-decoration:underline;

    color:black;

    vertical-align:bottom;

}

</style>

 

The only thing you have to change if you've followed the instructions are the listName and the url to site properties in the configuration section. You Can find the listId by going to the list settings of the Presence list and looking at the end of the URL.

You'll need to change the urlToSite property to the relative url to the site you're currently working on. You may also need to change the location of the jQuery file depending on where you've placed it on the site.

Step 4: Master your Master Page

Now that your script is ready, it is time to put it in your Master Page. Open up your master page in SharePoint designer and find the closing body tag. Should look like this:

You're going to paste the script you've modified for your use right above the closing body tag, then go ahead and save the master page.

If you've gotten this far should have successfully modified your site to see the presence information when you hover over a username. As an added bonus, I've removed the function that calls Microsoft's presence information in the EnsureIMNControl().

Step 5: Show of your brand new presence to your coworkers!

Or email meInsertATHereisaacstith.com

Webcast: Using Twitter and Skype for Presence Information Inside SharePoint

I have create a webcast talking about how you can use Skype and Twitter to provide presence information within SharePoint. The goal is to use Twitter to give the latest status of a user within SharePoint, and use Skype to enable voice or chat communications from within SharePoint. While this is not a replacement for Office Communication Server, it could be seen as a Stop Gap for companies or teams that have not deployed a communication infrastructure within their enterprise.

So head on over to the SharePoint Saturday Washington, DC site and see the webcast. And while you're there, why not donate to the canned food drive, you might win an hour with me in which we could implement this solution on your portal!

 

 

Also look for an upcoming blog post with specific instructions and the script used in the video .

3 Steps to Use the New Sample Themes on Your Site!

Microsoft recently released 10 new sample themes to base your site on a couple weeks ago, Daniel Brown has created a solution that will install these themes as a feature on your site[Link]. This is good for those that have access to the servers, but what about for those that do not? It is possible to upload the actual images and style sheets to your site to achieve the same affect. Be warned that the application pages will not be affected by this modification, only y a site theme change. You can do this in 3 simple steps, and should be able to make the change in less than 10 minutes.

 

Theme Name

Link to Download

Construction

[Link]

Contoso

[Link]

Corporate

[Link]

Events

[Link]

OARP

[Link]

Procurement

[Link]

Publishing

[Link]

Sporting

[Link]

Startup

[Link]

Team

[Link]

 

 

Step 1: Download and Extract

Locate the theme that you want to use on your site, download the chosen theme and extract the contents to a location on your computer. Before you upload it to your server you'll need to modify the CSS file in the directory.

Step 2: Modify the CSS

Open up the CSS file of the chosen theme in SharePoint designer. You will need to replace the "_layouts/1033" with the location you plan on uploading the files. In our case it'll be on the "Themes" Site in the Images directory, so we replace the text with "/themes/".

Step 3: Upload and Link Stylesheet

I chose to upload mine to the Images directory under my Themes site, this makes it easy to keep with the Themes structure.

Now that we have the theme uploaded, all we need to do is add the style information to the Master Page. Open up default.master in SharePoint Designer and insert the following line right before the closing line of the header.

<link rel="stylesheet" type="text/css" media="screen" title="oarp2" href="/Themes/images/oarp2.css" />

You'll need to replace the location of the stylesheet with the relative location of your theme's css file.

Save and congratulations! You've just modified your look and feel. This is what it looks like on my site.

See The New Microsoft Themes in Action

Last week Microsoft released 10 new themes for SharePoint which you can download here: [Link] Daniel Brown has created a solution where you can install these themes and get them on your site from the central admin. You may want to see these themes in action before you go ahead and push them out, or use them as a base for your branding. It is possible however to take the individual themes and use them without making server modifications. I will post more information on this later.

I was able to configure these themes for use without having server access to install a solution, by extracting the individual files themselves. I thought I would post the themes so people can make the decision to see if they're worth the effort.
Visit: http://www.sharepointevolved.com/themes/default.aspx to view the different themes that Microsoft in action.

You can use the theme switcher in the right header to switch between the available themes.

 

The theme should persist as you navigate through the site. This is just so you can visualize the themes, but I plan on showing how to make these themes available without server access in a following blog post

-Isaac

 

1 - 10 Next