Thursday, November 15, 2012

Would you fly with Airplane Guy?

You are at a dinner party and overhear a conversation. It goes something like this:

Stranger 1:  Hi, I'm Alice
Stranger 2:  Hi, I'm Bob. Don't I know you from the encryption examples?

Alice:      No idea what you mean, sorry. So what do you do for work Bob?
Bob:        I'm an Airplane Guy.

Alice:      Cool, what does that mean exactly? Are you a pilot?
Bob:        Yeah, on some days I fly the plane. Not much lately though.

Alice:      I'm sorry, have you been out of work?
Bob:        Oh no, far form that. I've just been focusing more on engine design lately.

Alice:      Wow, so you are a pilot and an engineer! That's quite an accomplishment.
Bob:        I'm not really an engineer, but I sometimes do that type of work. It's all part of being an airplane guy. I'm not exactly an expert, but someone's got to do it.

Alice:      I'm impressed nonetheless.
Bob:        Yeah, I really got into engine design when I ran out of property to extend the runway.

Alice:      What do you mean?
Bob:        Well my manager wanted to add more cargo to each flight, so I needed a longer take off distance to get the plane in the air. So I poured some concrete at the end of the runway and all was well. That lasted for a while, but then my manager was back and wanted more cargo capacity again. I can't extend the runway cause it would go off the property, so I'm working on an engine design to get more power in the plane.

Alice:      Wait, you poured concrete? Isn't that a waste of your talent?
Bob:        Nah, I'm an airplane guy, I do whatever it takes. I do wish  I could have taken a class in concrete though cause it doesn't seem like the runway addition will make it through winter. Oh well, I'll re-do it next spring.

Alice:      But can't you hire an expert?
Bob:        Experts are too expensive. Like I said, this is just part of the job.

Alice:      Wow Bob, sounds like you do quite a lot in your job.
Bob:        Sure, I like it that way. I didn't even tell you the fun part. We've been talking about cargo, but I much more prefer passenger flights. I really like interacting with the people. It's just too bad I only have such a short time between takeoff and landing to get to know them.

Alice:      I'm not sure I understand....
Bob:        Well I can only start handing out refreshments once I've engaged the autopilot after takeoff, and I do need to be back in the captain's chair when we start the descent. The tower really gets upset if they can't raise me on the radio. I've been hacking away at an iPad app so that I can fly the plane from the refreshment cart, but I'm not a very good programmer I must admit, so there are still some bugs to work out......


******************************  END  **********************************

Would you fly with Bob the airplane guy? Would it make you feel safe? Probably not.

So why is this on a SharePoint blog? Well just replace 'airplane guy' with 'SharePoint guy', 'engine' with 'database', 'runway' with 'storage' and 'passengers' with 'users'. It starts to sound a lot like the reality of many SharePoint projects.

Unfortunately, many people in the project owner/manager position are not aware that just like an airplane guy, there is no SharePoint guy. It is up to us to explain to them that a complex system such as SharePoint requires many specialists to design and operate. Whatever your SharePoint specialty, a common responsibility that we all share is to make this clear to our managers and customers. They may not want to hear it at first, so feel free to borrow the story of bob the airplane-guy.




Wednesday, October 17, 2012

Mobile browser limitation and fix suggestion

A limitation that I ran into when working on fivetonow.com was adding pictures to an event posting using a mobile browser. I have an iPhone and found it very disappointing that I cannot upload a photo into a mobile website. For this I would need an app. Here is my proposal how to solve this problem; all I need is to get the mobile browser manufacturers to hear me out.

Part 1: “Share bookmarks”

A site can include a special link that allows mobile devices to know how to share various assets such as picutres with that site. So in the fivetonow.com example we want to create a special link to create a new event, with picture. The link would look something like:

<a href="/CreateEvent" data-sharesender="image" data-shareid="eventpic">Add a ‘Share to fivetonow’ bookmark to your mobile phone</a>

The key part of this link is the data-sharesender attribute. This attribute would signal the mobile device that the user wants to register this site as a valid destination for their photo sharing. The same way I can share an image with the facebook or twitter app on my phone today, this link would cause my phone to register the /CreateEvent path of the given site as a valid place to send photos.

Part 2 “Receiver locations”

Once my phone understands that there is a special url I want to share photos with, that url needs to handle these photos. This means we need a standard way of processing an image being uploaded to such a special url. This is actually quite easy as long as we can agree on a standard. :)
The page can contain an input element like so

<input type="file" name="whatever" data-sharereceiver="image" data-shareid="eventpic ">

