Tuesday, March 25, 2014

SharePoint: Adding hyperlinks to document libraries

Sometimes you have external content that you would like to make available from your document library without uploading a file. Examples include documents in other SharePoint sites or libraries, and even links to other web pages including SharePoint pages and external web sites.

Turns out SharePoint already has this built-in, just well hidden. There is a built-in Content Type called "Link to a Document". Just add this to your library and then just click the "New" dropdown and select "Link to a Document"! It will simply ask you for a document name and url. You can supply a URL to anything that starts with "http://", including both SharePoint documents and external web pages. It does not support a link to a network share such as "\\myfileserver\folder1\somedoc.doc".
  1. Display your library (Example: Shared Documents)
  2. Click Settings and Library Settings
  3. Click Advanced Settings
  4. Check "Allow management of content types" and then OK
  5. In the Settings page scroll down to Content Types and click "Add from existing site content types"
  6. Select "Link to a Document", click Add and then Click OK
  7. Go back to your library and click the New dropdown and select "Link to a Document"
  8. Enter a display name (Document Name) and the URL (must start with http://) and click OK
So how does it work? The Content Type has a template that is an ASPX page that contains a server side control named SharePoint:UrlRedirector. When this page is rendered it simply redirects to the address listed in the items URL property. Also experiment with adding these built-in content types to your library:
  • Basic Page
  • Web Part Page
  • Dublin Core Columns (Do a web or wikipedia.com search for "Dublin Core")
  • Picture
You can also add customized folders to the New dropdown. See here. Need to add custom columns / meta data to any of the above? Just create a new Content Type based on one of the above and add it to your library. See here.

Note:
First Enabled "SharePoint Server Publishing Infrastructure" features under in Site Action --> Site Settings --> Site Collection Administration

Wednesday, March 19, 2014

Intermittent InfoPath Forms Services Error

No errors were logged in Event Logs. We have identified the root cause of the problem to be connectivity with SharePoint User Profile web service as we are using it to populate the properties of logged-in user at form-load.
On the other hand, this seems to be an issue only in a specific environment. So, we wanted to check the settings on the environment.
Resolution Steps:
1) Made sure all the data connection files have the environment specific List GUIDs, URLs and so on
2) Made sure all the settings related to InfoPath Forms Services under Central Admin are proper: Enable web service proxy, Enable cross-data connections, Disable Anonymous access
3) Made sure all the relevant user profiles are properly imported under SSP
4) Made sure that the authentication Loopbackcheck registry entry is disabled on the WFE server
Disable the authentication loopback check
Re-enable the behavior that exists in Windows Server 2003 by setting the DisableLoopbackCheck registry entry in the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa registry subkey to 1. To set the DisableLoopbackCheck registry entry to 1, follow these steps on the client computer:
  1. Click Start, click Run, type regedit, and then click OK.
  2. Locate and then click the following registry subkey: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
  3. Right-click Lsa, point to New, and then click DWORD Value.
  4. Type DisableLoopbackCheck, and then press ENTER.
  5. Right-click DisableLoopbackCheck, and then click Modify.
  6. In the Value data box, type 1, and then click OK.
  7. Exit Registry Editor.
  8. Restart the computer.
5) Made sure the alternate access mappings or managed paths are not breaking the web service calls in the interim
None worked. Finally, we have added a host file entry on the WFE server (we have only one WFE in our case) to point to its own IP, did a IIS reset  and it worked.
I have actually found this resolution on one of the blogs:
If the WFE servers are load-balanced, we need to add a host file entry on WFE pointing to its own IP on each of WFE. This is to deal with a known issue with InfoPath browser forms; all browser form calls to SharePoint web services will be made to the current machine that invoked the form.

-----------------------------------------------------
I recently came across this baby quite frequently when developing a form that used the user profile web service to automatically populate a ‘contact information’ section. For step by step instructions on how to achieve this, check out Itay Shakury’s terrific blog here: http://blogs.microsoft.co.il/blogs/itaysk/archive/2007/04/05/InfoPath-_2D00_-Get-the-current-user-without-writing-code.aspx
Anyway, despite this solution working for me on a single server environment, when I migrated it to a multi-server farm (NTLM) it intermittently stopped working. Although it didn’t seem necessary as the web service was a local resource rather than an external one; I looked into UDC files and Administrator approved form publishing. The authentication token was obviously being lost between serving the form and making the request to the web service because I was seeing these kinds of errors in the logs:
04/15/2008 17:01:05.39 w3wp.exe Forms Server Forms Services Runtime – Data C 82fy Warning The following query failed: GetUserProfileByName (User: ***, Form Name: ***, IP: , Request: *** Form ID: urn:schemas-microsoft-com:office:infopath:***, Type: DataAdapterException, Exception Message: The remote server returned an error: (401) Unauthorized. The remote server returned an error: (401) Unauthorized.)
After some digging through the server logs it became clear that the web service request was being sent via the load balancing server which was assigning it to 1 of the 3 MOSS servers in the farm. If the server that was serving the form got the request, the form worked perfectly and displayed the user details but if another server received the request then the error above was displayed because the server had no idea where the original request was from.
So after playing around with the web service data connection for a while- trying to use localhost or the server name instead of the host header (which Forms Services doesn’t like), I finally added a simple entry to all 3 server hosts files and mapped the host header name to 127.0.0.1. This ensured that once a server was assigned a request by the LB, any secondary requests to a farm resource would then be served by the same server (localhost) instead of being directed back to the LB.