IamCalvinBrown.com - Blog

Blog Posts for .NET Architects, Devs and Evangelists

SharePoint Recruiters ... please learn how to treat us SharePoint professionals

Ring..ring...ring... "Hello"..."Yes my name is [fill in the blank] and I am inquiring about an open SharePoint position in Alpharetta, GA". Here we go again and my standard response "I'm currently not in the market right but please email me the job description and I will forward to other people in my network". I then immediately go to indeed.com see the latest "SharePoint Architect" positions.

Those are the calls I can not stand. Look I understand that cold callers' job are to gather leads to feed to their "account managers" so my resume can be put in the stack of candidates that get submitted to the client. But as a SharePoint professional that has strived to be the best I could be, it is so disheartening to treated like a piece of cattle, no interest in how I am doing, how my day is, and definitely no interest in having a conversation about the position.

I would hope that one, the person calling me would have as much interest in me as I would have for the position. Also, before you call, please read my resume so you know a little about my experience in relation to the position. If the contract requires, 10 years of SharePoint development experience and I have been doing SharePoint admin for 6 years, it's not a good fit. If I have over 10 years of experience like myself, please don't call me about a $35/hour contract. I am worth more than that. Once you decide that I'm a good fit, please know something about SharePoint so I can share my experience. If the fit is a good one, have a thorough job description that you can send, that way the resume can be tailored to the job description. Most importantly, when you receive the resume, have the professionalism to follow up. At least keep me in the loop about the process so I know what's going on.

Remember recruiters, we are professionals, SharePoint professionals, but most importantly, we are people who need you just as much as you need to close the position.


Hey nothing big … I just need a SharePoint site

A site, just a team site right, no big deal? Such a simple request that causes the beginning of the end for SharePoint environments across organizations. Without a plan of attack, a repeatable plan of attack for your SharePoint sites, what starts off as a small intranet turns into an unmaintainable disaster. So now that I have your attention, the next question is what should be the plan of attack? A SharePoint site request should be treated as any other application request. If there was a request for a complex application, the first thing that would be done is to gather requirements, right? Well the same approach should be taken for any SharePoint requests.


Approach to SharePoint Requirement Gathering

Below is are some questions and a good place to start, obviously you can cater for your environment. These questions are designed to do three things:

  • Show the users that SharePoint is more than a document repository and showcase more of
  • Get the users take ownership of the site and decide on a point of contact
  • Assist in minimizing as many risks as possible




Business Owner

Portfolio Owner

Budget Holder

Business Objective(s)

Desired Outcome(s)

Number of proposed users

Geography(ies) of proposed users

Will users be internal only, external or both?

What user roles do you expect the solution to accommodate?

Are there any local language requirements associated with this solution?

Are there any specific device platforms you need to support e.g. tablet/mobile?

Will the solution contain secure data (personal, financial or client)?

What type of data do you require the solution to store?

What are the likely volumes of data objects (e.g. documents) to be stored per year and over the lifetime of the solution?

Do you expect the solution to require workflow?

Is data migration required? (Outside of the SharePoint)

Will the solution require integration with another system or data source?

     - If yes, is this integration for inbound, outbound data or both?

     - If yes, what is the name/type/technology of the integration system?

What is the requested Implementation Date?

Why has this date been identified/defined?

Will this replace an existing solution, if so what is the name/platform of that solution?

Will the solution/enhancement consolidate & simplify a current solution/process/activity?

Will the solution/ehnancement improve the delivery of information?

Will the solution/enhancement realise individual/team/business efficiencies?

Describe the new/existing business processes

Will user training be required?

What is the backup procedures?

Is there a Dev, QA, Staging environment?



I would be remiss if I did not say that we at King Strategy Solutions specialize in analyzing the proper requirements and determining the best approach from a development perspective.

Amazon S3 Advantages and Caveats

Amazon AWS is one of the most powerful and popular cloud tools available. I've been thoroughly impressed with its scalability and it's ease of use, once it's established. I will strongly suggest speaking with or consulting with someone with previous knowledge of the toolset, or you can have a bill for several hundred or even thousand dollars on your hands for things that you weren't aware were running.

