Archive for March, 2008

LINQ to SharePoint

March 28th, 2008 by Tobias Zimmergren

For those of you who’s new to LINQ (Language Integrated Query), here’s a brief description:
 
"General-purpose query facilities added to the .NET Framework apply to all sources of information, not just relational or XML data. This facility is called .NET Language-Integrated Query (LINQ). "
 
I was just about to start up a new project where I wanted to make LINQ-like queries to SharePoint, but when I did some research I found out that there’s a CodePlex project called LINQ to SharePoint that does about the same as I was about to start doing.
 
If you’re interested in LINQ and SharePoint, and perhaps an integration between the both – check it out: http://www.codeplex.com/LINQtoSharePoint
 
Hopefully there’ll be some further development on the project even though it’s been quiet for a while…
 
Good weekend!

Stress Testing SharePoint Solutions with Visual Studio 2008

March 27th, 2008 by Tobias Zimmergren

One of my pals, MVP Liam Cleary, posted a very interesting article on how to use Visual Studio 2008 to test the performance of your SharePoint Solution.
 

Since I just got my own blog up and running with the Enhanced Blog Edition kit (www.codeplex.com/cks), I thought that it’d be fun to compile a list of bloggers that run the EBE for SharePoint.

For now it’s not a very long and thrilling list, but hopefully it’ll grow!

If you’ve got a blog running SharePoint EBE (or just SharePoint), please let me know and I’ll add it to the list.

SharePoint Bloggers running SharePoint + Enhanced Blog Edition

Author: Tobias Zimmergren

I got a chance to finally try the blueprints out, and it works fine. It’s a couple of steps on the way that needs to be performes, listed below.

What you need to think about when setting it up is to make sure the following pre-requisities are installed on your SharePoint server:

  • .NET Framework 3.5 installed
  • Service Pack 1 for SharePoint (WSS 3.0 / MOSS 2007 depending on which version you run)
  • Silverlight 2.0 beta 1 runtime browser plugin
  • Configure the *.xap file type extension as a MIME type in your IIS webserver as: application/x-silverlight-2-b1
  • Configure the web.config using the ASP.NET 3.5 AJAX tags and the Silverlight configurations

Since I make an assumption that you guys already know how to complete the first few tasks here, I’ll just give you the web.config changes that needs to be made and then you can simply run the Setup for the Blueprints and have a whole lot of Silverlight/SharePoint fun.

Changes that needs to be done in your SharePoint application’s web.config in order to run Silverlight applications

This section will give you a walkthrough to what you need to do in your web.config in order to get the Silverlight Blueprints up and running.

Under the <configSections>-element, add the following code:

<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
  <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
    <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
    <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere" />
      <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
      <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
      <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
    </sectionGroup>
  </sectionGroup>
</sectionGroup>

Under the <assemblies>-element, add the following code:

<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>

Under the <pages>-element, add the following code:

<controls>
  <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
  <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</controls>

Under the <httpHandlers>-element, add the following code:

<remove verb="*" path="*.asmx"/>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>

Under the <httpModules>-element, add the following code:

<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

Under the <runtime>-element, add the following code inside the <assemblyBinding>-tag:

<dependentAssembly>
  <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
  <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>
<dependentAssembly>
  <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
  <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
</dependentAssembly>

Under the <configuration>-element, add the following code at the end (in the bottom of web.config)

<system.webServer>
      <validation validateIntegratedModeConfiguration="false"/>
      <modules>
        <remove name="ScriptModule" />
        <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
      </modules>
      <handlers>
        <remove name="WebServiceHandlerFactory-Integrated"/>
        <remove name="ScriptHandlerFactory" />
        <remove name="ScriptHandlerFactoryAppServices" />
        <remove name="ScriptResource" />
        <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode"
             type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode"
             type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      </handlers>
    </system.webServer>

Time to install and deploy the Silverlight Blueprints and try the Silverlight Web Part out!