Now the mobile browser would know that it needs to add the file path to the input field when it opens that page. It uses the data-shareid attribute to find the correct input field and writes the file path into it. This way the access to the filesystem on the mobile device is still limited but the user is able to submit pictures to websites. A regular browser works as intended since it just ignores the data- attributes.

This can be extended with different types of share bookmarks like sound and video. It would be easy to use, flexible and still safe as the phone decides what files can and cannot be shared.

Now if only I can get Apple to listen to me…..

Friday, September 07, 2012

How to add a Geolocation field to SharePoint 2013 lists using powershell


There is a great resource on MSDN that shows how to add a geolocation field to a SharePoint 2013 list using the client object model. It may not always be the handiest way to do this however, and you may want to do this using powershell instead. Here is the code for that.
Param(
 [parameter(Mandatory=$true)]
 $webUrl,
 [parameter(Mandatory=$true)]
 $listName
 )
 
Add-PSSnapin Microsoft.SharePoint.Powershell -ErrorAction SilentlyContinue

$fieldXml = "<Field Type='Geolocation' DisplayName='Location' />"

$web = Get-SPWeb $webUrl
$list = $web.Lists[$listName]

$list.Fields.AddFieldAsXml($fieldXml,$true,[Microsoft.SharePoint.SPAddFieldOptions]::Default)
$list.Update()
Save this to a file named Add-SPGeoField.ps1 file and you can execute the following command from powershell
  Add-SPGeoField.ps1 -webUrl http://someweb -listName SomeList
This will add a field named Location to list SomeList located in web at http://someweb. Note that the field name is hardcoded in the script but can very easily be added as a parameter if so desired.

Tuesday, September 04, 2012

Governance article published in DIWUG eMagazine



I recently had an article published in the Dutch Information Worker User Group (DIWUG) eMagazine. The article should be a good resource for those trying to get started with (SharePoint) governance, it's meant to be a practical guide to get you going.

It can be found at http://www.diwug.nl/e-magazines/pages/default.aspx

Am curious to hear feedback!

Wednesday, July 11, 2012

Speaking at SharePoint Connections





I am happy to announce that I will be speaking at SharePoint Connections in Amsterdam Nov 20-21 2012.

I will be presenting a session on how to create mobile friendly web apps on top of the SharePoint platform:

"Mobile access to SharePoint data is becoming a critical business requirement in many organizations. This session will explore the challenges that come up when surfacing SharePoint data to mobile devices, and how these can be overcome. The session will start by defining the requirements for mobile-friendly SharePoint solutions, and then proceed to determine how far these requirements can be met with out of box components. The majority of the session will however focus on implementing custom solutions on top of the SharePoint platform that are specifically tailored for access using mobile devices. Expect many demos.SharePoint Connections Amsterdam 2012"



Wednesday, May 16, 2012

Why Toad

IT projects could benefit a lot from a few simple practices, one of which is asking 'why' more often. In order to promote the asking of 'why', XComplica has launched a new website:

The Why Toad

Ensure your sound is on, then click the toad.

We've done our best to ensure this works on mobile devices as well, so feel free to bring the Why Toad to meetings, etc.

Happy asking 'Why'!

Friday, April 20, 2012

Sanity Check

I am curious if I am crazy, or if I missed something. I just had an unpleasant exchange with a customer, who refuses to pay for services rendered.

Last fall we had a meeting with this customer and they showed interest in using Office 365. So I drafted an offer, clearly stating that we will provide consulting services to set up and configure O365 for them.  I clearly made a distinction between our fees and that of Microsoft. MS offers a trial for 30 days with per month costs after that, we charge X for the setup. I even gave them a good price thinking we might get some more business down the road.

After some time, the guy who was assigned as my contact person emails me back that the customer is interested in pursuing the trial of O365, and when can we proceed. So I assign the work to my employee, and he spends the next week working with the contact person to understand what they need, and in setting up O365 for them. They reach a point where all is ready, and my guy gives them time to try things out.

A week or two pass, and my guy can't get a hold of customer contact person. We know the service is good for 30 days so we want to follow up, etc. No response. I then step into the picture and try to get a hold of the guy. No response. I then send an email to the company catchall hoping someone else will see it and reply. No response. By this time, the trial has expired. Eventually I get sick of being ignored, and send an invoice to the customer.

