Wednesday, August 10, 2016

SharePoint ignores MIMEtypes mapping unless on web server level

Earlier I reported that our business users request user-intuitive handling of non-Microsoft and non-standard file-formats that are administrated within document libraries. Enabling such in SharePoint on premise consists of 2 steps (See ‘SharePoint: Browser File Handling Deep Dive’ for an authoritative reference):
  1. Add in IIS Manager a MIMEtype mapping for the involved file-extension(s)
  2. Add the MIMEtype(s) to the AllowedInlineDownloadedMimeTypes configuration of the SharePoint webapplication(s)
These server-level configuration steps are not possible in Office 365 / SharePoint Online. I ensured that we can deliver our business users sustainable custom filetype handling on migrating to cloud deployment, via the utilization of Office 365 FileHandler Add-Ins concept.
Wrt MIMEtype mappings, IIS allows multiple levels on which you can configure these:
  • Web server
  • Site
  • Application
  • Physical and virtual directories
  • File (URL)
Note that not all these levels are applicable to SharePoint as virtual webserver.
The web server level is most easy to execute, but drawback is that it requires an IISReset to become active. And that means a temporary down of any SharePoint webapplication hosted on the WFE. Therefore I instructed our operations to add the MIMEtype mappings on the Site level. To be disappointed afterwards: on download of the files from SharePoint, the content-type was still ‘application/octet-stream’ aka the “unknown type”, instead of the configured MIMEtype e.g. ‘application/vnd.spotfire.dxp’. Only when we add the MIMEtype to web server level, SharePoint returns in the file download response the configured MIMEtype.
I conducted an internet search on whether this is intentional, or at least known SharePoint / MIMEtype (mis)behavior. Only found some discussion posts ([1], [2]) inquiring about the effect we noticed (on SharePoint 2010 and SharePoint 2013 Server farms).

Monday, August 1, 2016

Augment the Org Chart with additional information

The SharePoint Organization Browser (Org Chart) is a convenient out-of-the-box functionality to display the organogram on user basis. The information of this typically comes from the HR system, and is propagated to SharePoint User Profiles. In our company we work with a lot of externals. All of them are also administrated in our HR system, and thus also provisioned to the User Profiles. Which is what we want. Only thing that our managers miss, is that in the Org Chart no visual distinction is made between internal and external subordinates. We have this information available in the User Profile in a custom property. But the Org Chart only displays the full names of the colleagues visualized in the organogram chart.
In the ‘old days’ we simple would have built a custom Org Chart, using server-side code. But in the current times, this is strongly advised against. We have an architecture guiding principle that all application customizations and extensions must be future-proof. Modifying or rebuilding something that a platform delivers out-of-the-box does not qualify for us as future-proof. The platform vendor might replace the current component by a complete different setup in the future, of which we would then miss out. In this particular scenario there is another reason to not replace the out-of-the-box delivered by a custom developed. The Organization Browser webpart is standard included on user profile page Person.aspx. To change that we would need to replace the inclusion of the webpart by an own. Note that for Person.aspx publishing page (= SharePoint content) it is possible to do this, on premise and also online, e.g. via SharePoint Designer. However, what online is not possible is to deploy a server-side webpart. Implication is that the future-proof custom Org Chart must be redeveloped fully from scratch (no reuse / extension possible of the standard Org Chart webpart), either via 100% clientside script, or as (Azure deployable) provider-hosted Add-In.
As said, Person.aspx can be modified in both on prem as online. Better sustainable approach is therefore to extend on the out-of-the-box functionality with the requested customization. Inject a reference to an own JavaScript file, and in that file include a method to extend the displayed names of a colleague’s subordinates with information on whether internal or external. We have this information as user profile property, and this can in clientside context be retrieved via the UserProfile REST service.
Dynamic extend the Organisation Browser rendering with additional User Profile information
enrichOrgChartWithExternalOrg = function() { jQuery("#ReportingHierarchy").find("TR.ms-orgme").next().find("TD.ms-orgname > a").each(function(index) { var anchor = this; var href=jQuery(anchor).attr("href"); var accountName = unescape(href.substr(href.indexOf("accountname=") + "accountname=".length)); jQuery.ajax({ url: _spPageContextInfo.webAbsoluteUrl + "/_api/SP.UserProfiles.PeopleManager/GetUserProfilePropertyFor(accountName=@v,propertyName='ExternalOrganization')?@v='" + accountName + "'", contentType: "application/json;odata=verbose", headers: { "accept": "application/json;odata=verbose" }, success:function(data){ if (data.d.GetUserProfilePropertyFor.length != 0) { var extCompName = data.d.GetUserProfilePropertyFor.substr(0, data.d.GetUserProfilePropertyFor.indexOf(" - ")); var augmentedSubordinateName = jQuery(anchor).html() + " (" + extCompName + ")"; jQuery(anchor).html(augmentedSubordinateName); } } }); }); };
Standard Organisation Browser display extended with additional User Profile information
Note, the above code retrieves the extra user profile property per subordinate in a loop-control, each iteration includes a request-reply to the UserProfile REST service. To reduce the network latency impact from the client to SharePoint and back, one would want to avoid the loop and request all in one http request. The REST protocol supports this via $batch (Get UserProfile Properties with REST API Batching. And SharePoint Online and SharePoint 2016 are a good REST citizens, but SharePoint 2013 on premise is not: $batch is not supported. (Make batch requests with the REST APIs).