I needed to create a link to a document the same way SharePoint does it: using the DispEx client side function. The DispEx function performs all of the magic involved with opening an Office document directly in the appropriate Office app in a nice way, as long as you are using Internet Explorer of course. I believe it also uses ActiveX to do this, but that will be for another ran.. I mean blog post.
Searching for how to create such a link proved worthless. There are a few posts and Q&A’s on Stack Overflow out there, even at least one from one of those soon-to-be-extinct MVP’s – but they all hard coded most of the parameters for the function. It is true that the function has a plethora of parameters, but having them hard coded is not desirable – especially when the parameters are based on user-configurable settings, such as the ‘Force Checkout’ option in a document library.
Below is some code to create the ‘click’ script for the anchor element, gleaned via ILSpy and modified to accept an SPFile parameter. The DispEx function (and dependencies) also require that the anchor element have an HREF attribute set to the server-relative URL of the file. In the case of an SPFile instance, this would be FIle.ServerRelativeURL.
private string GetFileViewScript(SPFile file)
{
string text = SPUtility.MapToControl(SPContext.Current.Web, file.Name, string.Empty);
string text2 = (file.Item.ParentList.DefaultItemOpen == DefaultItemOpen.Browser) ? "1" : "0";
SPFieldLookupValue sPFieldLookupValue = file.Item["CheckedOutUserId"] as SPFieldLookupValue;
string scriptLiteralToEncode = (sPFieldLookupValue == null) ? string.Empty : sPFieldLookupValue.LookupValue;
string text3 = (SPContext.Current.Web.CurrentUser != null) ? SPContext.Current.Web.CurrentUser.ID.ToString(CultureInfo.InvariantCulture) : string.Empty;
string text4 = file.Item.ParentList.ForceCheckout ? "1" : "0";
return string.Format(CultureInfo.InvariantCulture, "return DispEx(this,event,'{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}')", new object[]
{
"TRUE",
"FALSE",
"FALSE",
text,
text2,
text,
string.Empty,
string.Empty,
SPHttpUtility.EcmaScriptStringLiteralEncode(scriptLiteralToEncode),
text3,
text4,
(string)file.Item["IsCheckedoutToLocal"],
(string)file.Item["PermMask"]
});
}
Er. Not sure if my comment happened or it disappeared. Trying again. Sorry if there's a double post.
ReplyDeleteThis is freaking awesome... what do I do with that code? I realize this post is a year old and you'll probably never read this, but I'm so frustrated trying to solve a problem this function is creating, I'm going to try this shot in the dark.
The code above is C# code that would be used within a web part or ASPX page for rendering an anchor (A) or button that opens a SharePoint file. The simplest example I can think of quickly is something like this:
Deletevar myFile = FunctionThatGetsSPFile();
Response.Write("<" +"input type=\"button\" value=\"Open File\" onclick=\"" + GetFileViewScript(myFile) + "\" />");
(Blogger does not like HTML tags in comments)