Post

Jun 05
Content Organizer not working due to Managed Metadata fields

​Configuring recently Records Center with custom Content Organizer routing, we face a few issues that lead to a single issue:

  • configuring a custom Content Organizer rule with our content types lead an error:

Microsoft.SharePoint.SPException: Failed to get value of the "Tags" column from the "Managed Metadata" field type control. See details in log. Exception message: Invalid field name. {9f1f354f-8324-44c0-a842-f1bd87a97bf9} http://recordscenter .
    at Microsoft.SharePoint.WebControls.BaseFieldControl.OnLoad(EventArgs e)
    at Microsoft.SharePoint.Taxonomy.TaxonomyFieldControl.OnLoad(EventArgs e)

  • Document send usign Send To action always has Document content type, though metadata is there, but not correct content type and no version history. Following errors are in ULS logs:

Routing Engine: Value could not be set for Field Type:TaxonomyFieldType Title:Type: Value cannot be null.  Parameter name: g.

and

Some but not all taxonomy values were found, this can lead to the catch all being incorrect.  Use TaxonomyField.SetFieldValue to update taxonomy values.  Stack trace is   
    at Microsoft.SharePoint.Taxonomy.TaxonomyItemEventReceiver.SyncHiddenField(SPItemEventProperties props, Boolean fieldAdding)   

The issue looked very strange, as fields were working correctly for both UI and custom code.

After deep investigation and comparing with a field created using UI, we find out that our Content Type is missing hidden Note field that comes together with MM field and is specified in the property Text field. In test1 Content Type you can see that there are 2 Tags fields - MM field test and Note field test_0. But for our document content type there is only Tags field.

MM_no_hidden_note_field.png

Though Tags_0 exists in Site Fields:

fields_there.png

Adding *_0 fields to our content types solved both issues (you can do it using PowerShell using similar code - http://sharepoint.stackexchange.com/questions/15692/adding-a-site-column-and-add-it-to-a-content-type-from-powershell-issuec). Please be careful when provisioning MM fields, as incorrect provisioning may result in unexpected errors in different places. There is a good blog post how to provision such fields - http://www.sharepointconfig.com/2011/03/the-complete-guide-to-provisioning-sharepoint-2010-managed-metadata-fields/.

Jan 26
Failed to create receiver object from assembly...

​Recently we have faced an issue with deployment to production server. One of our features stubbornly declined to activate due to event receiver creation failiture. After googling we tried almost all suggested solutions: restarted timer service on all servers, restarted of all servers, incremented assembly version, moved code to another feature, ... But our issue was much simplier:

Feature receiver code was dependent on a second helper assembly - Feature.Common.dll which was somehow removed from servers GAC. Thus creation of receiver crashed with a totally unhelpful message that made it really hard to find out the root cause of the issue. Error message is shown below:

PS C:Windows\system32> Enable-SPFeature -identity Feature.DataModel_SiteFeature -URL http://siteurl
Enable-SPFeature : Failed to create receiver object from assembly "Feature.DataModel, Version=1.0.0.0, culture=neutral, PublicKeyToken=key", class "Feature.DataModel.Features.SiteFeature.SiteFeatureEventReceiver" for feature "Feature.DataModel_SiteFeature"
(ID: 245abdd2-6907-4c12-9878-eb2a32ff9ab7).: System.ArgumentNullException: Value cannot be null.
parameter name: type 
	at System.Activator.CreateInstance(Type type, Boolean nonPublic)
	at System.Activator.CreateInstance(Type type)
	at Microsoft.SharePoint.Administration.SPFeatureDefinition.get_Receiverobject()
At 1ine:1 char l
Enable-SPFeature -identity "Feature.DataModel_SiteFeature" -URL http://siteurl
	+ CategoryInfo : InvalidData: (Microsoft.Share...etEnableFeature:SPCmdletEnableFeature) [Enable-SPFeature],
	InvalidOperationException
	+ FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SPCmdletEnableFeature

So please navigate to C:\Windows\Microsoft.NET\assembly\GAC_MSIL (new location to GAC in .net 4) and check that all assemblies you are using are there. :)

Jan 22
Invoke previous delegate control

​Sometimes when developing a delegate control that overrides some OOB functionality it's required to execute the previous (overridden) functionality in some cases. The most common case is a User Profile redirect control (ProfileRedirection delegate control) that is a Farm scoped and thus is applied to the whole farm. Recently we developed a highly customized public site collection that had a special profile page for each user. But for other site collections we wanted to have OOB My Site functionality. Thus we had to investigate how delegate controls are working internally and how to get a previous one.

