On SharePoint Development

by dave Wed, January 04 2012 17:56

This month at the Tri-State SharePoint user group, I’m beginning a new series of lectures entitled On SharePoint Development.  The idea is to step back a little bit from the how of our daily grind and spend some time talking about what and why.  We will discuss topics that people don’t take the time to think about in the rush to get their day to day jobs done – more of a thought-provoking session than a “here’s how you do it”  (although there will be demos and discussions of how to accomplish many of the tasks discussed).  The goal is to make us better SharePoint professionals by improving our work habits and making us more efficient.

A former boss of mine used to call this working “on the business” instead of “in the business”.

This is part of a larger effort I’m kicking off in the new year related to this topic.  I’m planning on video taping many of these sessions and posting them, along with white papers/articles, etc.  Here’s an idea of the types of topics I plan on covering:

  • Declarative vs. Programmatic – creating SharePoint artifacts
  • Programming SharePoint with JavaScript – why, where and how
  • Cross-Cutting Concerns
  • Tool Use – “What Does It Cost to be a SharePoint Dev?”
  • Deployment and Installation – batch files and scripts?  Really?
  • VS Project & Solution Design
  • Testing – UI, Unit, Automated, etc – (covering the why and where, not so much how)
  • Team Dev – when the team includes end users 
  • Performance, and why it doesn’t matter
  • Application building blocks in SharePoint
  • “Code is Not Evil”
  • Naming Standards and Pretty Code
  • Consistency - not a Hobgoblin
  • Code Reviews – check your ego at the door

While I typically dislike announcing things when I don’t (yet) have anything to show, I needed to put this stake in the ground and get this started.  Stay tuned for more information.

Tags:

Development | Announcements | SharePoint 2010 | Tri-State SharePoint

SPListItem != SPListItem?

by dave Thu, December 15 2011 19:23

I’m not entirely sure what this means, but I found it curious…

I had a big block of unoptimized code in a project I’m working on and so I lost track of what variables I had and where they had come from.  At one point, I created an SPListItem by retrieving it from an SPListItemCollection.  So  far, so good.  Nothing unusual:

SPListItem itm = lic[0];

Later on, after checking that this item represented an SPFolder, I grabbed it’s corresponding folder object:

SPFolder myFolder = itm.Folder;

Later still, I had to grab a column value.  Forgetting that I had the SPListItem directly, I went this route:

string myValue = (string)myFolder.Item[“myField”];

In stepping through my code, I found that myValue was null, when I knew that it did, in fact, have a value.  Looking at my code to figure out what I could have f-ed up, I saw the itm variable again.  I didn’t expect it would fix my problem, but it would be cleaner to work directly with it instead of going through the folder object, so I changed my code to:

string myValue = (string)itm[“myField”];

Now when stepping through my code, myValue wasn’t null, it threw an ArgumentException error.  WTF?

So, in other words:

SPListItem != SPListItem.Folder.Item

even though both are SPListItems, and I would have assumed the same SPListItem (which they really are because both have the same ID, there’s just something screwy going on with the available fields).

This is mostly a note to myself to fire up Reflector and see what is going on when I have more time.  I’ll try to remember to update this post if I can figure it out.

Imagine that…another head-scratcher from the SharePoint object model…

Smile

Tags:

Development | SharePoint 2010 | Notebook

SharePoint Tips

by dave Wed, December 14 2011 19:56

Last night at the final @TSSSPUG meeting of 2011, Michael Mukalian and I presented an informal couple of sessions covering various tips that we’ve learned over the years of beating our heads against the SharePoint wall.  Here’s a quick review of what I covered…

 

JavaScript & JQuery Intellisense

Add the following lines to the top of your .js files to get intellisense for JQuery and the Client OM:

/// <reference path="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\MicrosoftAjax.js" />
/// <reference path="c:\IntellisenseFiles\jQuery-1.7-vsdoc.js" />
/// <reference path="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\SP.core.debug.js" />
/// <reference path="C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\SP.debug.js" />

Note that the path in the second entry is to a folder on my dev machine where I put the –vsdoc files downloaded from the JQuery website.  Adjust your path as appropriate.

Developer Dashboard

I did a quick overview of the DevDash and why it is useful.

CKS:Dev

There’s NO REASON not to use this tool.  Just Do It.  www.cksdev.com

O365 FxCop Rules

If you’re doing Office 365 development, this is another must-have tool: http://o365fxcoprules.codeplex.com/

Resolving Sandbox timeout errors

On a development box only, add the following entry to your HOSTS file to improve the responsiveness of your sandbox process when it is starting up: 127.0.0.1     crl.microsoft.com

Adding a "close" link to the Status Bar with your status messages

var statusId=SP.UI.Status.addStatus("Title", "Hello World Status Message <a href='javascript:SP.UI.Status.removeStatus(statusId)'>[Close]</a>");

Using PowerShell in the VS Pre/Post Deployment steps

%windir%\sysnative\windowspowershell\v1.0\powershell -file "$(ProjectDir)MyPSScriptFile.ps1" where MyPSScriptFIle.ps1 contains your PoSh commands to be run

