Bing Maps Sandboxed WebPart for SharePoint Online and SharePoint 2013

I wanted to create a simple Bing Maps Web Part for SharePoint 2013 Sandboxed solutions and for SharePoint Online.

This isn’t the same as my previous Map Web Part posts, however it isn’t too difficult. As before we just define a DIV element in our WebPart with an ID:

<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Import Namespace="Microsoft.SharePoint" %> 
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="FlightMapWebPart.ascx.cs" Inherits="AirTravel.FlightMapWebPart.FlightMapWebPart" %>
<div id='myMap' style="position:relative; width:600px; height:400px;"></div>

The the code behind is simple enough. The main point is just to get around the Sandbox security restrictions by writing out Javascript directly with RenderContents. I also added a property to set the Bing Maps key.

using System;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;

namespace AirTravel.FlightMapWebPart
{
    [ToolboxItemAttribute(false)]
    public partial class FlightMapWebPart : WebPart
    {
        /// <summary>
        /// Constructor
        /// </summary>
        public FlightMapWebPart()
        {
        }

        /// <summary>
        /// Set the Bing Maps Key with a WebPArt Property
        /// </summary>
        [WebBrowsable(true),
        WebDisplayName("Bing Maps Key"),
        WebDescription("Your Bing Map Key Value"),
        Personalizable(PersonalizationScope.Shared),
        Category("Bing Maps")]
        public string BingMapsKey { get; set; }

        /// <summary>
        /// On Initialize
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            InitializeControl();
        }

        /// <summary>
        /// Create Child Controls
        /// </summary>
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
        }

        /// <summary>
        /// On Page Load
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        /// <summary>
        /// Add addidional content to the webpart
        /// </summary>
        /// <param name="writer"></param>
        protected override void RenderContents(HtmlTextWriter writer)
        {
            base.RenderContents(writer);

            // Add reference to JQuery javascript
            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/javascript");
            writer.AddAttribute("language", "javascript");
            writer.AddAttribute(HtmlTextWriterAttribute.Src, "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js");
            writer.RenderBeginTag(HtmlTextWriterTag.Script);
            writer.RenderEndTag();

            // Add reference to Bing Maps javascript
            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/javascript");
            writer.AddAttribute("language", "javascript");
            writer.AddAttribute(HtmlTextWriterAttribute.Src, "http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0");
            writer.RenderBeginTag(HtmlTextWriterTag.Script);
            writer.RenderEndTag();

            // Write javascript code
            writer.AddAttribute(HtmlTextWriterAttribute.Type, "text/javascript");
            writer.AddAttribute("language", "javascript");
            writer.RenderBeginTag(HtmlTextWriterTag.Script);
            writer.WriteLine(CreateLoadMapString(this.BingMapsKey));
            writer.WriteLine("LoadMap();");
            writer.RenderEndTag();
        }

        /// <summary>
        /// Create Load Map Javascript function
        /// </summary>
        /// <returns>Load Map Javascript String</returns>
        static private string CreateLoadMapString(string BingMapsKey)
        {
            // Sanitize, just in case some script passed instead of a key string
            string sanitized = HttpUtility.HtmlEncode(BingMapsKey);

            string mapDeclareString = "map = new Microsoft.Maps.Map(test, {credentials: '" + sanitized + "'});";

            StringBuilder js = new StringBuilder();
            js.AppendLine("var map = null;");
            js.AppendLine("function LoadMap() {");
            js.AppendLine("var test = document.getElementById('myMap');");
            js.AppendLine(mapDeclareString);
            js.AppendLine("}");

            return js.ToString();
        }


    }
}

And that’s it. Your WebPart can be used onpremise or on the cloud.
Image
One thing you may need to check is that the website where the Bing Maps Javascript file (LINK) resides is added to your Internet Explorer ‘Trusted Sites’ list.

Also of note is that waiting for the page to load with the JQuery ‘Ready’ function was not required before executing the Javascript.

UPDATE: I just noticed that I could pass a script through the webparts property! Added the HtmlEncode to make sure.

Should I Develop Office 365 / SharePoint Online Applications with the Apps Model or SharePoint 2013 Sandboxed Solutions?

I’ve been looking at more SharePoint Online work recently, and many people have encouraged me to look at the apps model as the way to build solutions for it.

I do get the apps model and after some years dealing with the complications of custom WebParts it does seem pretty compelling. That said after trying some coding over the weekend I’ve come to the conclusion that it really isn’t for every scenario.

Actually, I REALLY want to be able to just use the App development model. I want to buy a new laptop, and the requirement to run SharePoint 2013 is the only thing that blows my minimum system needs out.

First I did a side by side comparison between

  1. Building ‘traditional’ sandbox solutions in SharePoint 2013 and then deploying to SharePoint Online
  2. Building SharePoint Online apps directly

 

