Mobile LOB webpart pages in Sharepoint

by Jesper Persson 17. June 2009 16:53

One of the things Microsoft never quit has got its grip about is the support for mobile devices in Sharepoint, I know that it’s possible to get mobile views of lists and navigation by appending an m to the url like this http://servername/m what this does is simply redirecting you to /_layouts/mobile/mbllists.aspx page, one thing comes to mind here is that you are redirected to the _layouts folder which indicates this is an application, the pages are of the SPMobilePage type which inherits System.Web.UI.MobileControls.MobilePage that inherits the normal Page class like a normal LayoutsPageBase does via UnsecuredLayoutsPageBase.

But what’s the problem?

The problem as I see it are that you do not have a way of extending the pages with webparts if you need it, and on the other hand if you create a normal web part page and saves it to a page library the total page size will be very large and prevent the mobile device performing at a acceptable pace.

This is caused by Sharepoint, because it injects links to external js and css files that the device must load. I was recently hired as a consultant where the customer used Sharepoint and integrated with DynamicsAX.

Dynamics comes with a lot of webparts that was required to run on a Motorola hand terminal, which was used to scan barcodes. The problem was that the total page size was so large that the terminal was slowed down; the users didn’t need any special rights on the portal so Site Actions was not shown, and the need for the webpart menu wasn’t needed either.

But whenever Sharepoint sees a webpart it automatically loads core.css, init.js, ie55up.js (depending on browser) and core.js.

The challenge

We need to be able to select what the page returns depending on what you want to do. E.g. editing a page or using it from a hand terminal. So we need a way to control the output from Sharepoint without scarifying the functionality of the page. The goal was that an entire page must not exceed 10kb.

The measurements

I created a new master page based on the default.master called mobile.master, and a new page for testing purposes called mobilepage.aspx.

I used Fiddler2 to measure the payload of the page the result was as follows:

Even with everything removed from the Mobilepage.aspx and the masterpage we still have a payload of approx. 150KB that’s about 15 times more than acceptable also the chart says it all, about 80% is javascript, which is totally unnecessary in this scenario, in this demo the only thing want to show is this:

 

Naturally a more rich webpart will be used in a real world scenario.

Request filters and httpmodule to the rescue

After trying a few different approaches, one of them was to insert <Sharepoint:ScriptLink runat=”server”/> web control into the masterpage. That solved some of the issues concerning the core.js, but that’s only 70KB of the 140KB needed. I was still stuck with a lot of javascript.

Step 1 Create a httpmodule in C#

To do that two things have to be done first create a class that implements the IHttpModule interface and update web.config in the <httpModules> section      

<add name="MobileModule" type="Minimum_Payload.HttpFilter, Minimum Payload, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c23d6c989c59848d" />               

namespace Minimum_Payload
{
 
public class HttpFilter :IHttpModule   
 
{

    #region IHttpModule Members        
     
public void Dispose()       
     
{}
      HttpApplication _context = null;       
     
public void Init(HttpApplication context)       
     
{
           
       
_context = context;
           
       
context.ReleaseRequestState += new EventHandler(context_ReleaseRequestState);       
     
}
      void context_ReleaseRequestState(object sender, EventArgs e)        
      
{
        if (string.IsNullOrEmpty(_context.Request.QueryString["mobile"])) return;            
       
_context.Context.Response.Filter = new MobileFilter(_context.Context.Response.Filter);
       
     
}
                     
   
#endregion
   
  
}
} 

One of the requirements was the ability to control whether it was a normal browser or a mobile device, for this demo I choose the querystring.

Step 2 Create the Filter

I used this post as inspiration from 4guysfromrolla

public class MobileFilter : MemoryStream   
{
        Stream _output = null;
        public MobileFilter(Stream output)
        {
            _output = output;
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            string page = UTF8Encoding.UTF8.GetString(buffer);
            if(page.ToLower().Contains("<script>"))
            {
                int indexOfScript = page.IndexOf("<script>") + 8;
                int indexOfLastScript = page.IndexOf("</script><SCRIPT LANGUAGE='JavaScript' >");
                page = page.Remove(indexOfScript, indexOfLastScript - indexOfScript);
            }
            if (page.ToLower().Contains("</title>"))
            {
                int indexOfTitle = page.IndexOf("</title>");
                int indexOfLastTitle = page.IndexOf("<title>",indexOfTitle);
                page = page.Remove(indexOfTitle, indexOfLastTitle - indexOfTitle);
            }
            _output.Write(UTF8Encoding.UTF8.GetBytes(page), offset, UTF8Encoding.UTF8.GetByteCount(page));
         }
    }

This filter is very simple and I won't recommend that you use it in a production environment, but as an example it works well. The result of the payload of the page are shown here

smallpayload

Conclusion

It is possible to reduce the payload of the page and truly enable mobile devices using webparts. However I do not think that this scenario are supported by Microsoft and I also think that you should take great care in when using custom httphandlers in Sharepoint. Mainly because all request will pass through it, and this could degrade performance.

Source code

Minimum Payload.rar (8,62 kb)