While it's cumbersome at first, one of the easiest tools to use is Amazon S3. It's essentially provides you the capabilities to have your own CDN (Content Delivery Network). In this space, you can store website images, html, and various other non-executable types, as easily as you can upload an image to Facebook. The only caveat I would have about this awesome tool is that it absolutely requires that you setup and administer the CORS for each folder or group. With CORS, you can say who can retrieve these images (ex: yourwebsite.com is the only location that can request these images). Without this setup, it's very easy for your images to end up cached in Google and you pay the bill for site crawls, users sharing an image, etc. 

Otherwise, it's a great tool and as an Enterprise Consultant, I haven't seen an easier to use option to date.

SharePoint 2013 Designer Workflow – The Wait Action Dilemma

So I am working at a client building an onboarding workflow. The flow was fairly straight forward, there is an onboarding list and each department has a field they fill in when they completed the task with the information they received. For example, IT has an email field that they fill in upon completion of their email setup task. Payroll has an ADP employee reference field, and so on.


So I go into this thinking I have this in the bag because of my old handy dandy “Wait for field to change” command (Click here for more information)…Right…Wrong! Did I fail to mention that the client had a requirement of using a SharePoint 2013 workflow? So what I didn’t know was

In SharePoint 2010 the Wait for action is this:

In SharePoint 2013 the Wait for action is this:

The problem is I have no idea what the email address will be equal to so that’s out! So here is how do we handle it

This is in the first stage “Initialize Workflow”

Workflow Variable – IT Email While Loop set it equal to 0
Workflow Variable – WF Initial Email Address to the value of the Alakaina field initially
In the IT Verification Stage

At this stage
  • Set up a while loop to run while the IT Email While Loop equals 0.
  • Then used the Wait for Event: When an item is changed (click here for more information)
  • If Current Item – Alakaina Email not equals WF Initial Email Address Then set the variable IT Email While Loop to 1 to stop the loop
I would be remiss if I did not say that we at King Strategy Solutions specialize in analyzing the proper  requirement workflow and determining the best approach from a development perspective.

SharePoint in the real world – what version and what platform should I use?

So you’ve decided on SharePoint or you may have SharePoint in your current environment, at this point you may feel like you have more questions than answers, welcome to the club! LOL!


Let’s discuss two very important questions:

1)     What version of SharePoint should I use?

2)     What platform should it run on?

When you search those topics, the results are overwhelming and confusing. Luckily, we will discuss the best options, in the real world, your world and not in “the perfect world with unlimited funds”


What version of SharePoint should I use?

A majority of client environments I work with on a regular basis have the following versions in production

  • SharePoint 2010
  • SharePoint 2013
  • SharePoint Online (Office 365)

For the sake of the discussion and comparison, I will also include SharePoint 2016 as well. Some highlights of each version are:


-        SharePoint 2010 was a truly major upgrade to the SharePoint platform, it introduced a new user ribbon interface, co-authoring features, and it was Microsoft’s first true foray into social computing and knowledge management.

-        SharePoint 2013 was the next step in platform improvements. In my opinion the biggest improvement was with search. In the previous platform, FAST Search was a separate platform that had to be administered separately and then integrated into the environment. SharePoint 2013 incorporated FAST search into one platform.

-        SharePoint Online (Office 365) is the Microsoft platform for the cloud. (NOTE: The term “Cloud” simply means that you use an application that is hosted somewhere else and accessed via the intranet. In other words, if you use Gmail then you are using the cloud)

-        SharePoint 2016 was released in March of this year and the biggest changes are in the backend by increasing content database and list item limits. There are also vast improvements in hybrid integrations.  


Now the question is what version should you either implement or upgrade too. Below is a guide as to what you should do:


Current Version





Basic Intranet Usage / Document Storage / No Customizations

SharePoint Online

This is the best option for basic usage. No administration needs and have the ability for dynamic storage


Advanced usage (i.e. workflows, customizations), Heavier usage where SharePoint is a critical application

SharePoint 2013

SharePoint 2013 is so mature and rich in features it makes it the obvious choice above and beyond SharePoint 2016.

SharePoint 2010

All environment types and usages

SharePoint 2016

The reason for the SharePoint 2016 recommendation here is simply because of having the longest support possible

SharePoint 2013 / SharePoint Online

All environment types and usages