Time passes, and I get an email from one of the owners. "The guy you worked with is no longer at the company. You have no agreement, and it is unprofessional that you just send an invoice". Hmm, ok. So I send this guy the email correspondence as well as my offer that I drafted as to indicate that I did have an agreement with his ex-employee. It's unfortunate that something happened in their organization, but I can't be held responsible for that. We did the work, as agreed.

This results in a phone conversation where I am told that I am unprofessional, that "the world doesn't work like this" and that I can forget about being paid.

I understand the guy is upset that he has no value and an invoice on his desk. But the critical thing in my eyes is that I am not the one who is at fault here. We delivered as agreed. They didn't do anything with it, too bad. I mean, I still pay my gym membership even if I don't go.

I am curious if I am missing something here, or if my logic is sound. I want to warn other small businesses against working with this customer, but I first want to sanity check this.

Thanks!

Tuesday, April 17, 2012

Nasty error when writing data to SharePoint List

I am working on a SharePoint console app that needs to import data from an XML file into a SharePoint list. All was going well, and then suddenly I get the following error:


Attempted to use an object that has ceased to exist. (Exception from HRESULT: 0x80030102 (STG_E_REVERTED))

It happened at the SaveChanges call, and for Googlers at:

Microsoft.SharePoint.Linq.DataContext.SaveChanges()

No, I was not disposing the current SPContext (the most likely cause of this problem) since I was in a console app. So what else could it be? This post on stack overflow helped me figure it out.

One of the fields I have in the SharePoint list is a Yes/No field. SPMetal created a nullable bool form this, and so I figured I could safely ignore it if I chose to. Not the case. Once I started providing a value to that nullable bool, all was well again. The field definition for that Yes/No field does have a default value defined in CAML, but if this is the cause of the problem is not clear and I don't have time to test at the moment.

Moral of the story, if you are updating a list and see the error above, check that you are providing values to any bool fields. Likely the same story for choice fields and who knows what else.

Monday, April 02, 2012

Orange Tasks

Picture this scenario: your boss gives you a task to do. You are not quite sure how to do that task, but you know you will eventually have to figure it out. For now, it goes on the todo list. Time passes and you have been busy. That tasks still sits there, and you haven't gotten to it. You have in the meantime done other tasks that have come along after, but those were just easy to take care of. You have also escalated other tasks in that time, because these were clearly not things that you could/should do.

I would argue that everyone can relate to this scenario. It is something very common, and what I would like to call the 'Orange Task'. First however I need to explain green and red tasks. Note that my examples are general, and won't apply to everyone since people are all different.

Green tasks: You are asked to do something that is perfectly clear to you, and you are comfortable performing.
For example: Your asks you to get some milk from the store. You might not be in the mood to do this, but it's pretty clear to you how you need to get off the couch, walk/drive to the store, trade €2 for some milk and bring it home. The feeling you get here is: Ok, I know what needs to be done, just needs doing.

Red task: You are asked to do something that you are not able to do, and are comfortable in saying so. It is an unreasonable expectation that you should be able to do this, and you are not at all hesitant to reject this task.
For example: Go climb Mt Everest - today! The feeling you get is (most of us that is): Yeah right, whatever, I'm not going to do that....

Now, Orange task: You are asked to do something that you don't exactly know how to do or are not quite able to do. You feel however that you should be able to perform this task. Or in any case, you don't feel comfortable in rejecting this task. You also don't feel comfortable in performing this task. The easiest thing to do is to put this task out of your mind for now, and hope you can deal with it tomorrow.
For example: Remember when you were a teenager with a crush on someone and thought: "I will ask them out". Tomorrow was a better day to do it than today.  The feeling you get is: I should do this, it is valuable, but .....

I hope you now have some picture of what I mean by Orange tasks. So why am I writing abou this on my (mostly) SharePoint blog? Because I believe that Orange tasks are extremely dangerous to business, to projects in general and thus also to SharePoint projects.

Keeping an eye out for orange tasks should be a significant part of any project governance. Green tasks get done, Red tasks get escalated but Orange tasks sit there and fester. The longer they fester, the worse the impact. I have seen entire teams take the 'we'll cross that bridge when we get to it' approach when they damn well knew that particular issue needed to get solved ASAP and would cause big problems in the future. This is the 'ostrich head in the sand' approach or 'elephant in the room' phenomenon.

So what can you do? Hunt down the Orange tasks with a vengeance. Turn them into Reds or Greens as soon as possible. Make it team / company culture to do so. Ensure everyone knows what an Orange taks is, and foster a culture where identifying Orange tasks is viewed as a good thing to do. It will be hard, it requires a change in thinking, it requires open communication, it requires admitting to each other that we are not perfect. But it is worth it. Try it right now, look in your todo list, find an orange task. Can you ask someone for help? Can you figure out how to solve it? Can you tell your boss, etc that you need more clarification? Any of these are means of making that task Green or Red.

