Mit SharePoint 2010 ist es möglich, Dokumente aus diversen Websites an eine zentrale Website vom Typ „Document Center“ oder „Record Center“ zu versenden, um diese dort zentral bereitzustellen oder zu archivieren.

Die verfügbaren Ziele (Verbindungen) werden pro Web Applikation in der zentralen Administration (unter “General Application Settings”) konfiguriert. Damit der Transfer der Dokumente über Web Applikation-Grenzen hinaus funktionieren kann, werden diese über einen OOTB SahrePoint Webservice (officialfile.asmx) verschickt.

SharePoint Standard-UI für “Send To”-Verbindungen

Ist der Haken bei “Allow manual submission from Send To menu” für eine Verbindung gesetzt, dann kann jedes Dokument in der gewählten Web Applikation über diese Verbindung versendet werden. Dazu ist wird von SharePoint ein Eintrag im Kontext-Menü des Dokumentes eingefügt.

Eintrag im SharePoint-Kontext-Menü eines Dokumentes

Dass dieser Menü-Eintrag in jeder Website-Sammlung (WSC) der Web Applikation zur Verfügung steht, ist allerdings nicht immer gewünscht. Aus diesem Grund habe ich für einen Kunden diesen Mechanismus angepasst, so dass das Versenden per WSC-Feature explizit aktiviert werden muss.

Der Haken “Allow manual submission from Send To menu” wird bei dem angepassten Mechanismus nicht gesetzt. Somit ist der “Send To”-Eintrag standardmäßig nicht im Kontext-Menü des Dokumentes sichtbar.

Durch das Aktivieren eines eigenen Features auf Website-Sammlung-Ebene wird ein separater “Send To”-Eintrag im Kontext-Menu hinzugefügt. Dem Menü-Eintrag wird eine URL zu einer eigenen “Application Page” zugewiesen, auf der zusätzliche Konfigurationen für den Versand des Dokumentes vorgenommen werden können.

Feature-Elements-Manifest Code für “Send To”-Menü-Eintrag

Sind alle Einstellungen für den Versand eines Dokumentes ausgewählt und gesetzt (bspw. Metadaten und die Verbindung) , dann kann das Dokument per Knopfdruck gesendet werden. Dafür kann folgender C#-Code verwendet werden:

C#-Code-Snippet für das Senden eines Dokumentes

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction
    Id="Customer.EditControlBlock"
    RegistrationType="List"
    RegistrationId="101"
    Location="EditControlBlock"
    Sequence="1000"
    Title="Send To">
    <UrlAction Url="javascript:SP.UI.ModalDialog.ShowPopupDialog('{SiteUrl}/_layouts/Customer/targets.aspx?List={ListId}&amp;ID={ItemId}')"/>
  </CustomAction>
</Elements>

Die Auswertung, ob der Transfer erfolgreich war, findet in der Methode “HandleOfficialFileResult” statt. Dort kann ggf. auf eine Störung reagiert werden.

C#-Code Snippet, um das Transfer-Ergebnis auszuwerten

SPOfficialFileHost host = site.WebApplication.OfficialFileHosts[hostIndex];

                                    OfficialFileResult configuration = docItem.File.SendToOfficialFile(String.Empty, host, (currentUser != null) ? currentUser.LoginName : string.Empty, SPOfficialFileSubmissionMode.Manual, out additionalInformation);
                                    HandleOfficialFileResult(docItem, configuration, additionalInformation, host.OfficialFileUrl.ToString());

Die Auswertung, ob der Transfer erfolgreich war, findet in der Methode “HandleOfficialFileResult” statt. Dort kann ggf. auf eine Störung reagiert werden.

C#-Code Snippet, um das Transfer-Ergebnis auszuwerten

