Preparing Stand-alone SharePoint Farm for Apps Development

Microsoft has made it very easy to setup an development environment on Azure and if you are a MSDN subscription owner it is practically free. To get started with SharePoint development on Azure just follow the instructions published by the SharePoint team last year. Once you have the farm running you still need to complete additional steps to be able to develop and run Apps for SharePoint. Before you can start following the instructions provided by Microsoft some DNS configuration is required.

Assuming you are running with a single server NTML based setup, here is what you need to do:

  1. Use ipconfig /all through the command line to make notes of the machine IP and outside DNS server address
  2. Create a zone for the machine, name it e.g. sharepoint.local . Then make sure there is a host under the sharepoint-local pointing to the machines own IP.
  3. Edit the properties of the (DNS) server itself and add to the list of forwarders one pointing to the outside DNS server
  4. Create a zone for your apps, name it e.g. apps.com (primary zone)
  5. Add a cname under the apps.com with the fqdn *.apps.com and “full target name for target host” being e.g. <machine name>.sharepoint.local
  6. Finally check everything is working by running ipconfig /flushdns followed by trying to access your local SharePoint and the internet. Try also pinging e.g. whatever.apps.com

DNS settings

Advertisements

How to integrate with SharePoint

Thinker

There are numerous options to how to integrate your LOB systems with SharePoint. The answer tends to depend on who you ask, as SharePoint experts will tell yo to use BCS, Microsoft oriented consultants might recommend WCF /AppFabric and SAP consultants will tell you to go with Duet. The right approach depends of course on the actual business requirements. In this article I I will try to summarize the different approaches and highlight their pros and cons.

Continue reading

SharePoint Web Part Basics

All web parts are based on the same basic ingredients. When I started developing on my first web parts I did some extra work to find out the best practices. This post is meant to work as a simple reference and to answer some of the questions I had when I first started.

What web parts events should I use?

There are many different opinions on this. This is mine:

  • Never put code in the constructor as it might be called even if the object is later never used
  • In the OnInit initialize any controllers etc. you might have
  • In the CreateChildControls method create your controls, but don’t populate them. Note that it is a common practice to define all the controls and the wepart layout in a separate control class to keep the web part clean.
  • In the OnPreRender load the data into the controls and setup any async task you might need (they will be executed next)

How to register JavaScript?

There are many ways to include JavaScript on a page, the right one depends on your need. To include a script to to be executed directly after page load use the RegisterStartupScript combined with the ExecuteOrDelayUntilScriptLoaded (SOD) or _spBodyOnLoadFunctionNames.push functions:

public static class SharePointScriptHelper
{
public static string ExecuteOrDelayUntilScriptLoaded(Control control, string script, string after)
{
string script = string.Format("ExecuteOrDelayUntilScriptLoaded(function(){{{0}}}, '{1}');", script, after);
ScriptManager.RegisterStartupScript(control.Page, typeof(Page), "Script_" + control.ID, script, true);
}
}
SharePointScriptHelper.ExecuteOrDelayUntilScriptLoaded(this, "alert('Hello world!');", "SP.js");

The first mentioned takes care of the correct load order of scripts.

To include e.g. a library that is not meant to be directly executed use e.g. the RegisterClientScriptInclude method:

ScriptManager.RegisterClientScriptInclude(this.Page, typeof(Page), "MyScriptNamespace", ScriptFileUrl);

The point in using the ScriptManager is to avoid having the same script included multiple times, hence the key parameter in e.g. RegisterclientScriptInclude. The class offers a lot of functions that are worth taking a closer look at.

Note that is is a good practice to wrap you scripts in a “class”/namespace to avoid e.g. function name collisions with other scripts.

To easily include the web part id in your inline scripts you can use the ReplaceTokens function of the web part class to do this. It will simply replace tokens like e.g. _WPID_ with the correct property values.

How to include CSS on a page?

CssRegistration css = new CssRegistration();
css.After = "corev4.css";
css.Name = Settings.StyleSheetFileUrl;
this.Controls.Add(css);

I have not yet had a chance to test SharePoint 2013 to see if it works to refer to the corev4.css also in that version.

Where to define configuration parameters?

The web part definition file (yourwebpart.webpart) is definitely the only correct place. This way they the properties are fully customizable by the site owners when necessary.

Never store passwords in any file as they belong in the secure store service. You can prevent property values from being exportable for a simple way of hiding them.

How should I define my layout?

The most flexible and powerful way is to use XSLT for the rendering. You can implement it your self or inherit the DataFormWebPart class.

Where should I put the CSS, image and other files?

Put them in the appropriate SharePoint mapped folders. Always create a sub folder for you web part and give it a unique name e.g. based on the namespace of the main class.

How to do logging and debug?

Use the inbuilt framework. The most elegant solution would be to write your own service class deriving from the SPDiagnosticsServiceBase but note that it will need to be registered at deployment time.

public static class SPDiagnosticsServiceExtension
{
public static void WriteTrace(this SPDiagnosticsService service, string message, string categoryName, TraceSeverity severity)
{
SPDiagnosticsCategory category = new SPDiagnosticsCategory(categoryName, TraceSeverity.Unexpected, EventSeverity.Information);
service.WriteTrace(0, category, severity, message);
}
}

Usage

SPDiagnosticsService.Local.WriteTrace(ex.ToString(), "Web Parts", TraceSeverity.Unexpected);

I strongly recommend enabling the Developer dashboard and using the SPMonitoredScope to help optimize the performance of your web part.

That’s all for now, more to to come later.

Combining SharePoint Workflows and Calculated fields

In one of my projects I wanted to allow teams to work privately with their documents but also allow the rest of the organization to be able to access everything considered final. The two level versioning feature allowed me easily to do exactly this, but the challenge was to also find a way to encourage the teams to finally “publish” their items. The solution was to have a special column indicate the state of the item.

To make things more interesting, I decided to only use the dialogs of SharePoint designer and the web interface to accomplish this. The easiest way to insert HTML  into a list is by using a calculated column. Unfortunately, as I quite quickly found out, the calculated columns do not update on version and approval changes. The only workaround was to create workflow to react on these changes and then use the calculated column to generate the output.

This is what the list column setup looked like

The IsPublic column gets updated by the workflow and the Visibility column generates the HTML based on the value. There are many posts describing how to use a calculated column together with JavaScript to print out HTML, but all you actually need is to set the result type of the column to integer!

Using SharePoint designer I created the following workflow for the list

The problem with document libraries is that the file might not have been completely uploaded before the workflow kicks in. This is why the workflow needs to first make sure it can access the item before editing it.

There are probably many ways to check if there is a major version available, I decided to convert the version number (which is actually a string) to an int and see if it is higher than 0. After some trial and error I found out that the only way to convert a string representing a decimal (yes, the version column is a text field) value is by first converting it to a double.

The final task was to hide the IsPublic field from the list forms and find some nice icons to indicate the visibility.