Aspect 

SP 2013 Sandbox Solutions 

SharePoint Online App 

Comment 

Development environment 

Visual Studio 2013 + SharePoint 2013 & SQL Server installed locally

Visual Studio 2013  

The cost of licensing SharePoint 2013 and SQL Server for development purposes should be considered as well.

System Requirements 

Virtualization, 16GB RAM & multicore CPU recommended.  

4GB RAM 

It is possible to reduce the SharePoint 2013 requirements, however there are a few hoops to jump and basically you need a powerful machine.

Offline development?

Yes 

No 

Fairly obvious one…. 

Visual Studio Debug on SharePoint Online 

No 

Yes 

SharePoint 2013 Sandbox solutions can be debugged locally, but not when later deployed to SharePoint Online. This is potentially a big one, since sandbox solutions on both platforms do not operate exactly the same.

Ease of integration into SharePoint Site

Simple 

Difficult 

After installing an app it will not appear in SharePoint itself but rather its own separate application.


 

Packaged Solutions 

Simple. A sandboxed solution can be packaged, installed, activated, disabled and removed. 

Difficult. Custom code required, and uninstalling pieces will require the entire app to be removed.

This is not actually so clear cut. For ‘standard’ items such as Lists, Web Parts and Workflows, the sandboxed solution is easiest. If you want more web related files such as CSS and Javascript then it seems it is easier to deploy in an app.

Leverage existing web parts for lists 

Simple. The new list is visible to the WebPart through a standard API call 

Difficult. SharePoint cannot ‘see’ the new List, and a reference to it would have to be explicitly entered, if possible

I downloaded some webparts from the SharePoint store and many required me to select an existing list from the SharePoint site. There was no option to place the URL string to the app hosted List. 

 

 

 

Scenarios

 

Scenario 

Choice 

Reason 

Create some custom lists / web parts for end users 

Sandboxed Solution 

Simple to develop, deploy and remove. Much more difficult to use the same artefacts from SharePoint Online in a SharePoint Online App

Display a table that combines SharePoint list data with data taken from a standard SAP data source

Sandboxed Solution 

Use BCS to consume SAP as a data source 

SharePoint Online running under a highly restricted security governance model

SharePoint Online App 

Sometime developing a custom webpart is not sufficient to get around your organizations security practices. Hosting in an app is the easiest way to quickly develop functionality.

Flexible custom application 

SharePoint Online App 

The SharePoint Online sandbox is very restrictive from a security perspective. If you do not need the application to be hosted in a SharePoint site then I’d probably recommend using apps.

 

Conclusion

The app model is a great way to enable you to build flexible and powerful apps that leverage SharePoint on the SharePoint Online platform.

If you need to extend SharePoint itself, such as deploy custom Lists and Web Parts, then the Sandboxed model is still the way to go.

I hope that Microsoft can evolve the app model further and allow tighter integration of apps into the SharePoint application itself.

 

 

 

 

Windows 8.1 – Is it worth it?

I upgraded my Lenovo W520 from Windows 8.0 to Windows 8.1 2 weeks ago:

  • Stability
    • Windows 7 and 8.0 crashed now and then.. 8.1 seems stable so far
  • Hyper-V
    • I can now use all 8 cores for a VM!
    • Nice to have machines that can use EFI and boot from network, although not something I’m likely to use
    • The console now emulates RDP more closely, with full screen across two desktops possible! This is a great feature for demos when I will not be certain to have a router available
    • No RemoteFX .. why not? My machine is powerful enough to play Half Life 2 under RemoteFX
  • Outlook 2013
    • Font makes it easier to see more on the screen at once
  • Searching
    • This is a big one. Windows 8.0 let me type and find things in Apps, Settings or Files. I found it quite intuitive. Windows 8.1 not searches the Internet by default.. why?

So yes, basically worth it.

Some points:

  1. On a Lenovo W520, disable the NVidia graphics chip in the BIOS when installing Windows 8.1, otherwise it will crash without explanation
  2. It is very easy to install an additional mSATA drive on your Lenovo W520. (Although you need to remove the keyboard). Note that this interface has a 300 speed, even if you buy a 600 drive. (The internal 2 hard disk bays to however support 600)

 

How to stop your Bluetooth mouse freezing under Windows

I found my old Microsoft Wireless Notebook Presenter Mouse 8000 that I bought back in 2008. I lost the dongle however the bluetooth matched up easily with my Dell 6220 laptop and was working great.

However every now and then the connection was lost, requiring a visit to the Bluetooth control panel to ‘nudge’ it back into life. This was annoying to say the least.

The fix is not obvious however equally simple. Just find your laptop’s Bluetooth radio (likely a different name depending on your laptop) and click the ‘Power Management’ tab. Then just uncheck the ‘Allow the computer to turn off this device to save power’