Stand Pat

No need to upgrade as the features for SharePoint 2016 are not worth the migration costs


What platform should I use?

So what does this question actually mean? What platform? Well, the SharePoint environment has to run on a Windows Server. The minimum requirements are Windows Server 2008 R2, 32 GB RAM, Quad Core, with a 60 GB C: and 120 GB Data drive. So where should the server be? There are three options available to us:


-        Physical Servers -  Physical Servers are the traditional way of doing things and involve a piece(s) of hardware that are configured to perform the tasks of your business. Generally, this hardware is in your server room / break room.

-        Virtual Servers - A Virtual Server is normally one of many servers that operate upon a single physical server with each virtual server sharing the resources of the physical server between them.

-        Cloud Servers – Cloud Servers are virtual server but instead of the physical server being hosted in your environment, it’s hosted outside of your environment.


The best recommendation would be to use Cloud Servers in a hosted environment. A few of the pros are:


-        Scalable – add more server power in a moment’s notice.

-        Custom Infrastructure - clients can include custom network architecture, firewalls, load balancing and IP deployment.

-        High Availability - if a physical server fails, cloud servers are migrated to another physical server without experiencing an outage.

-        Sharable Computing Resources - no concern about lagging RAM or CPU power, even if another cloud customer's load grows.



So to summarize, the best bet to implement would be SharePoint 2013 in a cloud hosted environment and I would be remiss if I did not say that we at King Strategy Solutions specialize in analyzing your environment, capacity planning and determining the best approach as part of our SharePoint Landscape Assessment.

So you have SharePoint, now what…A discussion about adoption

You’ve gone to the seminars, your peers and direct reports have told you how great SharePoint was and how it will change the organization through collaboration. So you have SharePoint, now what. Usage is sporadic among various teams, there are some documents in SharePoint but it is not widely used and the user base ranges from developers who want to use custom web parts to employees that don’t know SharePoint exists. Depending on hardware, licensing, and staff, SharePoint can cost anywhere from $5,000 to $250,000 annually, so how do you get a return on that investment, adoption.

Dictionary.com defines adoption as “to take over as if it were one's own” and that is exactly the approach that department heads and business leaders need to take when looking at SharePoint adoption. SharePoint unlike most application is not what I call a “must-use” application like Microsoft Office. If you want to write a document, you must use Word. If you want to create a spreadsheet, you must use Excel. But when it comes to collaboration especially of content, all you need is a laptop with a “My Documents” folder and email and you are off and running. SharePoint is an “opt-in” application, like any IM application or any business social application (Yammer, Jive, etc.). So the approach must be different “firm but fair”.

So the question becomes how to create an adoption plan, right. Microsoft offers many templates and videos in their SharePoint Adoption Kit that assist organizations to “rah rah” users into using SharePoint. While that approach will work on some users, cheering the application doesn’t answer the biggest adoption roadblocks: “What will it do for me?”, “Is this something else I have to use to do my job?”, and “Do I have to use it?”

To address those concerns here are some simple ways to garner adoption:


Cardinal Rule #1: Thou shalt not send attachments over email

One of the biggest mistake organizations make is not making SharePoint their central repository of the truth. You are killing your adoption if you have one document stored in SharePoint and have another version of the document in as an email attachment. Instead of attaching, copy and paste the link to the document in SharePoint. That begins to get users in the habit of looking in SharePoint for documents. Habitual behavior is crucial to SharePoint adoption. A study was done and showed that 90% of all computer users open their email program first. They do it although no one told them to through instruction or policy. When asked why, over 70% of the respondents said “it’s a habit”. The same approach must be taken in SharePoint.

Cardinal Rule #2: Thou shalt command from the top down

A former client was looking at how to increase adoption in SharePoint, through many failed attempts once the organization’s CFO started using SharePoint for document reference for preparation of quarterly earnings calls the VP level reports naturally did the same thing. Once the VPs started using SharePoint to report the numbers, the Senior Directors began to use SharePoint to gather the numbers. You get the picture, Senior Executive buy in is crucial but more importantly, buy in must be top down. You don’t have to be a CFO, but if you are managing a team, once you start using SharePoint, the team will as well.

Quick Automation Wins

Cardinal Rule #3 – Thou shalt automate manual processes