Good hunting. :)

Friday, March 30, 2012

SharePint with a twist

I have an idea for a SharePint with a twist. I feel that at any conference, user group meeting, SharePint etc., I always end up talking to the people in the community whom I already know. While this is comfortable, I would see it as beneficial to meet some of the other people in the room. Somehow that rarely happens.

To promote this, I was thinking of setting up a SharePint with a speed-meeting part of the evening. This is something that is done at a business club I belong to, and I find it extremely valuable. The basic idea is that a timer starts, you find someone random to talk to one on one, and in 5 minutes, you move on to the next person. Everyone participates so it removes the 'weirdness' of talking to new people.

Let me know if you would be interested in such a SharePint event. If I get enough interest I will organize something in Amsterdam.

Wednesday, March 28, 2012

ASP MVC and SharePoint: Revisited

When I first wrote about integrating MVC and SharePoint, I wrongfully stated that one is limited to using MVC 2 and .NET 3.5. I was corrected by Rob Johnson (@bertyJobbo), and there have been numerous requests since to show how to use SharePoint with MVC 3. This post is all about work that Rob sent me, so all credit goes to him.


Here are the step by step instructions:

  1. Create a new MVC 3 project, note that you need to select .NET 4 in the dropdown





  2. Select your view engine and template type





  3. Once the project has loaded, right click on references and add a reference





  4. Select the SharePoint tab, and add the Client Object Model dlls





  5. Add a new controller





  6. Give the controller a name and choose any scaffolding you may want. Mine is empty.





  7. Add a using statement to the top of your controller code, to ensure the client dll is loaded


    using Microsoft.SharePoint.Client;
    


  8. Create the action method below, simply gets the title of the SharePoint site using Client Object Model.


            public string Index()
            {
                ClientContext ctx = new ClientContext("http://demo.xcomplica.local");
                Web web = ctx.Web;
                ctx.Load(web, w => w.Title);
                ctx.ExecuteQuery();
    
                string title = web.Title;
                return title;
            }
    


  9. Run your site, and you should see your SahrePoint site title in your MVC3 app!





Wednesday, January 04, 2012

Same .webpart url in Web Part Gallery causes weirdness

I ran into an interesting issue today, and although I haven't fully tested this yet, I think I now get what is going on.

I was working on refactoring a number of web parts for a customer, they had a less experienced SharePoint dev create a bit of a mess instead of a proper WSP, and so my first task was to create a proper SharePoint project in Visual Studio and include the necessary web parts. No issues, all worked on my clean test environment.

I then proceed to deploy my shiny new WSP on the test server, and while most things work as expected, the web parts that I included are not available. The feature that they are part of is activated so I am stumped for a minute. Quickly I start to suspect that this has something to do with the old web parts, but my new ones are in a different assembly, different namespace etc etc. After some poking around in the xml, I realize that both my web parts and the old versions have the same name, and thus deploy to the same URL in the web part gallery. This can be seen in the elements.xml file for the web part.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/" >
  <Module Name="MyWebPart" List="113" Url="_catalogs/wp">
    <File Path=MyWebPart\MyWebPart.webpart" Url="MyWebPart.webpart" Type="GhostableInLibrary">
      <Property Name="Group" Value="JoeTest" />
    </File>
  </Module>
</Elements>

A few quick tests on my local machine confirm that such URL collisions will cause problems, on my local machine it looked like web parts were being overwritten by the latest feature to deploy, but on the test server the old web parts persisted. This needs some more testing to fully understand what the intended behavior is, and whether it is something permissions related.

Nevertheless, as soon as I updated my URL deployment location, I was able to deploy the new web parts to the test server and use them on pages.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/" >
  <Module Name="MyWebPart" List="113" Url="_catalogs/wp">
    <File Path=MyWebPart\MyWebPart.webpart" Url="new_MyWebPart.webpart" Type="GhostableInLibrary">
      <Property Name="Group" Value="JoeTest" />
    </File>
  </Module>
</Elements>

I realize that it probably isn't best practice to have web parts with the same name, etc. but trust me that I have a good reason for doing this. In any case, after some thought it makes perfect sense that SharePoint will not allow us to deploy two .webpart files to the same URL, and so a change to the URL is needed to work around this.