private void HandleOfficialFileResult(SPListItem item, OfficialFileResult invalidConfiguration, string additionalRoutingInformation, string hostUrl)
        {
            try
            {
                string nextUrl = HttpUtility.UrlDecode(SPContext.Current.Web.Url);
                string name = "SendToOfficialFileError";
                string idStr = base.Request.QueryString["ID"];

                switch (invalidConfiguration)
                {
                    case OfficialFileResult.Success:
                        {
                            string parentWebUrl = item.ParentList.ParentWeb.Url.TrimEnd(new char[] { '/' });
                            if (nextUrl.StartsWith(parentWebUrl))
                            {
                                nextUrl = nextUrl.Substring(parentWebUrl.Length);
                            }
                            string message = "SuccessMsgSendToOfficialFile";
                            string messageParam = idStr;
                            XmlDocument document = new XmlDocument();
                            document.LoadXml(additionalRoutingInformation);
                            XmlNode errorNode = document.SelectSingleNode("//Error");
                            if ((errorNode != null) &amp;&amp; !string.IsNullOrEmpty(errorNode.InnerText))
                            {
                                message = (errorNode.InnerText == "MoveFailed") ? "SendToOfficialFilePostSubmissionMoveError" : "SendToOfficialFilePostSubmissionLinkError";
                            }

                            //Write transfer audit
                            //WriteTransferAudit(item, hostUrl);

                            XmlNode urlNode = document.SelectSingleNode("//Url");
                            string linkText = (urlNode != null) ? HttpUtility.HtmlDecode(urlNode.InnerText) : item.File.Url;
                            SPUtility.TransferToSuccessPage(message, nextUrl, linkText, linkText);
                            return;
                        }
                    case OfficialFileResult.MoreInformation:
                        WriteTransferAudit(item, hostUrl);
                        additionalRoutingInformation = String.Format("{0}/_layouts/Customer/transferSuccessPage.aspx", SPContext.Current.Web.Url);
                        // document is in drop off library waiting for timer job to push it into destination folder 
                        Response.Redirect(additionalRoutingInformation);
                        break;

                    case OfficialFileResult.InvalidConfiguration:
                        name = "SendToOfficialFileErrorInvalidConfig";
                        break;

                    case OfficialFileResult.NotFound:
                        name = "SendToOfficialFileErrorNotFound";
                        break;

                    case OfficialFileResult.FileRejected:
                        name = "SendToOfficialFileErrorFileRejected";
                        break;

                    case OfficialFileResult.FileCheckedOut:
                        name = "OfficialFileSubmissionFileCheckedOut";
                        break;

                    case OfficialFileResult.InvalidRouterConfiguration:
                        name = "SendToOfficialFileRouterError";
                        break;

                    case OfficialFileResult.RepositoryNotFound:
                        name = "OfficialFileSubmissionTargetNotFoundError";
                        break;

                    case OfficialFileResult.FileExists:
                        {
                            string strParentWebURL = item.ParentList.ParentWeb.Url.TrimEnd(new char[] { '/' });
                            if (nextUrl.StartsWith(strParentWebUrl))
                            {
                                nextUrl = nextUrl.Substring(strParentWebUrl.Length);
                            }
                            SPUtility.TransferToSuccessPage("FileExistsSendToOfficialFile", nextUrl, item.File.Url, item.File.Url);
                            return;
                        }
                    default:
                        if (name == null)
                        {
                            name = "SendToOfficialFileError";
                        }
                        break;
                }

                SPUtility.TransferToErrorPage(SPResource.GetString(name, new object[] { idStr, additionalRoutingInformation }) + "\n\n{0}", SPResource.GetString("SendToOfficialFileErrorRetry", new object[0]), this.Context.Request.RawUrl);
            }
            catch (Exception ex)
            {
                //logging
                throw ex;
            }
        }


Da SharePoint in Sachen Erweiterbarkeit alle Möglichkeiten bietet, kann die OOTB Basis-Technologie den Kundenwünschen entsprechend angepasst werden. Kaum ein anderes Produkt bietet so viel Flexibilität, um spezielle Anforderungen abbilden zu können.

Leave a comment

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload the CAPTCHA.