Frage

Ich tue dies in Sharepoint 2010, aber wäre nicht überrascht, wenn das Problem in Sharepoint 2007 existiert und hat die gleiche Lösung.

Ich habe eine Laufzeit Security Trimmer auf meinem BDC Daten. Ich hatte erwartet, die Sicherheitsschere mich URLs geben der „default“ Profil-URL definiert im Modell basiert. Leider ist das nicht der Fall. Es gibt mir eine URL wie:    bdc3: // amms_amms / default / 00000000% 252d0000% 252d0000% 252d0000% 252d000000000000 / 1971 / AMM / 1973 s_id = ibqaaaaaaaaa = & s_ce = 07nk0004080g10003o03vvf

Ich brauche die Eigenschaften dieses Objekts zu erhalten (wirklich nur der Primärschlüsselwert). Jede Idee, wie ich das mit dem BDC-Objektmodell? Der folgende Link scheint etwas Hilfe zur Verfügung zu stellen, aber ich habe nichts, dass verbrauchen die URL oben gesehen.

http://msdn.microsoft.com/en-us/library/ ee556400.aspx


Update: Ich sehe, dass Sharepoint 2007 eine AccessChecker hat (http://msdn.microsoft.com/en-us/library/aa981124.aspx) und 2010 wahrscheinlich hat dies auch (nicht gute Dokumentation für das Jahr 2010 auf diesem). Wir können nicht ohne weitere Sicherheitsbeschreibungen in der Datenbank, aber die AccessChecker Methode könnte ausreicht.

Graben ein wenig weiter ich sehe, dass Microsoft.Office.Server.Search.Connector.BDC.BdcSecurityTrimmer ist, was wahrscheinlich ist, was durch die AccessChecker in Sharepoint verwendet wird 2010. Es scheint, dass dies bedeutet eine Abfrage an die DB pro URL. Scheint ineffizient, selbst wenn sie es auf mehrere Threads tut (die die 2007-Dokumentation Ansprüche zu tun). Ich glaube, ich würde auf die Informationen in einen einzigen Web-Service-Aufruf zu Charge bevorzugen, aber ich bin auf dem Zaun ...

War es hilfreich?

Lösung

OK, hier ist eine Vereinfachung meiner früheren Antwort. Es scheint, dass Sie völlig Reflexion vermeiden kann:

using Microsoft.BusinessData.Runtime;
using Microsoft.Office.Server.Search.Connector;
using Microsoft.Office.Server.Search.Query;    

private string[] GetIds(IList<string> documentCrawlUrls)
{
    string[] ids = new String[documentCrawlUrls.Count];
    for (int i = 0; i < documentCrawlUrls.Count; i++)
    {
        try
        {
            string url = documentCrawlUrls[i];
            string id = new Microsoft.Office.Server.Search.Connector.UriParser(new Uri(url)).QueryStringParameters["s_id"];
            ids[i] = Identity.Deserialize(id).GetIdentifierValues()[0].ToString();
        }
        catch (Exception ex)
        {
            System.Diagnostics.Trace.WriteLine("Error: " + ex.Message);
        }
    }

    return ids;
}

Beachten Sie, dass ich versuchte, die Vermeidung der UriParser von Microsoft.Office.Server.Search.Connector mit Verwendung von Code wie:

string id = HttpUtility.ParseQueryString(new Uri(url).Query)["s_id"];
ids[i] = Identity.Deserialize(id.ToUpper()).GetIdentifierValues()[0].ToString();

Leider ist dies für einige IDs und andere nicht. Ich beschloss, nicht weiter zu untersuchen und nur die besondere UriParser verwenden. In einem Beispiel für die Ide Ich war auf der Suche waren „5,20,21,7,8,6,14,19,17,18,4“, aber dieser zweite Ansatz gab mir „5,20,21,24581,8, 24580,24588,24593,17,24592,4" . Dass verwirrte mich für ein paar Minuten, da die ersten 3 korrekt waren.

Andere Tipps

Ich bin nicht sicher, es ist der beste Ansatz, aber ich habe dies zu der Arbeit von Reflector mit Ingenieure Microsoft.Office.Server.Search.Connector.BDC.BdcSecurityTrimmer umkehren. Ich habe nur den Identitätswert so erforderlich, dass diese ein wenig vereinfacht.

Unten ist mein Code, der eine Reihe von documentCrawlUrls vorgesehen zum Sicherheitsschere nimmt und übersetzt sie in eine Reihe von Primärschlüsseln wie in meiner BDC-Modell-Datei definiert. Sobald ich die habe ich kann die Sicherheit bestimmen Trimmen mehr benutzerdefinierten .NET-Code.

In Checkaccess () meinem Security Trimmer (ISecurityTrimmer2) Ich habe:

String[] ids = GetIds(documentCrawlUrls);

Dann habe ich die folgende private Methode:

private string[] GetIds(IList<string> documentCrawlUrls)
{
    string[] ids = new String[documentCrawlUrls.Count];
    for (int i = 0; i < documentCrawlUrls.Count; i++)
    {
        try
        {
            string url = documentCrawlUrls[i];

            Identity identity = null;
            IEntity entity = null;
            ILobSystemInstance lsi = null;
            ParseUri(url, out entity, out identity, out lsi);
            if (identity != null)
            {
                object[] values = identity.GetIdentifierValues();
                if (values.Length > 0)
                {
                    ids[i] = values[0].ToString();
                }
            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Trace.WriteLine("Error: " + ex.Message);
        }
    }

    return ids;
}

Ich wollte nicht die SPBdcUri Klasse neu zu schreiben und es ist intern, so dass ich mit Reflexion betrug. Ich zur Zeit nur eine der möglichen Parameter verwenden, so dass ich auf die Effizienz zu verbessern. Ich kann die Teile der SPBdcUri neu schreiben, die ich brauche stattdessen Reflexion zurückzugreifen.

private void ParseUri(string crawlUri, out IEntity entity, out Identity identity, out ILobSystemInstance lsi)
{
    //SPBdcUri uri = new SPBdcUri(new Uri(crawlUri));
    AssemblyName assemblyName = new AssemblyName("Microsoft.Office.Server.Search.Connector, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");
    Assembly assembly = Assembly.Load(assemblyName);
    Type spBdcUriType = assembly.GetType("Microsoft.Office.Server.Search.Connector.BDC.SPBDC.SPBdcUri");
    object uri = Activator.CreateInstance(spBdcUriType,
        BindingFlags.NonPublic | BindingFlags.Instance,
        null, new object[] { new Uri(crawlUri) }, System.Globalization.CultureInfo.CurrentCulture);

    //uri.DoOverrideBDCThrottlingLimits = false;
    spBdcUriType.InvokeMember("DoOverrideBDCThrottlingLimits",
        BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
        null, uri, new object[] { false });

    //entity = uri.Entity;
    object entityObj = spBdcUriType.InvokeMember("Entity",
        BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty,
        null, uri, null);
    entity = (IEntity)entityObj;

    //identity = uri.Identity;
    object identityObj = spBdcUriType.InvokeMember("Identity",
        BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty,
        null, uri, null);
    identity = (Identity)identityObj;

    //lsi = uri.LobSystemInstance;
    object lsiObj = spBdcUriType.InvokeMember("LobSystemInstance",
        BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty,
        null, uri, null);
    lsi = (ILobSystemInstance)lsiObj;
}

Oh, hier ist meine "mit" Aussagen:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

using Microsoft.BusinessData.MetadataModel.Collections;
using Microsoft.BusinessData.MetadataModel;
using Microsoft.BusinessData.Runtime;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.BusinessData.SharedService;
using Microsoft.Office.Server.Search.Query;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top