Sunday, November 24, 2013

Creating an application context for a .NET MVC and Web API application

When I worked with SharePoint there was a useful object that would hold contextual data for the current request that was being processed, the SPContext.Current object. It would contain all sorts of useful SharePoint specific contextual info. Recently I was building a new ASP.NET MVC website, including a Web API portion, and wanted to create a similar concept in this custom website. The application being built receives certain information from request headers on each request, looks up data in a database based on this info and makes it easily available to all the code running during that request. I wanted to solve the 'easily available' requirement through just such a contextual object. I also wanted to make this work equally for the MVC as well as the API controllers which process the HTTP request a little differently. I thought it would have been done before, but it took some digging and experimentation to come up with a clean solution, so I thought I'd share it.

In brief, I will create a class that will hold the context data, and have one static property called Current. The Current property actually stores its data in the HttpContext.Current.Items collection (see Hanselman's discussion on why). Any code in that request can then use AppContext.Current.Data to get at this common data.

Step 1 : Create the AppContext


public class AppContext
{
    private const string APP_CONTEXT = "AppContext";

    // TODO: Update this with as many fields as needed
    public string Data { get; private set; }
    public AppContext(string Data)
    {
        this.Data = Data;
    }

    public static AppContext Current
    {
        get { return (AppContext)HttpContext.Current.Items[APP_CONTEXT] ; }
        set { HttpContext.Current.Items[APP_CONTEXT] = value; }
    }
}

The AppContext class holds the common data that needs to be accessible easily and quickly to any code running durring this request. This example only has one property, Data, but you can expand the AppContext to have as much complexity as needed. Notice the private setter on the property, the idea is that an AppContext is created once and not changed.

Step 2 : Create the Action filters


using System.Web.Mvc;

namespace JoeApp.ActionFilters.Web
{
    public class AppContextFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            AppContext.Current = new AppContext(filterContext.RequestContext.HttpContext.Request.Headers["MyData"]);
        }
    }
}

The first action filter is meant to be used by the MVC code. This filter inherits from the base class in the System.Web.Mvc namespace. The next action filter is meant for the Web API, and inherits form the base class in System.Web.Http.Filters. Each of these filters is reading a value from the Request headers, and each is doing so a little differently, according to the pipeline they execute in. The important thing to notice is that they both store the value in AppContext.Current by creating a new instance of the AppContext. In the real app I worked on, the code in these filters called a common helper function that did some database work and some other logic before creating the AppContext, so this can me much more complex than saving a string. Notice that the filters have the same class name, but live in a different namespace. I chose this to stay consistent with how Microsoft implemented the base classes.
using System.Web.Http.Filters;

namespace JoeApp.ActionFilters.Http
{
    public class AppContextFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            AppContext.Current = new AppContext(actionContext.Request.Headers.GetValues("MyData").FirstOrDefault());
        }
    }
}

Step 3 : Register the filters


In order for the filters to be used on every request, they need to be globally registered. The easy way to do so is in the global.asax, or rather in the config classes it calls. For the web filter it's the FilterConfig class:
 public class FilterConfig
 {
     public static void RegisterGlobalFilters(GlobalFilterCollection filters)
     {
         filters.Add(new HandleErrorAttribute());
         filters.Add(new AppContextFilter());
     }
 }

For the api filter it's the WebApiConfig class:
public static void Register(HttpConfiguration config)
{
    // Web API configuration and services

    // Web API routes
    config.MapHttpAttributeRoutes();

    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { id = RouteParameter.Optional }
    );

    config.Filters.Add(new AppContextFilter());
}

In each of these, I only added the one line that adds the filter to the filters collection.
Last step : Use the context
Now you can use the context in any of your code, and since your action filter exeutes on each request, the context will be properly populated each time. In the following example, the AppContext.Data contained the same data I passed in the request header called "MyData":
The controller action method:
        public ActionResult Index()
        {
            ViewBag.Data = AppContext.Current.Data;
            return View();
        }

The view:
<h2>Header was: @ViewBag.Data</h2>

The result

In not so many lines of code and a few simple classes, you can create a very handy construct to carry request wide data throughout your app. It's a concept used by Microsoft in a number of places (HttpContext, SPContext, etc) and so will be easily recognized by other developers.

Happy coding!

Monday, April 22, 2013

SharePoint is Complex. That's not a compliment.


SharePoint is complex. I've heard and repeated this many times. The reason users don't just jump on it and love it is because change is hard and as awesome as SharePoint is, users are not willing to put in the time to learn this complex thing and use it to it's fullest potential. I mean, SharePoint is a box of Legos, you can build something amazing or something awful, up to you, right?

