Monday, 28 October 2013

SharePoint 2013: HTTP 500 error when sending an email from a SharePoint Designer workflow

I recently encountered this problem for a client and the cause had me stumped. I did all the basic checking
1. Check the UPS was up to date
2. Made sure that the Workflow Manager was correctly installed
3. Made sure that the firewall was not blocking the WF manager port (12290 or 12291).

Still nothing.

The problem (it seems) comes from Document Library 'Advance Settings'; the document library had 'require checkout' set. I did not think anything of it, but once I removed it the workflow executed as expected.

Its a strange behaviour but at least its something to look at when trying to resolve the issue.

Thursday, 24 October 2013

SharePoint 2013: Can I add a document to a generic list?

The short answer is yes. In the advanced settings for a list, there is an 'enable attachments' setting.

Wednesday, 23 October 2013

SharePoint 2013: the given key was not present in the dictionary

I have been pulling my hair out over the last few days to resolve this issue.

I tried some of the suggestions:
1. make sure that the User Profile Service is up to date and make sure that a full synchronization has run.
2. make sure that the initiator accounts have access to Worflow History
3. make sure that the Doc library does not require checkout (or that your code handles it)

However the real solution to my problem came from SharePoint permissions. I had overridden the base permissions the on the Workflow Tasks list and the lists hosting the workflows and it seems that this caused the problem.

Once I reverted to the parents' permissions, the error disappeared.

The next problem was allowing users to approve their tasks. By default, users did not have 'approve' permissions on the list, so I needed to add a little code to my 'Tasks' web part to solve the problem; I gave the current user 'contribute' permissions on the list item so it could be moderated.

SPSecurity.RunWithElevatedPrivileges(() =>
using (SPWeb inner = new SPSite(dr["EncodedAbsUrl"].ToString()).OpenWeb())
string relativeUrl = dr["FileRef"].ToString().Substring(dr["FileRef"].ToString().IndexOf("#") + 1);
relativeUrl = relativeUrl.Substring(0, relativeUrl.LastIndexOf("/"));

SPList list = inner.GetList(dr["EncodedAbsUrl"] + relativeUrl);
SPListItem item = list.GetItemById(int.Parse(dr["ID"].ToString()));
SPRoleDefinition RoleDefinition = web.RoleDefinitions.GetByType(SPRoleType.Contributor);

SPUser user = SPContext.Current.Web.CurrentUser;

SPRoleAssignment RoleAssignment = new SPRoleAssignment(user.LoginName, user.Email, user.Name, "notes");

inner.AllowUnsafeUpdates = true;
if (!item.HasUniqueRoleAssignments)
inner.AllowUnsafeUpdates = false;


Thursday, 17 October 2013

SharePoint 2013: How do I set a custom page to be a default page for a site?

The solution is very simple; navigate to the page in SharePoint Designer 2013, right click and select 'Set as Home Page'.

Tuesday, 15 October 2013

SharePoint 2013: How can I tell if my page is in edit mode?

The solution lies in the object model: Microsoft.SharePoint.SPContext.Current.FormContext.FormMode
It returns a SPControlMode enumeration.

An example usage of the code is as follows:

if (Microsoft.SharePoint.SPContext.Current.FormContext.FormMode == SPControlMode.Display)
  // Do display stuff
else if ( Microsoft.SharePoint.SPContext.Current.FormContext.FormMode = SPControlMode.Edit )
  // Do edit stuff

SharePoint 2013: How do I access the Web Part Maintenance page?

I was working on a visual web part that was causing a lot of problems with the page hosting it. I need to remove it, but the 'Edit Page' was not working. The solution: navigate to the Web Part Maintenance page and remove it from there.

How do you get there: add ?contents=1 to the end of your page url.

For example, if my page is http://hostheader/pages/default.aspx, then the Web Part Maintenance page for that page is  http://hostheader/pages/default.aspx?contents=1

Tuesday, 8 October 2013

SharePoint 2013: Where is my Workflow History list?

I was trying to create a workflow, but the default 'Workflow History' list was nowhere to be see.
It appears that it was hidden, so I used PowerShell to resolve the problem:

$web = Get-SPWeb "http://myweb"
$list = $web.Lists["Workflow History"]
$list.Hidden = $false

Monday, 7 October 2013

Sharepoint 2013: IE Compatibility issues (it renders really badly)

I was trying to get my masterpage to render properly in IE (aka mission impossible) and, after a stack of trying, came up with the following changes that fixed my problems:

1. In the masterpage, add
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>

This will cause Sharepoint to use the latest version of IE installed on the host machine. I tried forcing the version (IE=7), but that did not seem to give the required results.

2. In the main CSS file, add

    font-size: 100%;



My CSS was shocking; the font sizes were terrible and the alignment was like my kids bedrooms - very messy. Setting the white-space and font-size resolved my issues.

Conditional CSS

Anyone who has tried to get CSS working with IE will know about the 'nuances' of the browser.

Thankfully, CSS gives us some conditional formatting methods to deal with these scenarios; you can apply class explicitly based on the browser type or version.

<!--[if IE]>
<style type="text/css">
    @font-face {
    font-family: "Arial";
    src: url("../new/over.ttf");
    src: local("Over the Rainbow"), url("../new/over.ttf");

See here for more information

Sharepoint 2013: Override display for App web part

My current project requires some custom CSS with the minimum amount of customisation. Instead of writing a stack of custom controls, we can 'intercept' the apps as they are being rendered and change their CSS at runtime.

The following is a sample of how this might look (I called my file blah.js):

(function () {
    var overrideContext = {};
    overrideContext.Templates = {};
    overrideContext.Templates.Header = "<div class='myheader'>";
    overrideContext.Templates.Footer = "</div>"
    overrideContext.Templates.Item = customItem;

function customItem(ctx) {

    return '<div class="myheadercss"><h1>'+ctx.CurrentItem.Title+'</h1></div>'+
           '<div class="mycontentcss"><img class="myimagecss" src="'+ctx.CurrentItem.Image0+'" alt="Image" />'+
           '<h2>'+ctx.CurrentItem.Header0+'</h2><p class="mytextcss">'+ctx.CurrentItem.Content1+' <a href="'+ctx.CurrentItem.Link0+'" class="mylinkcss">Read More</a></p></div>'

I placed my .js file in masterpage/scripts, so in the 'Miscellaneous' section of the webpart properties, I can put a link to my file: