我是在SharePoint 2010中这样做的,但是如果SharePoint 2007中存在问题并且有相同的解决方案,我不会感到惊讶。
我在我的BDC数据上有一个运行时安全修整器。我原以为安全微调器会根据模型中定义的“默认”配置文件URL为我提供URL。不幸的是,情况并非如此。它给了我一个网址,如: bdc3://amms_amms/default/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很可能是AccessChecker在SharePoint 2010中使用的东西。这似乎会对每个URL的DB进行查询。即使它确实在多个线程上这样做(2007年的文档声称这样做),也是效率低下的。我想我更愿意把这些信息分门别类成一个网络服务电话,但是.
发布于 2010-09-29 16:30:34
好的,这是我之前的答案的一个简化。看来您完全可以避免反射:
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;
}请注意,我试图避免使用以下代码从UriParser中使用Microsoft.Office.Server.Search.Connector:
string id = HttpUtility.ParseQueryString(new Uri(url).Query)["s_id"];
ids[i] = Identity.Deserialize(id.ToUpper()).GetIdentifierValues()[0].ToString();不幸的是,这对某些Id有效,而对其他Id无效。我决定不再做进一步的调查,只使用特殊的UriParser。在一个例子中,我正在寻找的In是"5,20,21,7,8,6,14,19,17,18,4“,但是第二种方法给了我"5,20,21,24581,8,24580,24588,24593,17,24592,4".。这使我搞砸了几分钟,因为前三名是正确的。
发布于 2010-09-29 03:57:24
我不确定这是最好的方法,但我通过使用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;https://stackoverflow.com/questions/3817142
复制相似问题