If you’ve come this far and ensured that your SharePoint site still runs with the newly added lines of code, and you have ensured that all the aforementioned pre-requisites are fulfilled – You’re ready to go!

  1. Run setup.exe for the Blueprints Hello Silverlight 2 Web Part and make sure that the System Check passes all tasks
    Silverlight Blueprints Setup
  2. Define which web applications that you would like to deploy this webpart to (tip: the one you’ve edited web.config for would be a good choise ;-)  ) – In my case it’s http://zimmergren:8003 
    Define where the solution should be deployed
  3. Just hit next and let the installation and deployment complete – Sit back and relax for those sweet 8 seconds.
  4. Navigate to the site application where you installed the Blueprints (In my case http://zimmergren:8003 which is a normal Collaboration Portal), from there, click the following:
    1. Site Actions
    2. Site Settings
    3. Modify all site settings
    4. Site Collection Features
    5. Activate on the feature called "Silverlight BluePrint for SharePoint: Hello Silverlight 2 Web Part" 

      Activate the Silverlight BluePrint for SharePoint web part

  5. If you havn’t already, create a new Blank Site (for ease and simplicity) and call it anything (I called mine Blueprints)
  6. Do the following:
    1. Site Actions
    2. Edit Page
    3. Click "Add a Web Part"
    4. Locate the section called "Silverlight BluePrint for SharePoint"
    5. Choose the Web Part called "Silverlight BluePrint for SharePoint: Hello Silverlight 2 Web Part"
      Add the Silverlight WebPart to your SharePoint page
  7. You’re all set. Cross your fingers and hope that it all works :-)

Proof that it actually works

On this screenshot you can see that the Web Part works, and when I right click you see the Silverlight menu as in any other Silverlight application.

Hello Silverlight 2 Web Part Proof Of Concept

And here’s another image with the Picture Viewer Silverlight WebPart:

Silverlight BluePrint for SharePoint Media Viewer Web Part Proof of Concept

Known Issues

  • If the version of your Silverlight 2.0 beta1 runtime differs from the one the Blueprints were compiled with, you’ll end up with an empty white webpart – although you can rightclick and get the Silverlight menu to show. In order to fix this problem, simply open the source project in Visual Studio and recompile it – then copy the .xap file to your setup’s ClientBin folder and replace the one there. (Or simply copy it to your filesystem directly to e.g. C:InetpubwwwrootwssVirtualDirectories8003ClientBinSL.HelloSilverlight2SL.XAML.HelloSilverlight2.xap
    • This problem was solved after conversating with Patrick, so – I now owe you a beer when I see you Patrick!

Last words

I sincerely hope that this helps you out in the process of configuring and getting your Silverlight Blueprints for SharePoint up and running quickly and with ease!

Thanks for tuning in, please leave a comment or drop a line in the mail – appreciate it! :)

Posted by; Tobias Zimmergren on http://www.zimmergren.net

Technorati Tags: , ,

New Blog: WSS 3.0 SP1 + Win Server 2008

March 17th, 2008 by Tobias Zimmergren

I just got this new blog up and running with Windows SharePoint Services 3.0 SP1 on a Windows Server 2008 machine.
 
It’s running really smooth and I hope it will be just as good as the one before.
 
Have a good day, and don’t forget to hook up the new RSS-feed ( www.zimmergren.net/rss.xml )
Author: Tobias Zimmergren
Url:
http://www.zimmergren.net

Yep. It’s me again…

I managed to salvage most of the data from the bluescreen a couple of hours earlier (due to the persistent use of source control).

I’ll cover this topic more in details in one of the days to come, for now – this is what it looks like:

 slclock

Please do comment!

Have a good night everybody! I sure will, now.

Bluescreen of Death on my VPC

March 13th, 2008 by Tobias Zimmergren

I completed my integration project with Silverlight 1.0 and SharePoint 2007 – which doesn’t requiry any configuration on your server, except to install my Web Part with the .wsp solution.