DeviceManager

Nokia Lumia 920 Observations

There is a ton of interest in the new Lumia 920, however thought I would add a few thoughts of my own.

In the past years I have gone from:

  1. HTC TYTN 2 (Windows Mobile 6.5)
  2. Apple iPhone 3
  3. Samsung Galaxy SII (Android ICS)

So I decided to jump back into the Microsoft ecosystem. Generally speaking this is a fantastic device, and the relativity heavy weight is not an issue for me. If you don’t like weight then consider a Samsung Galaxy SIII instead.

Missing apps:

  • Pleco : This is a really useful Chinese character / dictionary application for Android . No plans to release for Windows Phone.
  • Google Maps: Nokia Maps is for the most part comparable, however I’m surprised that Hong Kong station exits are not marked. (i.e. I can see there is an exit near my destination, however there is no way of knowing which letter it is) I could still use Google Maps through the web browser if I wanted though.

Apps with strange behavior:

  • SkyDrive: Great SkyDrive browsing, but no way to save the files onto my phone?
  • Nokia Maps: The incomplete subway exit markings (as above)
  • Twitter: Official app always scrolls to the top of your timeline, not from where you left off. (MetTweets is better)
  • FaceBook: Works, although noticeably less responsive than Andriod version
  • Lync 2010: Cannot join meetings. I’m not sure if this is a problem with my phone or my company’s Lync Server.

Good apps:

  • XBox Podcasts: I don’t have an XBox, however the Podcast facility is far better than ‘Google Listen’ for Android or iTunes for iPhone.
  • Outlook: Just integrates perfectly.
  • Skype: Far better experience than with the Android version. Experience for the other (PC) caller is improved greatly, although displayed screen shape is a little strange.
  • MetTweets: Best Twitter client I have found so far

Interface Issues:

  • URL bar too close to the Windows buttons: When typing a URL I often hit the Windows key by mistake. 
  • Switch between Wifi / 3G mode: I like to turn off my phone data plan when at home. The Lumia doesn’t have an easy way to do this, whereas even the iPhone 3 from 2007 has a quick way to turn on and off. I’m currently using an App called ‘Power Tool’ that makes this slightly easier.

Interface Strengths:

  • Bluetooth: This is the first device where Bluetooth has worked seamlessly for me. Even the Galaxy SII required a degree of persuasion to get my Bluetooth headsets to work. The Lumia 920 just works.

RDP into Windows 2012 client from Windows 8 host

I’m generally loving my Hyper-V capability under Windows 8, however for some reason I was unable to RDP into my new Windows 2012 virtual machine despite enabling remote access.

I discovered that there is a an extra option in the default firewall settings you need to enable if your host machine is not part of the same domain.

Since my laptop does not belong to any domain, I just ticked the ‘Public’ check box and all is fine.

 

 

SharePoint 2013 PowerPivot Install Issue: “Please install SharePoint before you install PowerPivot for SharePoint”

I wanted to try out the latest stack of SharePoint software from Microsoft, so I downloaded:

  1. Windows Server 2012 Essentials (for Domain Controller)
  2. Windows Server 2012 Standard
  3. SQL Server 2012 Enterprise
  4. SharePoint Server 2013 Enterprise

I installed SharePoint Server 2013 first, and then Installed the PowerPivot SQL Server option. I soon discovered an error in that SQL Server was looking for SharePoint 2010 as an installation check:

Rule “SharePoint installation requirements for PowerPivot for SharePoint” failed.  SharePoint Server 2010 is not installed on this computer.  Please install SharePoint before you install PowerPivot for SharePoint”

  • Disclaimer:The following Registry hack will likely result in an UNSUPPORTED installation of Microsoft SharePoint 2013. I publish it solely for use in your development environment. If you need to install a Production environment, then I suggest waiting for a fix from Microsoft.

I found a way past this with help from @spjeff :

http://www.spjeff.com/2012/07/19/fixed-sharepoint-2013-rule-sharepoint-installation-requirements-for-powerpivot-for-sharepoint-failed/

However I still had an install issue:

Since @SPJeff was installing a preview version, I also had a look at Process Monitor from SysInternals and discovered:

So there were lots of prerequisites missing from my registry.

I went to an another server that had SharePoint 2010 Enterprise installed and exported the following keys:

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\WSS]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\Secure]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\WSS\InstalledProducts]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\Secure\ConfigDB]

 

I the ran the REG files back on my SharePoint 2013 machine, and it all began to work:

The actual Registry files I used are embedded in the document below.

Use the following Registry files at your own risk.doc

(Please note that this fix probably doesn’t need all of these Registry entries, however I just grabbed everything to get around this quickly. You can probably delete after you have installed SharePoint 2013)

Follow

Get every new post delivered to your Inbox.