There is no special method in SharePoint API that could help us. Thus we need to go through all Farm level feature definitions and check their element definitions to be of Control type and Id to be ProfileRedirection. Each suitable we save to a list and the order by Sequence to get a previous one. Then we need to create this control. Actually, all element definitions are special internal classes and our Control element type is a SPControlElement and it already has a method to build itself - BuildCustomControl. Thus we only need to call it using Reflection. Also, FeatureXmlControlElement is a custom class that wraps around xml definition to help with sorting by Sequence.

private void UsePreviousControl()
{
    var controls = new List<FeatureXmlControlElement>();

    // iterate through all SP 2013 Farm Level features
    var features = SPFarm.Local.GetFeatureDefinitionsByVersion(15);
    
    foreach (var fd in features)
    {
        try
        {
            if (fd.Scope == SPFeatureScope.Farm)
	    {
	        var elementDefinitions = fd.GetElementDefinitions(SPContext.Current.Web.UICulture);

		// iterate through all feature definition elements to find Control elements with ID  ProfileRedirection
		foreach (var ed in elementDefinitions)
		{
		    if (ed.XmlDefinition.Name == "Control" && ed.Id == "ProfileRedirection")
		    {
		        var ce = new FeatureXmlControlElement(elementDefinition.XmlDefinition, fd, ed);
			controls.Add(ce);
		    }
		}

	    }
        }
	catch (SPException ex)
	{
	    continue;
	}
    }

    // if more than 1 ProfileRedirection delegate are registered
    if (controls.Count > 1)
    {
	// order by sequence to have current on the top
	controls = controls.OrderBy(c => c.Sequence).ToList();

	// get previous one
	var c = controls[1];

	// run not public method to build control from control manifest
	var methodInfo = c.Element.GetType().GetMethod("BuildCustomControl");
	var previousDelegateControl = methodInfo.Invoke(c.Element, new object[] {this});

	// add control and fire init event
        Controls.Add((Control) previousDelegateControl);
        // call to init the control with appropriate parameters
        ((IFormDelegateControlSource) previousDelegateControl).OnFormInit(_objectOfInterest);
    }
}


Oct 31
Deep dive into OneDrive for Business in team coloboration & document management

There are a few questions that come to mind when considering OneDrive for Business as a part of real world Document Management system:

Question #1: how to organize work between the personal OneDrive library and document sites? For example, an employee wants to have document locally to work on it later and then publish changes to original. Or create document, work on it using OneDrive on different devices and then he publish it to corporate DMS.

(DMS -> OneDrive for Business) Unfortunately, there is no Send To My OneDrive button in SharePoint 2013. OOB library Send To action can't be customized to send to OneDrive due to 2 reasons:

  1. it normally works only within one Web Application, but My Site setup guides to have it as a separate Web Application, that definitely can work but only with help of installed Office and ActiveX (you can find more here)
  2. it requires a dynamic path to user's personal site

Thus it's required to build a custom action that will copy a document to user's OneDrive folder. That is not a trivial task as it seems from a first look - if both documents are editable and there is a chance that they will require merging. Though it's possible to checkout original document to the user and reuse manage copies functionality, but it require complex coding and testing.

(OneDrive for Business -> DMS) We can configure (per each user OneDrive library) library Send To action to send documents to a single entry Drop Off library to route document using Content Organizer. But the key issue here is document metadata to identify the route. At users OneDrive library user doesn't have to care about a content type to assign to a newly created document. All documents are just Documents. Content type and meta information come at place only when user decides to publish document to DMS. Thus in OOB way he should change the content type, fill in meta information and use Send To action. 

Or we have to build own action to simplify the process.

Question #2: what's about security? 

Imagine a situation when your device is lost, all files are available to a person who found the device and cracked it if you have no protection/remote clean up. This can be really critical for sensitive corporate data.

Question #3: what's about large libraries?

(PC) As OneDrive for Business syncs the whole library it doesn't make sense to use it with large libraries as all documents will be downloaded to your device. Downloading a 1 gb library just for 5-10 documents you're working at the moment is useless. Thus you have to plan you system accordingly.

(Android using Microsoft Office Mobile) It's possible to download and edit only the document you need. You can quickly review and leave comments, sync back to cloud and others can continue working on you comments.

Question #4: what's about file meta information?

When you add a document to OneDrive for Business folder it's automatically synced to SharePoint. You get no dialogs for required information, though it's defined by a default content type. In case no versioning, you'll get you file there without meta information. Otherwise you'll get a draft version checked out to you that will require additional meta information in SharePoint to check in/publish. Thus a document will not be searchable due to the lack of corporate taxonomy, or not available to others.

In my opinion it make sense to strictly use versioning with OneDrive enabled libraries to prevent sharing documents without required metadata and have a track of versions in case something is synced badly.

Question #5: what's about multiple document libraries/sites sync?

You can only sync by a library. Thus you will have to sync as many times as many libraries you have. That's why it's not possible to sync a site.

Question #6: what's about document sets?

