【问题标题】:How do I load BDC data from a BDC URL?如何从 BDC URL 加载 BDC 数据?
【发布时间】:2010-09-30 00:30:34
【问题描述】:

我在 SharePoint 2010 中执行此操作,但如果 SharePoint 2007 中存在问题并且具有相同的解决方案,我不会感到惊讶。

我的 BDC 数据有一个运行时安全修剪器。我期待安全修剪器根据模型中定义的“默认”配置文件 URL 为我提供 URL。不幸的是,事实并非如此。它给了我一个像这样的 URL: bdc3://amms_amms/default/00000000%252d0000%252d0000%252d0000%252d000000000000/1971/amms/1973?s_id=ibqaaaaaaaa=&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 服务调用中,但我犹豫不决......

【问题讨论】:

  • Sharepoint 2010 没有“BDC”它有“BCS”
  • 它已重命名,但 SharePoint 2010 中的 BCS 具有 BDC 模型文件,并且整个 SharePoint 2010 API 都使用该首字母缩写词。

标签: sharepoint bdc bcs


【解决方案1】:

好的,这是我之前回答的简化版。看来你完全可以避免反思:

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.Connector 中的 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 个是正确的,所以这让我困惑了几分钟。

【讨论】:

    【解决方案2】:

    我不确定这是不是最好的方法,但我通过使用 Reflector 对 Microsoft.Office.Server.Search.Connector.BDC.BdcSecurityTrimmer 进行逆向工程来实现这一点。我只需要标识值,以便稍微简化一下。

    下面是我的代码,它采用提供给安全修剪器的 documentCrawlUrls 数组,并将它们转换为我的 BDC 模型文件中定义的主键数组。一旦我有了这些,我就可以使用更多的自定义 .NET 代码来确定安全调整。

    在我的安全修剪器 (ISecurityTrimmer2) 的 CheckAccess() 中,我有:

    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 类,它是内部的,所以我用反射作弊。我目前只使用其中一个 out 参数,因此可以提高效率。我可能会重写我需要的 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;
    

    【讨论】:

      猜你喜欢
      • 2011-05-20
      • 2011-05-18
      • 2011-09-09
      • 2011-06-17
      • 2020-10-24
      • 1970-01-01
      • 2013-05-24
      • 1970-01-01
      • 2010-09-11
      相关资源
      最近更新 更多