Tags: , , , , ,

Visual Studio 2010 Beta 1

by Jesper Persson 27. May 2009 05:40

Visual Studio 2010 has been released in Beta 1 so as a Sharepoint developer my first thought was to get my hands on the much advertised Sharepoint templates for Sharepoint. But to my disappointment I was unable to find any, so I guess I just have to wait a little longer

Here's some screenshots of the start page and Add new project.

You have to choose .NET 3.5 and the only two templates are the ones for workflows.

 

Please let me know if this is totally wrong, I would love to try them out.

Tags: ,

How to slipstream Sharepoint with Service pack 2

by Jesper Persson 15. May 2009 15:03

After reinstalling my developement environment so it would run on a Windows 2008 server in 64 bit to accomodate the requirements for a future update to Sharepoint 2010, I found my self searching the web for guides on installing Sharepoint on a 2008 box, I've done it before but naturally I have forgot all about how to do it, so here's a guide to how you should go about that.

First you need to download the two updates for WSS and MOSS respectively,
http://www.microsoft.com/downloads/details.aspx?FamilyId=79BADA82-C13F-44C1-BDC1-D0447337051B&displaylang=en 
http://www.microsoft.com/downloads/details.aspx?familyid=B7816D90-5FC6-4347-89B0-A80DEB27A082&displaylang=en 
just save them to any location you prefer, it's not important.

You need to copy all the sharepoint installation files to you harddrive.

open a command prompt and navigate to the folder where the updates are saved and type the following command:

Select the location of you Sharepoint installation files

 
It's important that you select the Updates folder for the extracted files.

Press OK, a EULA will be shown


Accept the terms and press Continue

Repeat the steps for MOSS SP 2

Select the same folder as before 

Accept the license terms

Verify that all files has been extracted to the Update folder, and you are ready to install Sharepoint

SP 2 is a cumulative update which means that it contains all previously released updates, more info an be found at these KB articles http://support.microsoft.com/kb/953338 http://support.microsoft.com/kb/953334

Enjoy!

Tags: , ,

Modifying Quick launch bar with JQuery

by Jesper Persson 1. April 2009 18:24

The Quick launch bar 

Many people are annoyed with the Quick Launchbar, because it quickly gets very large; I'm going to show how this can be solved with JQuery. I was inspired by a post made by Jan Tielens, you can read more about it here. I'm not going to claim to be any kind of expert with regards to JQuery so it's a learning experience for me too.

But what is wrong?

   

Well, there's nothing wrong with it by default, but it really takes up a lot of space and you need to scroll down the page just to see all the links, like this screenshot, not that many lists but a lot of space taken up. I know it's possible to remove the lists from the quick launch bar but then you need mere clicks to get the information.

It's obvious that this needs to be fixed.

JQuery

Unfortunately all the items in the quick launch are all using the same CSS classes so I haven't been able to find a way (yet) to select the individual sections. So this will only work on all the sub items. Insert this code into a Content Editor Webpart:

<style type="text/css">
   .myRowHighlight {color:red; background-color:#FFCC66}
</style>

<script>
$(document).ready(function()
 {
       $("table[class='ms-navSubMenu2 zz2_QuickLaunchMenu_8']").hide("slow");
       $("table[class='ms-navheader zz2_QuickLaunchMenu_4']").hover
        (
            function() {
                $("table[class='ms-navSubMenu2 zz2_QuickLaunchMenu_8']").show("slow");
            }
        );

       $("#OuterLeftCell").hover
        (
             function() {
                 $("table[class='ms-navSubMenu2 zz2_QuickLaunchMenu_8']").hide("slow"); 
             }
        );
 }
);

</script>

I have tested this in IE8 in normal and compatibility mode, Firefox, Opera and Safari and it looks fine in every one of them.

Update Update I managed to find someone that made a better implementation where the individual sections are expaneded check out this great post http://www.endusersharepoint.com/?p=985

Tags: , ,

Search does not work when accessed remotely

by Jesper Persson 25. March 2009 22:25

After setting up my Virtual PC with MOSS 2007 I tried to access the site from the host, the address did not get resolved by the DNS so I choose to access it by IP, everything worked great but when I used search I got this error:

Object reference not set to an instance of an object.   at Microsoft.Office.Server.Search.WebControls.CoreResultsWebPart.OnLoad(EventArgs e)
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Control.LoadRecursive()
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

I found an answer on MSDN you can see it here http://social.technet.microsoft.com/forums/en-US/sharepointsearch/thread/b5afd264-07a8-4f66-9d78-807b11bb6022/ it explained the problem but did'nt really solve it for me because of the DNS issue so I cant use the FQDN.

So the resolution was straight forward I just added the IP in the Alernate Access Mappings.

 

Tags: , ,

Contenttype feature throws exeception

by Jesper Persson 17. March 2009 21:04

Today I saw a strange error when creating a feature with a custom contenttype, I had no special field type pretty basic stuff but when the feature was activated this exception was thrown:

Value does not fall within the expected range.   at Microsoft.SharePoint.SPContentTypeId..ctor(String id)
   at Microsoft.SharePoint.SPContentTypeElement.ElementActivated(SPFeaturePropertyCollection props, SPSqlCommand sqlcmdAppendOnly, SPWebApplication webApp, SPSite site, SPWeb webNull, Boolean fForce)
   at Microsoft.SharePoint.Administration.SPElementDefinitionCollection.ProvisionFieldsAndContentTypes(SPFeaturePropertyCollection props, SPSite site, SPWeb web, Boolean fForce)
   at Microsoft.SharePoint.Administration.SPElementDefinitionCollection.ProvisionElements(SPFeaturePropertyCollection props, SPWebApplication webapp, SPSite site, SPWeb web, Boolean fForce)
   at Microsoft.SharePoint.SPFeature.ProvisionElements(SPFeaturePropertyCollection props, SPWebApplication webapp, SPSite site, SPWeb web, Boolean fForce)
   at Microsoft.SharePoint.SPFeature.Activate(SPSite siteParent, SPWeb webParent, SPFeaturePropertyCollection props, Boolean fForce)
   at Microsoft.SharePoint.SPFeatureCollection.AddInternal(Guid featureId, SPFeaturePropertyCollection properties, Boolean force, Boolean fMarkOnly)
   at Microsoft.SharePoint.SPFeatureCollection.Add(Guid featureId)
   at Microsoft.SharePoint.WebControls.FeatureActivator.BtnActivateFeature_Click(Object objSender, EventArgs evtargs)
   at System.Web.UI.WebControls.Button.OnClick(EventArgs e)
   at System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument)
   at System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