Document sets are treated as folders, but when you create a folder in synced library with document sets, it becomes a folder in SharePoint. So you have to create document sets only in SharePoint.

Question #7: what's about settings synchronization between devices?

There is no synchronization between devices. Each device has own list of synced libraries and multiple accounts can be used.

Question #8: does it work with all types of libraries?

No. For example, Picture and Assets libraries are not supported (more info here). Probably some others will also not work.

Conclusion

Let's summarize, OneDrive for Business is built for 2 goals:

  1. Provide a single place to store employee's documents (OneDrive library in personal site).
  2. Provide an easy way to collaborate on multiple documents in a single place within a project/team.
Oct 29
OneDrive for Business overview

​Recently I've started working with OneDrive for Business to check its functionality and improve process of collaboration on our Apps documents (specifications, overviews, instructions, marketing materials, versions, logos, images). Thus I've created a site collection in our SharePoint Online, added a few libraries & lists, enable versioning and describe how to use it to my team. I've installed OneDrive for Business to my working machine in order to have always the latest version of files locally. 

You can download OneDrive for Business here. Unfortunately, there is no version for Mac yet.

OneDrive for Business allows 2 types of synchronization:

spsitepro_30_types.png

Personal OneDrive for Business

Each user's personal site has a document library called Documents that is designed to be used with OneDrive for Business. There is a special link in the Suite Bar - OneDrive that point to the library (https://yourname-my.sharepoint.com/personal/username_and_domain/Documents/Forms/All.aspx). By default, documents in the library are available only for the owner and Shared with Everyone folder provides a place for documents that can be accessed by other people within the organization.

spsitepro_30_one_drive_document_library.png

Sync button starts OneDrive client (if installed) to sync with local PC. It requires authorization:

spsitepro_30_authentication.png

spsitepro_30_synced.png

It make sense to point that it's not possible to change the folder name during this process and if you have multiple personal documents libraries synchronized they will have names - OneDrive for Business 1, OneDrive for Business 2, etc.

Document libraries syncronization

Further it's possible to sync any document library. To do it - just right click on OneDrive icon -> Sync a new library -> paste library url to the opened window -> click Sync Now button or use sync button on the document library page:

spsitepro_30_sync_a_new_library.png

spsitepro_30_synced_lib.png

As you can see library is synced under SharePoint folder and have a name [Site Name] - [Library Name].

Working with Office

spsitepro_30_save_word.png"Save this document and refresh it with updates made by other authors."

Office 2013 provides ablity to simultaneously edit document from OneDrive folder, it works the same as before: you click save and your changes are uploaded to SharePoint, other authors changes are downloaded to your document.

Office 2010 doesn't provide such an ability. When you open a file from OneDrive folder it is opened as a local file. You can click save several times but it will only make changes to local file. When you close the app, the file will be synced with SharePoint. Thus if someone has also changed the file in SharePoint it will become unsynced and will require repair for a library.

Usage expirience

During my usage I found 2 issues that bothered me:

  • OneDrive for Business needs to close because of a hardware or configuration problem

First time I intalled OneDrive for Business to Windows 2012 R2 I had this error. I looked at different forums and it seems to be a common issue when installing/updating OneDrive for Business. I had to uninstall the version intalled with Office 2013 and intall the latest version. It started working, but later after updates the app failed to start with the same problem and had to be closed. Again after a few updates/restarts it resumed working correctly.

spsitepro_30_one_drive_error.png

  • Documents sync errors

spsitepro_30_sync_error_credentials.png

spsitepro_30_sync_error.png

spsitepro_30_repair_2.pngspsitepro_30_repair_1.png

spsitepro_30_repair_3.png

spsitepro_30_repair_4.png

Sep 09
Using DefaultAssetImageLocation propery of RichImageField in Page Layout

​RichImageField provides a very useful property called DefaultAssetImageLocation:

"Gets or sets the URL to a location in this site collection that is added to the top of the "Look In" section of the Asset Picker dialog box when selecting an image source URL."

Simply put, it allows specifying a library that will be opened once Browse... button is clicked. That is really helpful to have a centralized image storage library or use a separate library per site as it prevents chaos that users can create by uploading images to different libraries and then forgetting what site the images was uploaded to.

Accordingly to MS guideline about it's value:

This URL should begin with either "~SiteCollection/" or "~Site/" followed by the relative URL to the desired Windows SharePoint Services location. If this URL refers to a valid Windows SharePoint Services location that the authoring user has access to, it appears in the "Look In" section on the left of the Asset Picker dialog box when the dialog box is launched to select an image source URL.

 I tried to use values starting from both ~Site/ and ~SiteCollection/, but none of them worked for me. But when I specified full relative path - it worked. Then I remembered about SPUrl token, that works only for SharePoint Server, but it's my case. So the finally working value was:

 <PublishingWebControls:RichImageField FieldName="PublishingRollupImage" 
					runat="server" 
					DefaultAssetImageLocation="<% $SPUrl:~site/Lists/SiteAssets/ %>"
					/>