Not sure I buy this anymore. I'm starting to think all of SharePoint's complexity is just bad design. I was reading this blogpost http://37signals.com/svn/posts/3384-winning-is-the-worst-thing-that-can-happen-in-vegas by @dhh and suddenly had an epiphany.

A) I very much agree with this article
B) SharePoint is a fantastic example where this problem occurs over and over again.

Why is it that no one has to teach the majority of the population how to use Facebook? Why is it that I use Dropbox exclusively for my document storage, even though I have a free Office 365 environment? Why are iPads flying off the shelves? Let's answer these questions and extrapolate to SharePoint.

First, Facebook is all about human communication. Granted, most of it is stupid, but the product works. You sign up, find some friends, and start typing messages to them. Maybe add a picture, or a video. Easy. Intuitive. (Yes, it is getting cluttered as of late, but that can be it's undoing in the future. We'll see.)

Dropbox just works. I can't think of a simpler argument. To elaborate is that regardless of where I am, my documents are really just a click away. I can view most of them on almost all my devices, and I can edit them in most OSs. Actually this is more of an OS limitation than Dropbox. I don't have to do anything for this to work, other than install Dropbox and sign in. I use good old folders to organize my stuff, and I don't have to even think about what Dropbox does, since I get all the benefit without having to put much thought into it. It just works. Mom uses it.

I'm currently typing this on my iPad. Second one I've owned, first one went to Mom. Love this device, probably more than any other single computing device I have ever owned. It takes a while to get the apps that tweak each person's individual iPad to their liking, but once that happens, the productivity on this device is phenomenal. Yes I know I can't run Visual Studio, but the majority of computer users don't even know what that is. It is the combination of strict rules with the free market system within those rules that has allowed an incredible number of apps to be created for the iPad that all follow certainty standards. Learn to type in one program, you've got them all. Flexibility within constraints.

So what does all this have to do with SharePoint?

SharePoint is meant for sharing information and communicating  It is however far from easy or intuitive. The average user is bombarded with terms like collaboration, metadata, list vs libraries, MySite, etc., and usually get handed a team site. You can build whatever you want, the possibilities are endless! But possibilities is not what a user wants. They want easy, intuitive, just works and quick ROI.

SharePoint doesn't just work. From an organizational perspective, Microsoft sells it to a business, and they then need to start a SharePoint journey that is expensive and difficult. Then best part is that people like myself usually tell them they are not doing enough and need to spend even more € to get any ROI.  Once it's deployed it also rarely 'just works' for the end user. See the paragraph above.

The biggest issue in my opinion is the flexibility that SharePoint allows. Microsoft has been selling SharePoint as a platform. This means it's possible to do a million and one things with SharePoint. Ok, that doesn't sound that bad right? Well the flip side of that coin is that it's impossible to say what SharePoint does. The cognitive overhead of SharePoint is incredibly high. Especially for end users. There is so much flexibility and not enough limitation that every SharePoint so-called solution to a business problem works differently form others. The standardization found in iOS apps due to limitations is nowhere to be found in the SharePoint world. Every customer I have seen has struggled to tame SharePoint and found one or another unique way to make it work for them. This process costs a lot of time, money and produces sub par results.

I am very happy to see SharePoint 2013 introduce the app store, and Microsoft finally pushing customizations outside of SharePoint from a technical perspective. A great step forward, for techies at least. The end user will still be confused with library vs list, what is a view?, how do my tasks integrate with outlook?, why are there major and minor versions?, what is publishing a document?, etc etc etc.

I apologize to all SharePoint enthusiasts out there, and there are many of you (us). It is time however that we really look at what we are peddling and consider what we need to do to hear the words EASY, INTUITIVE, SIMPLE, VALUABLE, LOVE IT, and such.

Wednesday, April 17, 2013

SharePoint CoE vs SharePoint Server CoE


Disclosure: I was recently hired and then quickly fired from a SharePoint Center of Excellence, and the experience gave me some insight I’d like to share.

Borrowed from: http://hurtatworkblog.com/can-i-be-fired-for-making-a-workers-compensation-claim-in-minnesota/
When I was interviewing for this position, I was mainly asked questions involving ROI and Value proposition regarding SharePoint. The client has a huge SharePoint environment and felt there wasn’t as much value being reaped from the investment as could be. It seemed like a great opportunity to sink my teeth into the more human side of SharePoint and I was excited to do it. The recruiter said the client was extremely picky, and when I got an offer after a few grueling interviews, she was thrilled.