First I thought it was some sort of error due to the fact that im inheriting from the picture contenttype, the ULS  and eventlog did not help much.

The contentype element:

<ContentType Name="MYcType" ID="0X010102008A0F43E3F6A74b968501DFB9F2DBBA59">

After some investigation I realised that the problem was with the ID attribute, don't use capital X in the ID attributes value like above use this instead:

<ContentType Name="MYcType" ID="0x010102008A0F43E3F6A74b968501DFB9F2DBBA59">

Tags: , ,

Visual Studio intellisense stopped working

by Jesper Persson 12. March 2009 13:07

After installing the CAML.NET IntelliSense the intellisense stopped to work but only in XML files my normal C# code was working just fine.

What the h... the xmlns is set to Sharepoint but it does not work in any of my projects???? 

Just to be sure I started all over with a blank Solution and en empty Project, then I added a XML file

Look I can choose the right namespace

This is a start but wait no intellisense, how about that.

As it turns out VS had added all the XSD's and that did not work well, if they share the same namespaces and element declarations.

To solve the issue I selected the Schema property on the document and pressed the ... button

As you can see all the sharepoint schemas has been selected

Change it like this

And Voila intellisense is back Smile

Tags: , ,

Install your Sharepoint solution files from windows explorer

by Jesper Persson 11. March 2009 18:41

Once upon a time 

I was listening to my favorite Sharepoint podcast I think it was this show. They were talking about the different tools you have to have in your bag as a Sharepoint developer, most of them was not new to me but I think it was Andrew Connell who were talking about a tool/utility that extended the Windows Explorer context menu, so you can install a Solution file (wsp) from the menu.

Let me get one

That sounds like a great utility, so I immediately googled for a tool like that, but I was unable to find anyone else who had done that, might be because I can't find the right search terms but anyhow, I'm not giving up so easily so I made the utility myself.

My primary goal was that no assemblies or code should be deployed so the solution is only a modification to the registry.

Download the registry file here, it's tested on Windows 2003 Server R2 and Windows 2008 Server.

wsp solutions.reg (832,00 bytes)

The result

Tags: , ,

Best intranets in 2008

by Jesper Persson 4. March 2009 18:49

Jacob Nielsen has awarded the 10 best Intranets for 2008 but one of the most interesting things about the list is, besides that the danish company COWI is on the list, are that 5 of the 10 intranets are based on Sharepoint.

This is from the UseIt Site: In total, the 10 winners were built on 26 different products — substantially fewer than the 41 used in 2008 or the 49 used in 2007. Most impressively, fully half of the winning intranets used SharePoint, especially the recent MOSS platform (Microsoft Office SharePoint Server 2007). As the following chart shows, SharePoint use has grown dramatically in recent years. This is particularly impressive given that, from 2003–2006, the winning intranets didn't use earlier versions of SharePoint at all.

Increasing use of Microsoft SharePoint among award-winning intranets from 2003 to 2009
Microsoft SharePoint has seen substantially increased use among well-designed intranets in recent years.

 

Tags: ,

Sharpoint P&P Guidance

by Jesper Persson 4. March 2009 17:00

I was just browsing the Pattterns & Practice web site the other day and noticed that they have released a Sharepoint Guidance in November, ít has escaped me completely, and I dont think many other people have seen it at least not people I meet. It is very comprehensive give it a try 

http://www.microsoft.com/downloads/details.aspx?FamilyId=C3722DBA-6EE7-4E0E-82B5-FDAF3C5EC927&displaylang=en

 

Tags: , ,