But…

Instead of giving you a nice guide on how to implement and integrate Silverlight, Microsoft gave me a Bluescreen of Death smacked in my face when I was copying my files to the source control environment.

 bluescreen

Anyhow, it’s not such a big loss. I think most of the things are checked into the Source Control environment already, so i just need to set up a new VPC – seeing as this one doesn’t even start anymore :S

Hang in there a few days and you’ll have your Silverlight 1.0 integration served on a Silverplate!

Keep in touch.

Author: Tobias Zimmergren
Url:
http://www.zimmergren.net

If you’ve read my last two blogposts you already know how to configure ASP.NET 2.0 AJAX for your SharePoint Server and how do deploy a UserControl that uses AJAX functionality on you SharePoint Server.

You can find my previous articles here:

This blogpost shows a simple implementation of a UserControl that uses the Object Model to query the search service using a keyword and then using an UpdatePanel in AJAX to present the result to the user without any page reloads.

Let’s create an AJAX based UserControl which purpose will be to search using the Search Query Object Model

Copy the nessecary assemblies to your local bin folder (I’m deploying locally to the WebApplication on port 80)

To make this work (in this case, since I’m deploying to the UserControls folder with inline code, not calling any own assemblies) you need to copy the two .dll files to your /bin folder of the WebApplication where you want to deploy this UserControl.

  1. Copy C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12ISAPIMicrosoft.Office.Server.dll
  2. Copy C:Program FilesCommon FilesMicrosoft Sharedweb server extensions12ISAPIMicrosoft.Office.Server.Search.dll
  3. Paste the two files to C:InetpubwwwrootwssVirtualDirectories80bin (Note: It can be any other port other than 80 if you’re deploying to another WebApplication)

The reason that we copy these files to our deployment target’s /bin is simply that I’m deploying locally to that WebApplication and some of the namespaces and classes that we need to use in order to be able to query the Search Object Model are availible in those assemblies. There’s better ways to accomplish this, but to keep it simple I’m going with this approach.

Create the custom AJAX UserControl that will query the SharePoint Search Query Object Model

For simplicity, I’ll reference all the servercode inside the <script> block and not using a code-behind assembly.

  1. Launch Visual Studio 2005 (or whatever version you’re running)
  2. Create a new file based on the "Web User Control" template, name it as you please
  3. Add the following tags just below the Control directive:

    <%@ Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI" TagPrefix="asp" %>
    <%@ Import Namespace="Microsoft.Office.Server" %>
    <%@ Import Namespace="Microsoft.Office.Server.Search.Query" %>
    <%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>

    It could look something like this:
     searchajax1

  4. Just below all the references you just added, add the following code:

    <script runat="server">

    </script>

  5. Add the following code right below the references you just added. This code is simply to give us a simple user interface for the user to perform the search from:

    <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">
        <ProgressTemplate>
            <img src="http://zimmergren/hostedImages/ajax-loader.gif" alt="Searching…" style="border: 0px none #fff;"/>
        </ProgressTemplate>
    </asp:UpdateProgress>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            Enter a keyword to search for<br />
            <asp:TextBox ID="tbSearchString" runat="server" Width="230px"/><br />
            <asp:Button ID="btnSearch" runat="server" Text="Search" OnClick="btnSearch_Click" />
            <asp:Literal ID="literalSearchResults" runat="server" />
        </ContentTemplate>
    </asp:UpdatePanel>

    It could look something like this:
     searchajax2

  6. Insert this code inside the <script>-tag you created earlier:

    protected void btnSearch_Click(object sender, EventArgs e)
    {
        // Job insurance, to pause and show that the UpdateProgress works
        System.Threading.Thread.Sleep(2000);
        try
        {
            string startTable = "<table style="width: 100%;">";
            string endTable = "</table>";
            string searchResultItem =
            "<tr>" +
                "<td><a href="{0}">{1}</a></td>" +
            "</tr>" +
            "<tr>" +
                "<td>" +
                    "<em>{2}</em>" +
                "</td>" +
            "</tr>" +
            "<tr>" +
                "<td>Site: {3}</td>" +
            "</tr>" +
            "<tr>" +
                "<td style="padding-bottom: 10px;">Author: {4}, Item Size: {5}</td>" +
            "</tr>";

            string outputResults = startTable;

            ServerContext context = ServerContext.GetContext("SharedServices1");
            KeywordQuery keywordQuery = new KeywordQuery(context);

            keywordQuery.ResultTypes = ResultType.RelevantResults;
            keywordQuery.EnableStemming = true;
            keywordQuery.TrimDuplicates = true;
            keywordQuery.QueryText = tbSearchString.Text;

            ResultTableCollection results = keywordQuery.Execute();
            ResultTable resultTable = results[ResultType.RelevantResults];

            if (resultTable.RowCount == 0)
            {
                literalSearchResults.Text = "Sorry, your search didn’t return any results";
            }
            else
            {
                while (resultTable.Read())
                {
                    outputResults += string.Format(searchResultItem,
                        resultTable.GetString(5),
                        resultTable.GetString(2),
                        resultTable.GetString(6),
                        resultTable.GetString(8),
                        resultTable.GetString(3),
                        resultTable.GetString(4));
                }
            }
            outputResults += endTable;
            literalSearchResults.Text = outputResults;
        }
        catch (Exception ex)
        {
            literalSearchResults.Text = ex.Message;
        }
    }

    Instead of going all crazy about how the code actually works with the Search Query Object Model, I’m just pasting the code here for you to try and will explain the Search Query Object Model in another article.