Sep 09
Image Renditions in RichImageField

There is a new cool feature​ Image Renditions in SharePoint 2013. It's blogged a lot about it and you can find more details, for example, here. Selecting image for Image Field in a page layout it's possible to select an Image Rendition, that will be used for the image. It's really useful, as you don't need to pick the size manually and can use any size image.

spsitepro_36_select_image_rendition.png

But what if you have a strongly defined layout? Is it possible to predefine the Image Rendition size, so user don't need to select a proper one?

And the answer is Yes. There is RenditionId property in RichImageField, that require to specify the Id of the rendition (you can easily find it using Site Settings -> Image Renditions -> ID column).

spsitepro_36_selected_rendition.png

But what if you're not customizing the SharePoint, but developing a solution and don't know the Rendition Id, as it may differ depending on environment? You can easily customize creating a new Image Field Control that accepts RenditionName property and get Rendition Id based on it.

public class PublishingImageField : RichImageField
{
    public string RenditionName { get; set; }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        var renditionId =  GetRenditionId();
        if (renditionId != null)
        {
            RenditionId = renditionId;
        }
    }

    private int GetRenditionId()
    {
        ImageRenditionCollection imageRenditions = SiteImageRenditions.GetRenditions(Web.Site);
        ImageRendition rendition = imageRenditions.FirstOrDefault(ir => ir.Name.Equals(RenditionName));

        return rendition == null ? -1 : rendition.Id;
    }
}

And what is really cool - user woun't break the layout with a large image by mistake.

Sep 03
Default Image for Publishing RichImageField

​Recently I worked on a page layout that had an image and if there is no image, default one should be displayed. Unfortunately, using OOB Image Field it's not possible to set a default image. So after short investigation of the field, I've created my on my own version, overriding it's RenderFieldForDisplay method:

public class PublishingImageField : RichImageField
{
    public string DefaultImageUrl { get; set; }

    protected override void RenderFieldForDisplay(HtmlTextWriter output)
    {
        if (ControlMode == SPControlMode.Display && Item[FieldName] == null)
        {
            output.Write("<img src='{0}' />", DefaultImageUrl);
        }
        else
        {
            base.RenderFieldForDisplay(output);
        }
          
    }
}

Hope, it will be useful!

Aug 28
Note field - This field can have no more than 255 characters

Creating today a Pages library with custom fields, I found a strange issue during editing page properties from a page layout: This field can have no more than 255 characters.

spsitepro_35_This_field_can_have_no_more_than_255_characters.png

I used Note field and it always worked well for large multiline text from my experience:

<SharePoint:NoteField FieldName="myFieldName" runat="server"/>

After few attempts to make it work with MaxLength property and different field types, I found a great post that describes my issue. And all I need to do is to set UnlimitedLengthInDocumentLibrary property of my field to TRUE:

  
  <Field ID="myGUID"
           Name="myField"
           SourceID="http://schemas.microsoft.com/sharepoint/v3"
           Group="myGroup"
           DisplayName="myField"
           Type="Note"
           UnlimitedLengthInDocumentLibrary="TRUE"
           Required="FALSE"
           RichText="FALSE">
   </Field>

This behaviour is only limited to document libraries (which my Pages library is) and it seems the first time I need additional multiline field for a page layout:)

Aug 11
Postman for Chrome - the best way to work with REST & web services

​Testing REST APIs not always easy - need to configure browser to display results correctly, hard to make POST requests and etc... That usually result to some kind of test application that require development and support. But there is a great alternative. Please welcome - Postman​, an add-on​ for Google Chrome.
spsitepro_32_postman.png

Its realy easy to make GET request for SharePoint REST API. All you need to do is to login by the user you want in Chrome. Then you can make requests.
spsitepro_32_getlists.png

If you'd like to see response in JSON - no problem, just specify Header "Accept" with value "application/json; odata=verbose":​
spsitepro_32_getlists_json.png

Nothing complicated for POST request - all that's required is to specify X-RequestDigestYou can get it by making POST request to /_api/contextinfo:

spsitepro_32_get_digest.png

Knowing a correct X-RequestDigest we can make POST call to API specifying it in the Header:

spsitepro_32_make_post.png 

Also it's helpful to Add to collection ​frequently used request. Thus you can template all you API and check whether it works in few clicks. Also it's convenient to have in collections​​​ requests like /_api/contextinfo that can be used with any POST request.

Hope it will help you the same as me!

1 - 10Next
Web Part Error: Activation of solutions with sandboxed code has been disabled. Correlation ID: 590f249e-b07a-4000-89df-13348c3cb171.