On day one of my assignment, I show up at the client’s SharePoint CoE. Strange day, as I am put through a rigorous technical interview that seems like a Microsoft certification exam but much more vague. I do very poorly.  Coming back from a 3 month break with my newborn daughter, and having expected a business role, I can’t remember the nitty gritty details off the top of my head. The people at the table are all looking at me with an expression of surprise and disgust, what is this guy doing here and how did he even make it this far? A few days pass and I am told by the business unit manager that they need someone who is technically excellent at architecture and can sit down with the end client and be just as smart as their architects. I am not that guy, and I can’t help them deliver more value from SharePoint.

At first I was really confused by what happened, but I think I now understand. This particular SharePoint CoE is actually a SharePoint Server CoE. The only focus is on the health and performance of the SharePoint server, and this is done by bringing in the best technical people money can buy.

I think this is just awful. I wish people involved would understand the difference between a well-oiled SharePoint farm and a valuable one. An army of technical experts will never be enough to create a true SharePoint CoE that derives value for the end user. Technical experts are fantastic at the WHAT, but often fail to think about the HOW and rarely acknowledge the WHY. (See this video http://www.ted.com/talks/simon_sinek_how_great_leaders_inspire_action.html

A great example of this was a discussion during my technical grill session regarding JavaScript. I mentioned that I could create a Sandboxed solution with a piece of JavaScript such that it would crash everyone’s browser when they opened that page, thus rendering the site useless. The response I got was: “Not our problem, the server will run according to SLA”.

Don’t make the same mistake as this CoE in question. SharePoint is far more than a healthy farm. Understand the value it is bringing to your business, and understand WHY it is in place at all. Only when looking from that perspective can you have a SharePoint CoE vs a SharePoint Server CoE.

Monday, February 04, 2013

Back to Canada

It's been a fantastic seven years in the Netherlands, but it's time to move on. I moved here with the intention of creating and growing a business, and I gave it a pretty good shot. In the meantime I managed to meet a girl, get married and become a dad to Juliana. Mel and I have discussed this decision for a long time, and for many reasons we've decided it's time for us to move. We've chosen Canada as our new home. I once wrote a post about leaving the USA back to Europe and find it enlightening reading that post years later. Because of that, and because someone may actually read this blog, I've decided to outline why it's time for me and mine to go back to Canada.

Last December we welcomed Juliana Jade into the world. It's fantastic being a father, I am really enjoying this new job. One very unexpected side effect of becoming a father was the immediate change in long term planning. When it was just Mel and I, long term plans meant deciding where we would go skiing the coming winter. Now we are both thinking in terms of schools we want our child (and perhaps children) attending and which culture we want them to grow up in. Asking these questions made us realize that the Netherlands is not the answer. Neither of us is Dutch, and we feel it’s really important to establish a family identity from a cultural perspective. I grew up in Slovakia and then Canada, and know first hand the complexities of children and parents identifying with different cultures. Think 'My Big Fat Greek Wedding'. Since I am Canadian and Mel American, it may seem that we have yet another clash on our hands. It turns out however that Mel and I identify with one and they same culture, let's call it the 'great lakes' culture. For me it's southern Ontario and for Mel Michigan. There may be a line on the map and an annoying wait at the bridge, but the culture on both sides of lake Huron is nearly identical.

When I came back to Europe 7 years ago, I was leaving NYC. I had enjoyed my stay in NYC but it was time for me to leave. Combine that with not having any family on that continent, it made sense to come to Europe. I was not done with Canada however. I remember giving my Canadian cash to some friends saying I had no idea when I would be back, but that turned out to be quite short sighted and silly. I have found myself back in Ontario almost every year since then. Whether it was for a wedding or a detour while visiting Mel's family. Somehow I have put roots down in that area which are strong and lasting. I suspect it's my 'other family', the guys whom I spent my university years with. It's been almost 10 years since I lived in that area and yet I can't seem to get rid of them. They insist on sending Christmas cards and sharing pictures of their kids. :)

Speaking of family, yes I will miss being close to my Mom, Dad and brother. That's the biggest downside for me, and it's significant. I do hope to get my brother out to Canada for a longer stint at one point, he hasn't lived there since he was 7 or so and it would do him some good. My parents keep talking of traveling around the world and such so perhaps we'll see as much of them in Canada as we would in the Netherlands. This will be tough but we'll just have to work hard to make the best of it.

Europe, including the Netherlands, is going to financial hell and asking my wife and I to pay for it. I feel as if we are financially discriminated against in this country. That sounds harsh, but it seems to be that this is a state best left for the very wealthy or the poor. The very wealthy have countless opportunities to use loopholes and financial trickery to hold on to their wealth. There is a reason IKEA uses the Netherlands for their tax scheming. The poor, or perhaps those just getting by are supported by the state to remain out of poverty, and sometimes beyond. A friend once told me, when your child is born, put them on the social housing waiting list. This way when she is old enough to move out of the house, she will be eligible for a great downtown apartment for next to nothing. That just doesn't feel right to me.

In the immediate term I see taxes going up, benefits disappearing. It feels as if the Netherlands is in a bi-polar state, not being able to decide whether it's capitalist or socialist, but is suffering from the downside of both. Taxes of a socialist state with the costs of a capitalist one.

They say you only live once and it goes by fast. I therefore don't intend on spending all of it doing the same thing. I've been in consulting for a decade now, and most of it I've spent working on Microsoft stuff, and more narrowly: SharePoint. There are folks out there who can dedicate their whole career to one thing, I just don't think I can be happy being one of them. I feel that there is so much more to learn, to discover and to achieve.

I've learned a lot running my own business. It made me grow up real fast and take responsibility like never before. I now look back at being an employee, and at the discussions I had with my boss(es) and realize what an ignorant punk I was. I'm very happy with the path I have been on up to this point, but it feels like it's time for a change again. What that change will be I don't know. I do know I love technology and its ability to change the world, so I'm not going to become a gardener or something. I do like the energy of small businesses, so perhaps a start-up would be a good place for me. In any case, I have a feeling I may be leaving SharePoint behind. Let's see.

Nature, do we miss it. Both Mel and I love the outdoors. We met rollerblading, we made great memories hiking, skiing, skydiving, canoeing, horseback riding, camping, etc. We thrive in the outdoors. The city of Amsterdam has been fantastic and we've enjoyed exploring its nooks and crannies but I think we both get a bigger kick navigating a river in a canoe or sitting by a campfire. We want our children to know campfires, clear lakes and rivers, fishing with a reasonable chance of success, afternoon hikes through real nature, wildlife (not just mice) and the spirit of adventure and peace that comes from setting out into the woods with nothing but a backpack and a day to kill. We haven't been able to find that in the Netherlands.

For all these reasons and many more, it's time for us to say goodbye to the Netherlands and start a new chapter of our lives in Canada.

In my next post I will go into the practicals of where we want to live and what YOU can do to help. :)

Tuesday, January 22, 2013

€50 SharePoint Expert or 'Why SharePoint Projects Fail'

A few years ago SharePoint exploded. No, I don't mean your particular SharePoint server (although that may have happened), but rather the number of businesses that wanted to implement SharePoint and started some form of a SharePoint project. This was great for Microsoft and for those of us who had been working with SharePoint and had invested a significant part of our career into this product. We were needed as employees for consultancy firms or as independent consultants. SharePoint customers were billed hourly rates that were significantly higher than what they were used to paying for .NET developers or project managers. Quickly SharePoint became an instant +30% modifier on the rate. A great example of supply and demand economics at play, and how opportunity favours the prepared. Those of us who knew SharePoint enjoyed the undersupply in the market.

Markets don't sit still however. More than a few .NET developers decided to become SharePoint developers. How hard can it be? Web Parts, Workflows and a quick MCPD in SharePoint was all it took to get in on the good life. Increasing supply of SharePoint developers is a good thing for the market. Customers get a better price and there are enough SharePoint professionals to ensure all the necessary work gets done. Those of us who were in on the game have to live with the fact that our gravy train has ended and we have to adapt to market conditions and charge a 'fair' price. Sure, that seems reasonable. The problem lies in the quality of a 'converted' .NET developer. SharePoint is a complex animal and is much more than Web Parts and Workflows. There are exceptions to the rule as I personally know 'converts' who are great SharePoint experts, but these folks don't charge €50 an hour.

The €50 an hour SharePoint expert is one of the most dangerous creatures in the SharePoint ecosystem. They have enough knowledge to convince a customer (and often themselves) that they can do the job, but not enough experience to do the job properly. The customer is not an expert in technology and too often shops on price and resume alone. Worst yet, there is the recruiter creature in this ecosystem whose primary job is to create as large a difference in billable rate between the 'expert' and the customer in order to maximise its own profit. This creature loves the €50 'expert' since there is lots of margin that can be padded on with some evil sales skills.

SharePoint has earned a bad reputation in the last few years. Somehow many projects that seem great on paper and promise a fantastic future turn into something marginally average at best, or just go into the trash. Why? There are many reasons, but one of these is lack of experience. The 'experts' whom the customer entrusts are really no experts at all, and they are being paid to learn on the job. 'Trial and Horror' is what a friend called this process.

SharePoint projects are hard. Given a large bucket of money, great people and lots of time, you still have to work very hard to get value and success out of your SharePoint project. What do you think the chance of success is with a small bag of coins, average people with no or wrong experience and tight deadlines? As someone else whom I respect greatly once said: "Don't ask for a Mercedes when all you can afford is a Kia". Or in other words, why use Dr. Nick?

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…..