More often than not SharePoint is seen as a document repository, missing all of the built-in out of the box automation functionality. If you have any data collection processes (and I bet your HR department has a ton), SharePoint out of the box can very easily automate and streamline those processes to increase usage and adoption, more importantly answer that question “What can it do for me?”. Some very simple out of the box processes that can be automated are:

  • On/offboarding through the use of task lists and alerts
  • Open Enrollment through the use of InfoPath and a forms library
  • Training Registration
  • Expense Reporting

(I told you HR has a lot of processes that could be streamlined)

In conclusion, taking very simple steps will not only increase your adoption but increase the return on your investment and I would be remiss if I did not say that we at King Strategy Solutions  specialize in analyzing your environment and determining the best adoption approach as part of our SharePoint Landscape Assessment.

Joseph King

Senior Sharepoint Collaboration Expert

Why good consultants are rarely available

“Where are you in your career,” a question asked often by recruiters.
As an Enterprise consultant, I often find these types of questions, generic and humorous. Seriously! What consultant or consultancy, with a myriad of skills, is randomly available on a Tuesday? If they are, this is a red flag. We are never not working on a project (or 10) and in the bidding process for others. Certainly, some projects are cancelled or budgets are cut, however, we are never idle. At least not the good guys.

According to a poll conducted by CNN Money, there are 5.8 million IT jobs available. With this insight, I have asked several of my colleagues if they have encountered these types of questions. 95% of them say this is a regularly occurring question and they share the same sentiment. I believe the future of solid IT skills will be scheduled in advance, like buying a Tesla or Koenigsegg 1-to-1. I'm left to think and wonder; is the current style of finding good talent antiquated, and in alignment with the "good ole days", where you could bill unlimited fees, travel, and get per diem and expenses approved with only knowing your manager really well? Or, are we looking to update and shift paradigms as quickly as technology itself shifts.


Calling JSONP / JSON WCF Service from HTML

