2010-09-28 74 views
0

我在SharePoint 2010中這樣做,但如果問題存在於SharePoint 2007中並且具有相同的解決方案,則不會感到驚訝。如何從BDC URL加載BDC數據?

我在我的BDC數據上有一個運行時安全修剪器。我期待安全微調器根據模型中定義的「默認」配置文件URL給我提供URL。不幸的是,事實並非如此。它給了我像一個網址: bdc3:// amms_amms /默認/ 00000000%252d0000%252d0000%252d0000%252d000000000000/1971年/ AMMS/1973年S_ID = ibqaaaaaaaaa = & s_ce = 07nk0004080g10003o03vvf

我需要的屬性?這個對象(真的只是主鍵值)。任何想法如何與BDC對象模型做到這一點?以下鏈接似乎提供了一些幫助,但我沒有看到任何消耗上述URL的內容。

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


更新:我看到SharePoint 2007中有一個AccessChecker(http://msdn.microsoft.com/en-us/library/aa981124.aspx)和2010年可能有這個問題,以及(在這方面找不到2010年的好文檔)。我們不容易在數據庫中擁有安全描述符,但AccessChecker方法可能就足夠了。

進一步挖掘我發現Microsoft.Office.Server.Search.Connector.BDC.BdcSecurityTrimmer是SharePoint 2010中AccessChecker使用的可能內容。看起來,它會對每個URL的數據庫執行查詢。即使它在多個線程中執行(似乎2007年的文檔聲稱要這樣做)似乎效率低下。我想我寧願將信息批量加入單個Web服務調用,但在柵欄上...

+0

Sharepoint 2010沒有「BDC」它有「BCS」 – 2010-09-28 21:24:52

+0

它已重命名,但SharePoint 2010中的BCS具有BDC模型文件,並且在整個SharePoint 2010 API中都使用該首字母縮略詞。 – 2010-09-29 00:30:51

回答

1

OK,這是我以前的答案的簡化。看樣子,你可以完全避免反射:

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; 
} 

請注意,我試圖使用從Microsoft.Office.Server.Search的UriParser避免。連接器使用代碼如:

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

不幸的是,這適用於某些身份證,而不是其他人。我決定不進一步調查,只使用特殊的UriParser。在一個例子中,我期待的ID是「5,20,21,7,8,6,14,19,17,18,4」,但這第二種方法給了我「5,20,21,24581,8, 24580,24588,24593,17,24592,4" 。自從前3個是正確的以來,這讓我困擾了幾分鐘。

0

我不確定這是最好的方法,但我通過使用反射器來工作反向工程Microsoft.Office.Server.Search.Connector.BDC.BdcSecurityTrimmer。我只需要身份值,以便簡化這一點。

下面是我的代碼,它將提供給安全修剪器的documentCrawlUrls數組轉換爲我的BDC模型文件中定義的主鍵數組。一旦我有了這些,我可以使用更多的自定義.NET代碼來確定安全修整。

在的checkAccess()我的安全修整的(ISecurityTrimmer2)我有:

String[] ids = GetIds(documentCrawlUrls); 

然後,我有以下的私有方法:

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; 
} 

我不想改寫SPBdcUri類它是內在的,所以我以反思作弊。我目前只使用其中一個輸出參數,所以我可以提高效率。我可以重寫我需要的SPBdcUri部分,而不是使用反射。

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; 
} 

哦,這是我的 「使用」 的語句:

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;