(source: http://www.thesharepointbaker.co.uk/2011/12/post-deployment-powershell-sharepoint-visual-studio/)

Using LinqPad as a snippet compiler/tester

LinqPad: (free) http://www.linqpad.net/

 

Hopefully folks got some value out of the session.

 

Dave

Tags:

Presentations | Office 365 | Tri-State SharePoint | Development | CKS | JavaScript | Notebook | SharePoint 2010

CKS:API update and AOP

by dave Tue, November 15 2011 23:48

CKS:API is still moving along. It’s a little behind schedule due to work constraints.  Two new developers have joined the project and I’m looking forward to some additional eyeballs on the code to help tighten it up.  I’m also looking into Aspect-Oriented Programming (AOP)  to overcome one of the big hurdles in CKS:API – littering all of that logging code throughout your codebase.  I’m hoping that AOP will work as advertised (I’m using PostSharp, which seems to be the standard for AOP in .Net) and if it does, then parts of CKS:API will be refactored to make this an option.  PostSharp has a free “community” edition so it won’t necessarily shut anyone out.  You’ll still have the option of manually inserting the logging code on your own, so this is not a show-stopper requirement for using CKS:API if we do go that way.

Stay tuned…more details to come…

Tags:

CKS | Development | ProDev

CKS:API Beta 3 Release Notes

by dave Thu, October 06 2011 00:22

CKS Beta 3 launched this week to go along with my session at the SharePoint Conference.  I really wanted this to be a production-ready 1.0 release and I think it’s close, but I’d like to have feedback from more folks to make sure I haven’t overlooked things.  There’s still some tightening up I’d like to do and a few rough spots in the code but nothing too bad.  I’ll get them cleaned up soon, too.  I’d really like some feedback, though, so please kick the tires and let me know what you think.

What is CKS:API?

CKS:API is a library for use by developers to address the cross-cutting concerns of logging, instrumentation, exception handling and code contract support.  It is a library for use, not a standalone, fully-baked product.  Full source code is available on the Codeplex site: cksapi.codeplex.com

New Functionality

Using CKS:API hasn’t changed much since the beta 2 release.  There have been a few additions that I’ll cover here.  For information on other functionality, please see the beta 2 release notes.  I’ll also include a detailed usage walkthrough here to help you test things out.  But first, the new stuff:

  1. Logging functionality - a couple of new methods have been added to the logging classes:
    • DumpVariablesInDebug/DumpVariablesInRelease: Two similar methods, any calls to the former get removed by the compiler when you compile a Release build so they are not included in your production code.  Feel free to use it liberally.  Calls to the latter are not removed from your production code so they will execute and could slow things down if overused.  Just be careful.  In a nutshell, these two calls allow you to write information about your variables to your log (farm or sandbox) at any point in your code.  See below for a usage example.
    • WriteElapsedTimeStart/WriteElapsedTimeStop: another pair of related methods.  They allow you to log timings for arbitrary events in your code.  You call the first at the beginning of something you want to time and pass in a descriptive name.  You get back an ID.  call the second at the event of the event you want timed and pass in the ID.  The timing information will be written out to the log.
    • Monitor: This new method is related to the above two.  It gives you that ability to record timing information to the log.  The difference is that in Farm solutions, this will use SPMonitoredScope whereas in Sandbox Solutions, this will use the above two methods, since SPMonitoredScope is not available in the Sandbox.  I would expect that this would be used more often, with the above two coming into play only when you need more control or there isn’t an appropriate delegate for your needs). 
    • Sandbox Logging Configuration: You can now control the amount of information written to the sandbox log by setting a property called “CKSAPI_LogLevel” on the RootFolder of the SandboxLoggingList.  The SandBoxLogger checks this property to determine whether to add each entry to the log.  The SandboxTest project includes a rudimentary webpart that allows you to set this value.  I’d like to clean this area up a bit before the final release. It is critically important to use this efficiently to avoid using too many resources in your sandbox solutions.
  2. SPDisposeCheck Integration: I was running SPDisposeCheck against the code previously to check for Dispose problems, but now its fully integrated and I’m using the SPDisposeCheckIgnore attribute as appropriate to avoid false positives.
  3. Office365/SharePoint Online: For the first time with this release I started testing against Office 365.  Previously I was testing only in my local development sandbox.  I started using the Office 365 FxCop tools from Codeplex (http://o365fxcoprules.codeplex.com/) to validate that my code would run in Office 365 and found that there were a few items I needed to change in the code.  I came across a couple of additional situations where Office 365 would choke on the code and I’m working with Kimmo Forss (the author of the rules project) to get my updates included in the Codeplex project.
  4. NotifyAdministrators – it is now possible to create an entry in a separate SharePoint list for events that happen in your processes.  Combine this with SharePoint’s support for alerts/notifications and you now have an easy way to notify administrators (or really anyone) of an event happening in your code that they may need to know about.

Other than that, there was more cleanup and tightening of the code.  As I mentioned, there’s still more to go here.

CKS:API Usage Walkthrough

To begin working with CKS:API there are a couple of steps that you need to take.  I’ve tried to keep these as few as possible. 

  1. Include the CKS:API assemblies in your package so that they get deployed.  The CKSAPI assembly is required for all projects, you’ll also need either CKS.FarmInstrumentation.dll or CKS.SandboxInstrumentation.dll

    image

  2. Add References to the appropriate DLLs in Visual Studio
  3. Now we need to add code to initialize our logging environment.  For all projects, add code similar to the following to a Site Collection scoped Feature:

     image

  4. For Farm Solutions only, add code similar to the following to a Farm-scoped Feature:

    image

  5. Add the following using statements to your code:
    • image 
  6. Now you can start using CKS:API in your code.  See the sections below for details on the various pieces of functionality and how you can use them.

Simple Logging

Writing to the logs for either Sandbox or Farm solutions is simply a matter of making a call to either of the Write overrides:

image

The former is obviously quicker – all you need to do is specify the actual message to be written.  It will written to the log with a category of “General” and a severity of “Information”.

The latter override allows you to specify a category and a severity.  The CKSLoggingCategory enumeration defines 58 different categories currently and you can add more if the ones I’ve provided don’t meet your needs.  Examine the CKSLoggingCategory.cs file for the existing values.  (By adding new items to the enumeration, they will be included in the Central Administration “Manage Diagnostic Logging” facility – more on that later). 

The LoggingSeverity enumeration defines 5 possible values: Information, Timings, Warning, Error, Critical Error.  They are used to control when information is written to logs, according to how the logging is configured in your environment.

Farm logging writes to either the ULS or the WIndows Event Log. Sandbox logging writes to a standard SharePoint list created in the root of the site collection.

Logging in the Sandbox

If you’re working in the Farm, there’s nothing you need to do to prepare for logging.  The above will suffice.  Sandbox logging is a bit different, though.  In order to maintain performance and reduce the Resource impact of running this code in the Sandbox, we batch the sandbox log entries in a List<string> variable and flush them out to the SharePoint list.  In order to support this, we need to tell the logger to begin and end our batch.  We do this with calls to <SandboxLogger>.BeginScope() and <SandboxLogger>.EndScope().  My recommendation is to put these calls in your page/control lifecycle events as opposed to putting them in each method:

image

Instrumentation

Instrumentation sits on top of logging.  Logging is simply a facility for recording data.  Instrumentation is the capturing of data that will be meaningful when analyzing or debugging your code.  CKS:API provides several facilities for supporting instrumentation:

Dumping Variables

When debugging your application, it is often useful to know the values of some variables when an exception happened.  The two methods DumpVariablesInDebug and DumpVariablesInRelease allow us to do this.  See the beginning of this post for the difference between these tow methods.  Using them works exactly the same, though:

image

You make the call to the DumpVariablesInxxx method and pass in a collection of CKSVariableWrapper objects.  The CKSVariableWrapper object allows you to specify:

  • the name of the variable (
  • the current value of the variable
  • (optionally) a string collection of property names on an object variable that you want to dump.

In the code snippet above, we’re dumping three variables: AN SPList, a string and an Int.  For the SPList, we’re explicitly stating that we want to dump out the values of the Title, ItemCount and CanReceiveEMail properties.  For the string and int variables, there are no properties to dump, so we simply dump out the values of these variables.  The end result of this call is:

image

Timings

Another common need when debugging is to know how long certain pieces of my code are taking to run.  While most of the time, we would want to do this with our full Load Tests (and we all do load testing, right?), there are still times when we want to see some basic timing information in regular runs of our code.  CKS:API provides for this.  Begin timing by creating a GUID variable and calling the logger.WriteElapsedTimeStart method.  You pass in a string value that uniquely identifies the particular event/events you want to time.  You get back a unique identifier that identifies this timing instance.  Ending a timing requires you to call logger.WriteElapsedTimeEnd and pass in the GUID you got back previously.  CKS:API will now record the elapsed time between your start call and your end call.

Here’s the code:

image

And here’s the end result in my logger (the ULS log is shown, the sandbox log would be similar):

image

Debug Logging

We’re interested in different information when we’re actively coding and debugging our code than when we’re running that code in production.  We potentially want to see a lot more detail about our running processes than what we want to have logged in production.  However, we don’t want to have to go through and rip out all of that extra logging before compiling a Release build.  Instead, we take advantage of Visual Studio’s conditional compilation functionality to have the code excluded when we compile in Release mode. The following methods make use of this:

  1. Logging Method details: WriteDebugMethodStart and WriteDebugMethodEnd work in conjunction to log when we entered and exited a method.  Using them is simple:

    image

    And results in logging entries like these:

    image

  2. Logging Debug messages: The WriteDebug method allows you to add messages to the log in a Debug build but the call is stripped out in Release build so the code never executes:

    image

One comment about all of the debug methods – it is possible to use the normal Debug.Write calls in Visual Studio to achieve a similar end.  The reason this functionality exists in CKS:API is that it allows you to have all of your logging in one place, along with the out of the box SharePoint log entries (in the case of the Farm logger).  I find that a little easier than having some information in my log and some in the Visual Studio debug window.

Exception Handling

The Exception Handling in CKS:API hasn’t changed at its core, but the approach developers take to it has changed a bit in this release.  Before looking at the developer experience, here’s a quick refresher on the user experience:

Users will either see this:

image

or this:

image

depending on what the developer does.  In the background, a much more detailed error message is written to the logs.

New in this release is that developers can now override the color of the status bar and the text that shows up on the status bar.  If they don’t provide values for them, defaults are used.

Developers can make use of the Exception library in CKS:API as follows:

image

They can catch any type of Exception and process it via this mechanism.  In the initialization code for the CKSExceptionDetails object, the developer can specify:

  • The Display (shown): can be Dialog, StatusBar or None
  • The control that threw the exception
  • The category with which to classify the error – using the CKSLoggingCategory enumeration discussed above
  • The severity of the exception – using the LoggingSeverity enumeration discussed above
  • The StatusBarColor – using the CKSStatusBarColor enumeration
  • The User Text – override the default friendly error message shown to the user.

Code Contracts

CKS:API includes a rudimentary implementation of code contracts. It is not nearly as robust as what is available in .NET4, but it will help get you to start thinking that way.  The implementation of Code Contracts didn’t change in this release.  One thing I would like to do before releasing a 1.0 release is to use the Code Contracts more throughout CKS:API.  Right now, usage is a little spotty.

Code Contracts allow you to explicitly state what your software requires in order to operate properly. For CKS:API, this integrates with the Exception handling functionality to throw a specific error if the contract requirements are not met. This is implemented as a control class along with a bunch of validations, which are implemented as extension methods on various objects in the .Net framework.

In general, using a code contract consists of calling the RequiresThat method of the CodeContract class and supplying a condition to be checked. For example, the following code will ensure that the variable pageName is not null or an empty string:

Contract.RequiresThat(pageName.ValidateHasAValue());

    The comparison is functionally equivalent to

    string.IsNullOrEmpty(pageName)

    but by using the code contract, we also get the exception handling built in as well as opportunities for additional logging if we so desire. Preliminary performance testing indicates that the first usage of a code contract is marginally slower than the equivalent code (due to the loading of the additional assembly?) but subsequent usage in a request incurs no performance hit.

    If the contract is not satisfied, we will get a log entry similar to the following (in a Farm Solution):

    image

    (You would get a similar log entry in a Sandbox solution.) Because we’re using the exception framework in CKS:API, the user sees a nice user-friendly message as we saw previously.

    Currently, the following validations are supported as extensions to specific objects:

    String Double & Float Int
    ValidateHasAValue ValidateIsGreaterThanOrEqualTo ValidateIsOdd
    ValidateIsShorterThanOrEqualTo ValidateIsLessThanOrEqualTo ValidateIsEven
    ValidateIsLongerThanOrEqualTo ValidateIsGreaterThan ValidateIsGreaterThanOrEqualTo
    ValidateIsLongerThan ValidateIsLessThan ValidateIsLessThanOrEqualTo
    ValidateDoesNotContain ValidateIsEqualTo ValidateIsGreaterThan
    ValidateContains ValidateIsNotEqualTo ValidateIsLessThan
    ValidateDoesNotEndWith   ValidateIsEqualTo
    ValidateEndsWith Object ValidateIsNotEqualTo
    ValidateDoesNotBeginWith ValidateIsNotType<T>  
    ValidateBeginsWith ValidateIsType<T> IEnumerable
    ValidateIsExactLength ValidateIsNull ValidateAllAreNotNull
    ValidateIsShorterThan ValidateIsEqualTo ValidateAnyAreNull
    ValidateIsNotExactLength ValidateIsNotEqualTo  
         
    Guid    
    ValidateIsNotEmptyGuid    
    ValidateIsEmptyGuid    

    Question: Each validation currently begins with the prefix “Validation” which makes them easily discoverable, but personally I don’t like what it does to the code readability – it makes the code stilted. What do you think – keep the prefix or drop it?

    There is also a related piece of functionality in the Code Contract part of CKS:API – the ability to simply perform a check of a validation without throwing the error:

    Check.ThatAllAreNotNull(SPContext.Current, myVar, myVar2)

    This makes use of the same contract framework, but instead of throwing an error, it simply returns a boolean true if the check passes, or false if it fails. All of the same validations are supported.

     

    That pretty much closes out the CKS:API Beta 3 Release notes.  I would like to publish a 1.0 production-ready release by the end of October, so please give it a whirl and let me know any feedback – good or bad.

    Feedback

    Remember that this is a beta, but please post any issues to the Issue Tracker on Codeplex, or any questions to the Discussion forum

    Acknowledgements

    Various pieces of the CKS:API functionality would not have been possible if various members of the SharePoint community had not shared their work.  Thanks to the following folks for their help, it really helped me to finalize a couple of the tricky bits, especially related to some of the intricacies of the SPDiagnosticsServiceBase:

    1. Andrew Connell

    2. Todd Carter

    4. Jürgen Bäurle

    5. Andy Burns

    I need to dig up the links to their blogs/articles and will get them posted here in a quick edit soon (I’m trying to get this post pushed out before my SPC session so I’m a little short on time Sad smile ).

    Tags:

    SPC 11

    by dave Wed, September 28 2011 21:17

    Well, we’ve got just a couple of days until the SharePoint Conference kicks off in all its glory in Anaheim, CA.  I’ll be presenting one session on Wednesday afternoon – Instrumentation and Debugging on Premises and in the Cloud.  I’m running my demos through their final paces and making sure everything will run smoothly. 

    If you’re going to SPC from the Philly area, please track me down to say Hi.  If I’m not presenting or attending a session, I’ll likely be hanging out in the exhibit hall – probably spending a lot of time in the Critical Path Training booth.  Feel free to swing by there. 

    Speaking of CPT, check out AC’s post for their plans for SPC.  They’ve got a ton of stuff going on, lots of things to give away ($25,000 in free training!), book signings and more.  I really can’t recommend CPT highly enough if you’re looking for SharePoint training.

    This year’s SPC is looking really promising from a content perspective so it should be a great time.

     

    See you in Anaheim!

    Dave

    Tags:

    Ephemera

    Out of Box Columns are a Pain in the Ass

    by dave Wed, September 28 2011 00:56

    Before I begin my rant, let me qualify this by saying this only applies if you are building an *application* on top of SharePoint.  If you’re just using it largely out of the box for simple collaboration and content storage then this post likely doesn’t apply to you.  If you’re pushing things a bit and using SharePoint as an application framework, read on…

    Folders are a nice logical organization structure.  Sure, lots of people bemoan the use of folders, preferring a metadata-based approach, and I’m not going to argue that point here.  Suffice it to say that sometimes, perhaps especially when you’re building an application on the SharePoint platform, folders make sense.  So now let’s discuss why the out of the box columns are a PITA.

    Take for example, the Name column on the Folder content type.  If you’re following along at home, it has an InnerFieldName of FileLeafRef.  For whatever reason, you can’t delete this field (OK, I actually get this one…it’s used all over the place in SharePoint and deleting it would break things).  But the problem is, you can’t easily HIDE this column, either.  The CanToggleHidden property for this field is false and its read-only so we can’t change it.  This means that the code myField.Hidden = true throws an error.

    OK, so let’s not try to set the Hidden property, but let’s just remove it from the various places it shows up.  There’s nothing that stops us from setting the ShowInXXXForms properties (ShowInDisplayForm, ShowInNewForm, ShowInEditForm) to false.  That will achieve the same effect as setting Hidden to true, right?

    Unfortunately, no.  It appears that the default forms do not honor these properties, at least not for the FileLeafRef/Name field.  Here’s what I get after setting the ShowInXXXForms properties to false for FileLeafRef:

    image

    The field still shows up.  Sad smile

    Interestingly, if I run the same code, but have a custom form configured to display the content type, I get the results I expected:

    image

    Luckily, I am using custom forms for this application so I’ll get the results I wanted. 

    [EDIT: Make sure that you set the ShowInXXXForm properties AFTER the last content type is added to the list or else the fields will still show up]

    Dave

    Tags: ,

    Development | SharePoint 2010

    CKS:API Beta 2 Release Notes

    by dave Mon, September 12 2011 23:36

    CKS:API Beta 2 is live on codeplex: cksapi.codeplex.com.  This post will serve as the release notes for this release.

    As with the last release, this project is still in BETA.  It is not ready for production use, but it’s getting closer.  This release is *nearly* fully functional, but there’s a lot of cleanup and performance tweaking that still needs to happen.  The plan is to have that all complete and released by early October.

    Call to Action

    If you are interested, I would appreciate some feedback.  Please see the Functionality section below for more information, and please consider downloading the bits from Codeplex and testing things out.  If you come across any bugs, please log them to the Issues list on Codeplex – I’ve added some known bugs already.  If you have questions or ideas, please start a Discussion on Codeplex. 

    If you are interested in helping out, I’ll be ready for assistance after I get this to a v1 release in a few weeks.  Until that time, it would be harder to bring someone else on board and still hit that deadline.  But please feel free to contact me via Codeplex and give me some ideas of where you would like to help out.

     

    Functional Areas

    CKS:API currently consists of the following functionality:

    1. Exception Handling and user-friendly display
    2. Logging (Farm & Sandbox)
    3. Code Contracts

    Each of these will be detailed below.

    CKS:API Design Goals

    One of the primary design goals of CKS:API is to be an example of SharePoint development best practices.  It’s not quite there yet, unfortunately.  One of the drawbacks of “side projects” is that there’s a lot of starting and stopping and not a lot of up-front design.  This project has been refactored MANY times and so there are still some ghosts in the machine waiting to be cleared out.

    Other design goals include:

    1. Simplicity.  If a utility library doesn’t make things easier/better then why bother using it?  CKS:API is intended to make things easier for developers to write high quality applications.  This does not mean that it is simple internally, but it must be simple to use – at least simpler than writing the code manually.  For example, validating that a series of objects are not null could be written as:
      if (null == exception || null == display || null == throwingControl)
      {
           //throw an error
      }

      However, using CKS:API allows you to write this instead:

      Contract.RequiresThat(new List<object>() { exception, display, throwingControl }.ValidateAllAreNotNull());

      Not only is this easier as the number of checks increases, it also gives some context and intention to the code – we’re enforcing a software contract.  The mechanics of throwing the error and maintaining a friendly user experience are hidden from us as there’s no reason for us to have to deal with them every time we want to enforce a contract.

    2. Ease of Use.  If a library places too many requirements on developers before they can even start using it then it is not worth the hassle.  Using CKS:API was  designed to place the smallest number of requirements on the developer as possible.  More details on this are in the Using CKS:API section, but basically it consists of adding the assemblies to your project and your Solution Package and making one method call to prepare the environment.  That’s it.  You’re now ready to start using CKS:API in your projects.
    3. Best Practices.  Yes, I fully realize that this term is so over used as to be almost meaningless, but it is a design goal anyway.  As I mentioned previously, it is not quite there yet, but it is getting there.  What I mean by best practices is simply that the code makes an effort to:
      • be of high quality – there was some thought that went into the code and it wasn’t just tossed together randomly.  This doesn’t mean that every single line is perfect as there are always trade-offs for one thing or another.  It simply means that the code is intentional and the best possible code considering all known situations and trade-offs
      • be consistent – this was a biggie, especially when trying to reconcile sandbox logging and farm logging.  It was important that the experience between the two be as consistent as possible to make things easier for developers.  Sometimes this meant that the implementation details were a bit contrived internally, but the experience for developers is nearly identical whether they are logging to the ULS or to a list (in the case of the sandbox)

    Using CKS:API

    CKS:API is a utility library to be used in other projects. It is not something to be installed to your SharePoint environment by itself. To that end, it does not consist of typical SharePoint Solutions and Features. Why is this? Simple. You don’t install a utility library just for the sake of it – it is just included as part of whatever “real” application you are installing so why should you have to activate a Feature in SharePoint just to make a utility library available?

    Here’s how you would use CKS:API in one of your projects:

    1. Add a reference to the library assemblies in Visual Studio.  There are three assemblies that make up CKS:API:
      1. CKSAPI.dll – (required for all projects).  This is the core library
      2. FarmInstrumentation.dll – required in farm projects
      3. SandboxInstrumentation.dll – required in sandbox projects
    2. Add the assemblies as Additional Assemblies in Package Explorer.
    3. To use logging, instantiate either the CKSFarmInstrumentor or the CKSSandboxInstrumentor object and call it’s InitializeEnvironment method (this should typically be done in your feature receiver)

    That’s it.  You can now start using CKS:API in your projects.  For details on what is available and how to use it, see the Functionality section below.

    The source code includes 2 simple sample projects that can be used as the basis for testing – one for Sandbox and one for Farm.

    Functionality

    There are three main areas of functionality for CKS:API: Exception Handling and user-friendly display, Logging (Farm & Sandbox) and Code Contracts.  Details on each of these are provided here.

    Code Contracts

    First, this is not functionality that is intended to replace or even be compared to what is available in .Net 4.  Conceptually they are similar, but I fully expect to tear this section out of CKS:API once SharePoint can use .Net 4.  In that sense, it is just a stopgap measure to improve the general quality of our code in the short term.

    Code Contracts allow you to explicitly state what your software requires in order to operate properly.  For CKS:API, this integrates with the Exception handling functionality to throw a specific error if the contract requirements are not met.  This is implemented as a control class along with a bunch of validations, which are implemented as extension methods on various objects in the .Net framework. 

    In general, using a code contract consists of calling the RequiresThat method of the CodeContract class and supplying a condition to be checked.  For example, the following code will ensure that the variable pageName is not null or an empty string:

    Contract.RequiresThat(pageName.ValidateHasAValue());

      The comparison is functionally equivalent to

      string.IsNullOrEmpty(pageName)

      but by using the code contract, we also get the exception handling built in as well as opportunities for additional logging if we so desire.  Preliminary performance testing indicates that the first usage of a code contract is marginally slower than the equivalent code (due to the loading of the additional assembly?) but subsequent usage in a request incurs no performance hit.

      If the contract is not satisfied, we will get a log entry similar to the following (in a Farm Solution):

      image

      (You would get a similar log entry in a Sandbox solution.)  Note that there is currently an open issue getting the name of the parameter that failed validation, which is why it shows up as “Unknown.”  Because we’re using the exception framework in CKS:API, the user sees a nice user-friendly message  - more on that later.

      Currently, the following validations are supported as extensions to specific objects:

      String Double & Float Int
      ValidateHasAValue ValidateIsGreaterThanOrEqualTo ValidateIsOdd
      ValidateIsShorterThanOrEqualTo ValidateIsLessThanOrEqualTo ValidateIsEven
      ValidateIsLongerThanOrEqualTo ValidateIsGreaterThan ValidateIsGreaterThanOrEqualTo
      ValidateIsLongerThan ValidateIsLessThan ValidateIsLessThanOrEqualTo
      ValidateDoesNotContain ValidateIsEqualTo ValidateIsGreaterThan
      ValidateContains ValidateIsNotEqualTo ValidateIsLessThan
      ValidateDoesNotEndWith   ValidateIsEqualTo
      ValidateEndsWith Object ValidateIsNotEqualTo
      ValidateDoesNotBeginWith ValidateIsNotType<T>  
      ValidateBeginsWith ValidateIsType<T> IEnumerable
      ValidateIsExactLength ValidateIsNull ValidateAllAreNotNull
      ValidateIsShorterThan ValidateIsEqualTo ValidateAnyAreNull
      ValidateIsNotExactLength ValidateIsNotEqualTo  
           
      Guid    
      ValidateIsNotEmptyGuid    
      ValidateIsEmptyGuid    

      Question: Each validation currently begins with the prefix “Validation” which makes them easily discoverable, but personally I don’t like what it does to the code readability – it makes the code stilted.  What do you think – keep the prefix or drop it?

      There is also a related piece of functionality in the Code Contract part of CKS:API – the ability to simply perform a check of a validation without throwing the error:

      Check.ThatAllAreNotNull(SPContext.Current, myVar, myVar2)

      This makes use of the same contract framework, but instead of throwing an error, it simply returns a boolean.  All of the same validations are supported.

      Exceptions

      CKS:API provides a couple of standard custom errors currently and there are plans to define more.  Right now it supports:

      • CKSException – the base class for all CKS:API exceptions
      • CKSContractException : when a contract is violated
      • CKSInvalidOperationException: when an invalid operation happens
      • CKSValidationException: when a condition check fails validation
      • CKSWrapperException: used to wrap a standard .Net exception to provide a consisten logging and end user experience even when the standard .Net exception classes are used.  This also allows us to support the processing of unhandled exceptions.

      The goal behind the exception handling is to provide detailed information to the administrators and developers while showing a consistent, friendly error message to the end users.

      Depending on how the developer uses the framework, the user will see either a StatusBar message:

      or a dialog box:

      image

      [NOTE: The contents of this user error page are currently hardcoded into CKS:API and are not functional.  I’m not sure that CKS:API will ever implement this and it will likely be left up to anyone using the product to define the error page they want their users to see.]

      In some cases (notably when an unhandled exception occurs, the user sees the same dialog page but in the full browser window instead of the modal dialog box.  If the user click the “Help” link in the StatusBar, they will be shown the dialog box.

      From the developers perspective, things couldn’t be easier:

       try
      {
          throw new CKSInvalidOperationException("oops...something bad happened");
      }
      catch (Exception ex)
      {
          instrumentor.HandleException(ex, ErrorDisplayType.StatusBar, this);
      }
      (instrumentor, in this example, is an instance of a CKSFarmInstrumentor object). 

      Detailed logging information is either written to the ULS log for Farm solutions (as seen above for the Contract) or to a SharePoint list, for Sandbox solutions:

      image

      Notice that the sandbox logger makes use of append-only fields and batches the information written into groups to reduce the number of writes to the SharePoint DB, and therefore the number of resources used.  See below for more details on each logger.

      Handling standard .Net exceptions is identical to handling CKS exceptions – simply call HandleException on your instrumentor and pass in the exception, how you want the information displayed (choices are StatusBar, DialogBox or None) and a reference to the object that threw the error (this).  CKS:API takes over from there and handles it all for you.

      The last piece of functionality in the Exception framework is the handling of otherwise unhandled errors.  If an error happens anywhere in the processing of your page that you do not catch and deal with, instead of seeing a standard error message, the users will be shown the dialog box page (not inside the modal dialog box though).  Note that there are currently a few bugs in this section:

      1. The exception information is not currently logged for unhandled exceptions
      2. Sandbox solutions are not shown any error message.  They simply see their page with no indication that anything happened.  This is better than the standard “an error has occurred in the target of an invocation”  message that users love so much, but not ideal.  Hopefully this will get resolved in the next release.

      Logging

      The last piece of functionality included in CKS:API is a logging framework.  The goal of this piece is to provide a consistent, highly functional logging solution regardless of whether the code is running in the sandbox or in a farm.  To that end, CKS:API provide the following methods:

      • LogError
      • LogInformation
      • LogWarning
      • WriteToDeveloperDashboard
      • LogDebug
      • LogMethodStart
      • LogMethodEnd

      The first three are fairly obvious in what they do.  The last four might need a little explanation:

      • WriteToDeveloperDashboard: writes a message to the Developer Dashboard (duh) in a somewhat more simplified way than what you get out of the box.  In addition to supporting the standard SPMonitoredScope approach (currently only one implementation is included), it also provides the ability to write arbitrary messages to the Dashboard.  This all works for a Farm environment just fine.  What I’m hoping to do is extend the same (or at least similar) functionality to Sandbox solutions as well, something not generally considered possible.  I’ve got a few ideas that I hope to get in place in the next release.
      • LogDebug: Gives the developer the option of writing messages to the log that will only execute when the assembly is compiled as a DEBUG build.  When they compile their project in a RELEASE build, the calls to this method are automatically stripped out.  This means that the developer can go crazy writing debug information into the log while they are developing their code and not have to worry about stripping them out before doing a Release build.  The compiler does it for them by means of the conditional compilation directives available in Visual Studio.  There is exactly zero performance impact to that extra logging because the calls are simply not included in the Release build.
      • LogMethodStart/LogMethodEnd: This is part of that “going crazy” writing debug information into the logs I mentioned earlier.  Adding this call to the beginning/end of your methods will automatically create a log entry with the name of the method and the time.  This can be useful for tracing through your code to uncover nasty little Heisenbugs.  These both make use of the same conditional compilation as LogDebug so there’s no reason to remove these calls from your source code before compiling a RELEASE build. 

      Closing

      That about wraps up the information for beta 2 of CKS:API.  Please take it for a spin and let me know what you think.  Just remember the standard developer disclaimer – this is still a work in progress so no laughing at my code   Smile

      Feedback

      Remember that this is a beta, but please post any issues to the Issue Tracker on Codeplex, or any questions to the Discussion forum

      Future Releases

      I am currently planning the following release schedule:

      • Production-ready 1.0 – October 2011.
      • Bug Fixes 1.1 – 1.9 as needed.

      -Dave

      Tags:

      CKS:API Beta 1 Release Notes

      by dave Tue, August 09 2011 01:10

      CKS:API Beta 1 is live on Codeplex: cksapi.codeplex.com.  This post will serve as the Release Notes for the Beta 1 release.

      First and foremost, this is a BETA release.  The project changed considerably between Alpha and Beta and while I don’t expect future releases to include such a massive internal change, there will absolutely be changes to the structure of things.  Furthermore, this is a BETA, it is not ready for prime time.  If you have a few minutes to test it out on your DEV environment and offer some feedback, that would be great.

      Design Goals of CKS:API

      CKS:API is in a large way, a utility library.  It is not something to be installed to your SharePoint environment by itself.  To that end, it does not consist of typical SharePoint Solutions and Features.  It is a collection of assemblies to be included in other projects.  Why is this?  Simple.  It is a utility library at heart and you don’t install anything for utility libraries – they are just included as part of whatever “real” application you are installing.

      This brings me to one of the primary design goals of CKS:API – it does not place requirements upon you as a developer, other than a few simple method calls.  Using CKS:API is as simple as:

      1. Including the assemblies alongside your code – typically this means adding the CKS:API assemblies as “Additional Assemblies” in your Package Explorer:

      package explorer

      2. Make a call to the static Initialize method in CKSAPIUtilities.  (Technically, even this is not required as the code will just process with some defaults, but it is recommended)

      3. Use the functionality of CKS:API as you need.  See the Usage section later in this post for additional information about using CKS:API.

      Another design goal of CKS:API is to demonstrate best practices for SharePoint development, however, it is definitely not there yet.  I have a lot of code cleanup to do.

      Functionality

      For Wave 1, CKS:API consists of the following functionality: logging, exception handling/display and code contracts/validation.

      Logging

      This is basic logging right now.  It will eventually be expanded to include the Event Log, but for now it simply logs to the ULS.  The CKSFarmLoggingService includes the following methods for logging:

      • LogError – write to the logs with a category of “Error”
      • LogInformation– write to the logs with a category of “Information”
      • LogWarning– write to the logs with a category of “Warning”
      • LogCustom – write to the logs with a custom category
      • LogDebug – write to the logs with a category of “Debug.”  Also, this method makes use of Visual Studio’s conditional compilation feature so that any calls to the LogDebug methods are automatically stripped out when you compile a Release build of your project.  This means you can use these methods extensively in your code and not have to worry about them polluting your production code with unnecessary logging or having to go in and remove them all before compiling a release build.

      There is also some preliminary functionality for writing a message to the Developer Dashboard: WriteToDevDash.  This method will change in future releases, it’s really just something I was playing around with for now.  It gives you the ability to write a message to the Developer Dashboard without wrapping your code in a monitored scope.  You don’t get the monitoring capabilities currently, it is literally just a way to write some text out.  I’ll be expanding upon this to add more functionality in future releases.

      Exception Handling/Display

      Exception handling and display is arguably the biggest part of this wave of CKS:API.  The idea behind it is to make it really, really easy for developers to handle exceptions in their code and serve two audiences:

      1. Administrators or other developers, who need detailed error information to be able to troubleshoot
      2. Users, who don’t care about all that detail, they just want to be able to get their jobs done without having to jump through a lot of hoops.

      To this end, CKS:API includes a small collection of custom Exception classes (I’ll add more in the next release, I’m just keeping it small while I work out all the kinks).  Developers can make use of these in a typical try/catch paradigm:

      try
      {
          throw new CKSInvalidOperationException("oops");
      }
      catch (CKSException ex)
      {
          CKSApiUtilities.HandleException(ex, SandboxUtilities.IsInSandbox, ErrorDisplayType.Dialog);
      }

      The end result of this is detailed information being written to the logs:

      image

      but a nice use friendly error being shown to the users:

      image

      A few things to note:

      1. Currently only Farm Solutions are supported, but I anticipate achieving close to full feature parity for Sandbox Solutions
      2. The contents of the dialog box is currently hard coded and non functional.  I’m just trying to show the type of help that can pretty easily be shown to users.  I’m not sure how far the CKS:API project will take this side of things.  I may leave it as simply a framework for developers to extend as they need to.
      3. Notice in the screenshot from the ULS Log Viewer above, that the logging message automatically includes the name of the class and the name of the method that triggered the error.  When I add the Event Log integration, this is what will be written to the Event Log.  I’ll likely add a full stack trace to the ULS at that point.
      4. The last parameter in the HandleException method determines how the error is shown to users, either as a dialog box, as shown above, or simply an entry on the status bar:

      image

      If the user clicks the “Help” link on the Status Bar, they will be shown the dialog box.

      There is some capability to handle non-CKS exceptions in a similar manner.  In other words, the following code would deliver similar results, even though we are not throwing an exception derived from our base CKSException class:

      try
      {
          throw new Exception("Standard .Net Exception");
      }
      catch (Exception ex)
      {
          CKSApiUtilities.HandleException(ex, SandboxUtilities.IsInSandbox);
      }

      Finally, this release includes preliminary support for handling uncaught exceptions.  Adding the following code typically to the Load event of your page or control:

      CKSApiUtilities.CatchUnhandledExceptions();

      will result in, once again, a similar experience.  For example, this code:

      using (SPSite site = new SPSite("http://Invalid.Url"))
      {
          //Do Something
      }

      will still result in the following, even though the error happens outside our code (when SharePoint tries to instantiate an invalid site collection) and is not wrapped in a try/catch:

      image

      Contracts/Validation

      Last but not least is a rudimentary validation framework, which can also be used for something similar to code contracts in .Net.  This is likely best described with some sample code:

      CodeContract.RequiresThat(throwingPage, Validate.IsNotEqualTo, null);
      CodeContract.RequiresThat(myInt, Validate.IsLessThan, 0);
      CodeContract.RequiresThat(myObject, Validate.IsType, SPListItem);
      CodeContract.RequiresThat(myString, Validate.IsExactLength, 17);

      or if not used to ensure method parameters, simply validation:

       Validate.That(head, Validate.IsNotEqualTo, null);

      If any of these fail, then an exception is thrown by the contract/validation framework and handled as outlined above in Exception Handling/Display.  There are two specific exception types that are thrown, either a CKSContractException or a CKSValidationException.

      Usage

      Understanding usage of CKS:API is a bit of a shot in the dark for now.  I plan on addressing that with better test projects in a future release.  For now, you can review this post in more detail, take a look at the source code (specifically the simple web part in the CKSInstrumentationFarmTest project), or post a question on the Codeplex discussion forum for the project.  I monitor the discussions there and will respond as quickly as I can.

      Feedback

      Remember that this is a beta, but please post any issues to the Issue Tracker on Codeplex, or any questions to the Discussion forum

      Future Releases

      I am currently planning the following release schedule:

      Beta 2 (including bug fixes and Sandbox functionality) – early September 2011

      Production-ready 1.0 – October 2011.

      -Dave

      Tags:

      More fun with SharePoint and JavaScript

      by dave Mon, June 20 2011 10:33

      I was getting an odd error in a project in which the following line of JavaScript was throwing an error:

      var ctx = new SP.ClientContext.get_current();

      The error being thrown was: Microsoft JScript runtime error: Unable to get value of the property 'get_current': object is null or undefined

      This was odd because it the debugger was telling me that “ClientContext” was undefined.  Huh?  That doesn’t make sense. 

      Turns out the problem was the way I was calling the code.  The code above was in a function that I was calling from ExecuteOrDelayUntilScriptLoaded like this:

      ExecuteOrDelayUntilScriptLoaded(myMethod(), "SP.js");

      Do you see my mistake?  Yeah, I included the open and close parenthesis in the method call.  It should be:

      ExecuteOrDelayUntilScriptLoaded(myMethod, "SP.js");

      The error message certainly is a bit misleading…

      Tags:

      JavaScript | SharePoint 2010 | Development