Deploy the UserControl
  • Copy or Save the UserControl to the following location: C:InetpubwwwrootwssVirtualDirectories80UserControls and you’re all set.

If you’ve configured AJAX and installed the SmartPart you should be all set and be able to use it. See this short post on using the SmartPart if you don’t know already.

Final Result

This is what it looks like when you hit the button (the red image spins around for 2 seconds (see the code, Thread.Sleep(2000)) to show how it will look if it’s a heavy query and needs some loading time.
 searchajax3

This is what the result will look like, note that everything is done within an UpdatePanel and we do not experience the page to reload, or any visual postbacks.
 searchajax4

Download the UserControl here

SharePoint Cross List Queries in a custom UserControl

March 9th, 2008 by Tobias Zimmergren

Author: Tobias Zimmergren
Url:
http://www.zimmergren.net

I got the question last week weather it’s possible to get items from all lists of <your chosen type here> gathered and displayed on one page.
This is – like most things – possible in SharePoint without any greater efforts. With something called Queries we can use the object model to query SharePoint and get a result quite painlessly.

To demonstrate a very simple example, I’ve created a very small usercontrol (for use with Jan Tielen’s SmartPart) that looks like this:

 crossqueries1

This code will combine all the items in all of the TaskLists on the current SiteCollection and display them in a simple GridView as seen above in the screenshot.

Code for the Cross List Query UserControl

 crossqueries2

 crossqueries3

Simple enough, huh?
Of course you can create webparts, usercontrols, application pages, or any other type of application to interact with the object model in this way. I chose to do it using a UserControl for the ease of deployment, testing, development and demonstration.

For your conveniance I’ve uploaded the UserControl (.zip) here so you can download it.

Silverlight (2.0) Blueprints for SharePoint

March 3rd, 2008 by Tobias Zimmergren

Author: Tobias Zimmergren
Url:
http://www.zimmergren.net

Hi people, been really busy the last couple of weeks and havn’t had the time to answer your mails nor write any new blogposts.

However, I just felt that I needed to get this link out there for you guys to check out in case you havn’t already: http://www.ssblueprints.net/sharepoint/

"Open Source Source Code and Full Blueprint coming soon" – Sounds promising

While you check out that link, I’ll try to figure out the topic of my next MOSS post ;)