The code below allows you to hit a WCF service and return the results. Use any version of jquery.min.


                        type: "GET",

                        url: "http://www.iamcalvinbrown.com/wcf/Authentication.svc/sayHello",

                        success: function (j) {

                            console.log('inside results');



                        error: function (j) {





Enabling CORS in WCF

Familiarize yourself with these items:

1. Global.asax - Application_BeginRequest method
2. Exact url that will be requesting data

Note: http://localhost will not work. Please specify the port (ex: http://localhost:234) if you're running in development mode.

By adding this to your Global.asax, you allow the caller to hit your service and get a return. Otherwise, the status will be a 200, but with a readyState of Load.

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:61417");
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE");

                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");

Creating a Table Variable in SQL

Table variables are excellent for the temporary needs of SQL developers to create a structure (in memory) and select data just as you would from a real table.

Declare @MyTableVar TABLE



first_name    VARCHAR(35),

last_name   VARCHAR(35)


WCF - Return JSON Content (for Angular consumption)

Note: If you use string as a return type, it will not work when consumed directly by Angular.

You need 3 pieces:

  1. WCF Service (ex: RestService.svc)
  2. WCF Interface Class (ex: IRestService.cs)
  3. Newtonsoft.Json (install this package)
What the interface should look like:
public interface IRestService
      void getContentInJsonFormat(string id);

What the WCF Service looks like:
public class RestService: IRestService
     [WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle =WebMessageBodyStyle.Bare)]
    public void getContentInJsonFormat(string id)
          string workingString = "some random text or object";  // you should actually put a Json string here or create a class to return

         HttpContext.Current.Response.ContentType = "application/json; charset=utf-8";
         HttpContext.Current.Response.Write("[" + JsonConvert.SerializeObject(workingString) + "]");

How to call this service:
(when hosted) http://www.IamCalvinBrown.com/restservice/IamCalvinBrown/123
(locally) http://localhost:3242/RestService.svc/IamCalvinBrown/123

The url is unique to your website, so please don't use port 20949 unless it's actually your sites port. RestService is the name of the WCF service. 123 is the input parameter.

Happy coding.

Generate a Random name from an array using JQuery

We have an array of items, and we want to pull the item out of the array by id. In this case, the id is randomly generated. If found, show the name.

1. There should be a div somewhere in the body of the screen named message_div


<script type="text/javascript">

$( document ).ready(function() {

var array = [ 

{'id':'1' ,'name':'IamCalvinBrown'} , 

{'id':'2' ,'name':'Calvin'}, 

{'id':'3' ,'name':'Nailah'}, 

{'id':'4' ,'name':'Kendi'},

{'id':'5' ,'name':'Everybody'}, 


$("#changeTextButton").click(function ()


// generate a random number between 1 and 5 (change the 5 to increase with the size of the array)

var _randomNumber = Math.floor((Math.random() * 5) + 1);

// find the specific item in our list

// findById takes the array from above and the randomNumber generated



function findById(source, id) {

 var _id = id.toString(); // conver the number to text since we are generating random numbers


 for (var i = 0; i < source.length; i++) {

if (source[i].id === _id) {

 return source[i].name;



 throw "Couldn't find object with id: " + id;




Remove special characters from a string in C#

public static string RemoveSpecialCharacters(string str)


            StringBuilder sb = new StringBuilder();

            foreach (char c in str)


                if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '.' || c == '_')





            return sb.ToString();


Adding 2 decimal spaces and a dollar sign to a decimal in C#

decimal _someValue = 123.4m;

_someValue.ToString("C").ToString(); // the output is: $123.40

Make all urls lowercase in MVC

The line highlighted in yellow sets all urls to lower case. this is more visually appealing to the users and less confusing with longer urls.

public static void RegisterRoutes(RouteCollection routes)



            routes.LowercaseUrls = true;




                   new { controller = "Home", action = "Index" }



                "Index", // Route name

                "{controller}/{action}/{id}", // URL with parameters

                new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults



How to get Angular to display HTML

The important items to note here are two things. 1 is the angular-sanitize.min.js file which manages the html rendering, and the ng-bind-html attribute. It can be added to a div, span, etc, however I used it on a paragraph tag in this example.

The code that's displayed to the users

<div ng-app="myApp" ng-controller="myCtrl">

          <p ng-bind-html="description"></p>


The code (note: should be enclosed in a <script> tag

var app = angular.module('myApp', ['ngSanitize']);

var _desc = '<b>this is</b> sample html being displayed;

 app.controller('myCtrl', ['$scope' ,function ($scope) {

                $scope.description  = _desc;


Get a Querystring parameter in JQuery


var customerId = getParamByName('id');

 console.log("ID: " + customerId ); // write out the value

  function getParamByName(param) {

          paramparam.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");

          var regex = new RegExp("[\\?&]" + param+ "=([^&#]*)"),

          results = regex.exec(location.search);

          return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));


Adding a WebMethod to a .cs page

When you want code that can be called by JQuery inside your .cs page, you only need to add the [WebMethod] attribute.

Please note, the name of the method is erroneous, and this method returns no data. Have your function return a complex object (POCO), or a string. The Json below will deserialize it and return it to JQuery.


using System.Web.Services;



        public static string getSomeDataFromSomePlace()




                // method that returns data from the DB, a webservice, etc

string _objectOrPlainText = string.empty; // clearly this won't return anything -- go fetch data here


            catch (Exception ex)


                log.Error("SalonProfile:getSalonAmenitiesAndDescription", ex);


            string json = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(_objectOrPlainText);

            return json;


Selecting an item by name in a dropdown in JQuery

<select id="clients">

 <option value="1" >John</option>

  <option value="2">Calvin</option>

  <option value="3">Adjo</option>


// the list above is named clients, so the code below will select the item by name
$("#clients option:contains('Calvin')").attr('selected', true);

Setting the default page in web.config

Google wants the first page of websites to work with a simple / . To enable your site to be search friendly it's always best to set the default page that you site will render. Below is an example of how to do this:

      <defaultDocument enabled="true">    <!-- this line enables default documents for a directory -->
            <clear/>     <!-- removes the existing default document list -->                
            <add value="login.aspx"/>     <!-- login.aspx is now the default document  -->                
            <add value="index.aspx"/>     <!-- 2nd default document in search order -->                
            <add value="iamcalvinbrown.aspx/>     <!-- 3rd default document in search order -->
      <modules runAllManagedModulesForAllRequests="true"/>