Monday, 21 November 2011

Output a String With Escape Characters

Not something that is often required, but something that popped up today - how to get the literal output from a String object in C# including the escape characters.

So let's take a String variable declared like this:

string str = @"c:\temp";

The literal string is c:\temp, but what if we wanted the underlying escaped string which would look something like this:

"c:\\temp"

Not so easy.  Fortunately, Google being the fount of all knowledge these days, I put it to work in finding some help and unearthed a neat example from Stack Overflow using an Extension Method:

internal static class ExtensionFunctions
{
    internal static String ToLiteral(this String input)
    {
        var writer = new StringWriter();
        CSharpCodeProvider provider = new CSharpCodeProvider();
        provider.GenerateCodeFromExpression(new CodePrimitiveExpression(input), writer, null);
        return writer.ToString();
    }
}

To use it simply type str.ToLiteral(); and it will return the string complete with the escape sequence intact.

Friday, 18 November 2011

Using Parameter Binding

Nothing new here​, but Parameter Bindings (see Microsoft's article on them here) have been around for a while and more widely publicised for use with the Data Form and Data View Web Parts. Something not so widely know is that any web part inheriting from the Data Form Web Part also has the same functionality available.

This means useful web parts like Search Results, People Search Results, Content by Query Web Parts, Xslt List View Web Part, RSS Aggregator web part and more all have this available to them.

In SharePoint 2010, apparent new functionality made things like the query string available to the underlying Xslt in a Content by Query Web Part. The truth is that this was available in 2007 by using Parameter Binding and the QueryString Location property (as I blogged previously).

What is more useful, is that the Search Results and People Search Results now include a Parameter Binding property available through the web part toolpane which means that level of configuration can be done through the UI rather than hacking away at the underlying web part file. Entering the Parameter Binding is easy enough using the syntax:

<ParameterBinding Name="[name]" Location="[selected location]" />

for each property you want to use. The [name] is added into the Xslt for the Web Part as an Xsl Param and it's then available.

Useful, simply and quick. Something to bear in mind.

Thursday, 3 November 2011

Sandbox Solutions and the Update Panel

There are already several articles on the web​ relating to the use of the ASP.NET UpdatePanel in sandbox solutions, so to add to the mix, here's another one.

Sandbox solutions and the UpdatePanel: the truth of it is that you cannot use the UpdatePanel in sandbox solutions. If you try to use it you get an error stating "The control with ID 'UpdatePanel1' requests a ScriptManager on the page". Using the ScriptManager.GetCurrent returns null. If you try to add your own you get an error as you can only have one ScriptManager instance at a time. You can add your own, however, by adding it as the first control in the Form.Controls control tree, but even this will most likely break the page unless you duplicate the exact scripts you may be adding to the page in code - the symptom of this is the ScriptResource.axd that would normally contains your scripts returns with a 404.

That aside, the reason the ScriptManager.GetCurrent doesn't return the actual ScriptManager you have added to your page or master page is to do with the way sandbox solutions replace some objects with its own object types. For instance, the System.Web.UI.Page object is replaced by the SPUserCodePage object.

The question for me is why is the ScriptManager not available? Why not allow the use of the UpdatePanel in a sandbox?

Wednesday, 26 October 2011

Problems Adding Rest Service Reference in Visual Studio

If you ever have to add a Service Reference for the SharePoint List WCF Service to a project in Visual Studio 2010​ you may encounter a "Bad Request" or "There was an error downloading ..." type message even though you can view the results of the same service through a browser.

The way around this is very simple and resolves the problem, however, in my mind, this should only really be done on development machines to get around this issue and not rolled out across a Live installation. What you need to do is go to IIS and change the authentication methods for the _VTI_BIN folder to disable Anonymous access. That's it. You can then successfully add the service reference.

Tuesday, 18 October 2011

Custom Workflow Actions in SharePoint 2010

On a recent SharePoint 2010 project I had the opportunity to look at creating custom Workflow​ Actions which is a way to extend the actions already available in SharePoint Designer Workflows.
If I'm honest, the foray was both informative and slightly arduous but perhaps due mostly to my own inability to type properly and my own lack of understanding. Let's start by having a look at why we decided to look down this path.

Why a Custom Workflow Action?

The project in question required a handful of workflows to be developed, all of which were prepared and written using SharePoint Designer. The problem was highlighted early on that we needed to port the be able to package the workflows up to deliver them across multiple platforms during the development life-cycle.

For 2 of the workflows, this didn't pose a problem since they were Reusable Workflows which lend themselves to just this kind of functionality. The 2 workflow, however, was a List-based workflow and as such it was not able to be exported as a WSP. The reason the workflow was a List-based workflow was due to the columns necessary to facilitate the workflow actions - Approval Status being the culprit in this scenario. As it turns out, the "Approval Status" column is not visible for anything other than a List-based workflow.

To allow the workflow to be packaged up meant it had to be a Reusable Workflow, or we had to provide a work-around. After several attempts to package the workflow up (using this method http://ikarstein.wordpress.com/2011/02/10/walkthrough-how-to-move-or-copy-a-sharepoint-designer-2010-list-workflow-to-another-list-on-the-same-site-or-another-site/ was a way to export a List-based workflow using the "Export to Visio" and "Import from Visio" options which did work but didn't provide the hands-off approach we wanted) we decided to try writing a custom Workflow Action to perform the steps we required.

Nuts and Bolts

As it turns out, creating a custom Workflow Action is pretty straight-forward. Create a class, create a publicly declared static method in the class, and away you go. The first parameter must be a context object - we were deploying as a User Code Solution so this was of type SPUserCodeWorkflowContext.

If you're action doesn't need any parameters, do your coding stuff and then move on to the feature XML.

One note here - any typos or spelling mistakes mean that your workflow will not run. I battled for a long time to debug my workflow with only frustration as my reward. I eventually searched the SharePoint logs and found that I had mis-named a parameter so my workflow was never being run. Once I had fixed that, I was away after I had attached to the SharePoint User Code process.
Here's a couple of walk-throughs I found: http://msdn.microsoft.com/en-us/library/gg615449.aspx and http://msdn.microsoft.com/en-us/library/ff798499.aspx. What I would say is that the first article is more accurate. The second one makes no mention of the fact that the method you implement for your action should be a static method - even the example code doesn't show this, so beware.

End-to-end, the final solution (which wasn't overly complicated) took about a day, and at the end I had a fully working custom workflow action which I could use in my workflows. Looking back, it was actually quite painless and easy and once you know where to look (i.e. SharePoint logs, debugging etc) it was fairly rapid.

The Fairytale Ending(?)

Unfortunately, there is no happy ending to this story. I went through a day of trauma and frustration and came out the other side having happily implemented my custom workflow action into a reusable workflow. I saved the workflow through SharePoint Designer to a WSP and thought things were making sense.

I then moved the workflow to another site collection and installed the WSP and that's where the story currently ends. It didn't work. Well.....I say that it didn't work, but I don't really know if I'm honest. The only definition I have to say it didn't work is the fact that the workflow I had created did not appear anywhere so I was unable to use it. No doubt I will post further about this once I've figured out what went wrong here.

Final Thoughts

Looking back at the reasons behind our decision to use a workflow it was mostly dictated by the approach to the required functionality we had already started: namely the other 2 reusable workflows. Keeping to the same model for the third workflow made sense as it followed the same technology instead of departing in a different direction and introducing custom code instead of manully created workflow (i.e. event receivers).

As it turned out, writing a custom workflow action still meant code in order to achieve the portability we wanted so at that point, perhaps, it would have been better to write an event receiver. The influence to stick with workflow came from the technology angle - keeping to the same "hymn sheet" as it were. Yes, it was custom code, but at least it was still workflow.

Fortunately, in this scenario we did have a fallback position to backup the site and restore it, so the time invested was as much for research into this area, which, if I'm honest, was time well spent.

Monday, 12 September 2011

Text Links vs Image Links (SEO)

A slight departure from the normal SharePoint articles I normally write, so from a completely HTML design point of view, here's an interesting question that I've asked myself several times and only answered through my own experience and through quite a few assumptions.
If you have an image displaying text, how does that compare in terms of SEO (and by SEO I'm not referring to SharePoint search ranking here) against using the actual text itself in a link. To give an example, you may display a link using HTML markup like this:

<a href="/mylink/"><img src="thisisalink.jpg" alt="this is a link"/></a>

or like this:

<a href="/mylink/">this is a link</a>

Whichever way you decide, which one ranks better? 

It seems there is no definitive answer, but there are quite a debates about the whole subject. I read an article recently that helps to clarify: http://www.kingrosales.com/2009/04/seo-debate-text-links-vs-image-based-links/ but even this makes some assumptions. Having said that, in my experience, I have always used text and I think on the logic provided in the article, I feel as though that's probably the right way to go.

Friday, 2 September 2011

Finding Feature IDs

​If you're anything like me, sometimes you need to find out what the ID of a SharePoint feature is and it can be something of a trial to locate the exact ID, especially if there's no handy SharePoint Server to remote onto and then go and search the FEATURES directory. So, a much easier way to get the ID of a feature is to use the Developer Toolbar (if you're using IE). Turn on the developer toolbar and select the Activate button of the feature you're interested in using the element selector. The button is enclosed in a DIV which has an ID attribute as follows:

ietoolbar_featuresexample.jpg
As you can see from the image, the ID attribute of the DIV is a GUID, and this GUID is the Feature ID. Simple.