is there a simple way to add IP to the restriction list in IIS IP and Domain blocker programmatically, at best from within ASP.NET code?
As suggested by #kev you need to use the Windows Management Instrumentation (WMI) and Active Directory Service Interfaces (ADSI).
below are some ways to block IP by programmatically:
1)
using System;
using System.Text;
using Microsoft.Web.Administration;
internal static class Sample {
private static void Main() {
using(ServerManager serverManager = new ServerManager()) {
Configuration config = serverManager.GetWebConfiguration("sitename");
ConfigurationSection ipSecuritySection = config.GetSection("system.webServer/security/ipSecurity");
ipSecuritySection["allowUnlisted"] = false;
ConfigurationElementCollection ipSecurityCollection = ipSecuritySection.GetCollection();
ConfigurationElement addElement = ipSecurityCollection.CreateElement("add");
addElement["ipAddress"] = #"192.168.2.50";
ipSecurityCollection.Add(addElement);
ConfigurationElement addElement1 = ipSecurityCollection.CreateElement("add");
addElement1["ipAddress"] = #"192.168.2.52";
ipSecurityCollection.Add(addElement1);
serverManager.CommitChanges();
}
}
}
2)
using System;
using System.IO;
using System.Collections;
using System.DirectoryServices;
using System.Reflection;
namespace soccerwrek
{
class IISWMI
{
[STAThread]
static void Main(string[] args)
{
try
{
// retrieve the directory entry for the root of the IIS server
System.DirectoryServices.DirectoryEntry IIS =
new System.DirectoryServices.DirectoryEntry(
"IIS://localhost/w3svc/1/root");
// retrieve the list of currently denied IPs
Console.WriteLine(
"Retrieving the list of currently denied IPs.");
// get the IPSecurity property
Type typ = IIS.Properties["IPSecurity"][0].GetType();
object IPSecurity = IIS.Properties["IPSecurity"][0];
// retrieve the IPDeny list from the IPSecurity object
Array origIPDenyList = (Array) typ.InvokeMember("IPDeny",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.GetProperty,
null, IPSecurity, null);
// display what was being denied
foreach(string s in origIPDenyList)
Console.WriteLine("Before: " + s);
// check GrantByDefault. This has to be set to true,
// or what we are doing will not work.
bool bGrantByDefault = (bool) typ.InvokeMember("GrantByDefault",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.GetProperty,
null, IPSecurity, null);
Console.WriteLine("GrantByDefault = " + bGrantByDefault);
if(!bGrantByDefault)
{
typ.InvokeMember("GrantByDefault",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.SetProperty,
null, IPSecurity, new object[] {true});
}
// update the list of denied IPs. This is a
// complete replace. If you want to maintain what
// was already being denied, you need to make sure
// those IPs are in here as well. This area
// will be where you will most likely modify to
// your needs as this is just an example.
Console.WriteLine("Updating the list of denied IPs.");
object[] newIPDenyList = new object[4];
newIPDenyList[0] = "192.168.1.1, 255.255.255.255";
newIPDenyList[1] = "192.168.1.2, 255.255.255.255";
newIPDenyList[2] = "192.168.1.3, 255.255.255.255";
newIPDenyList[3] = "192.168.1.4, 255.255.255.255";
Console.WriteLine("Calling SetProperty");
// add the updated list back to the IPSecurity object
typ.InvokeMember("IPDeny",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.SetProperty,
null, IPSecurity, new object[] {newIPDenyList});
IIS.Properties["IPSecurity"][0] = IPSecurity;
Console.WriteLine("Commiting the changes.");
// commit the changes
IIS.CommitChanges();
IIS.RefreshCache();
// check to see if the update took
Console.WriteLine("Checking to see if the update took.");
IPSecurity = IIS.Properties["IPSecurity"][0];
Array y = (Array) typ.InvokeMember("IPDeny",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.GetProperty,
null, IPSecurity, null);
foreach(string s in y)
Console.WriteLine("After: " + s);
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.ToString());
}
}
}
}
You could refer this links for more detail:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/f6580aaf-ed47-4bb1-b976-6108595b8dfb/block-ip-in-windows-through-c?forum=csharpgeneral
Related
I’m writing a customization to add records to a timecard and I’m trying to create a new record to add to the timecard. Using the logic in T230 I’m creating a variable and I’m being told by the compiler that EPTimecardDetail cannot be found.
I’ve added using PX.Objects.EP and PX.Objects.PM but I figure that if TimeCardMaint can be found then EPTimecardDetail should be able be found as well. I’ve included my using code as well but I think I’m missing something else.
using System;
using System.Collections;
using PX.Data;
using PX.Data.BQL.Fluent;
using PX.Data.BQL;
using PX.Objects.CS;
using PX.Objects.PM;
using PX.Objects.EP;
using PX.Objects.CR;
using PX.Objects.AR;
using PX.Objects.CT;
using PX.Objects.GL.FinPeriods;
using PX.TM;
using System.Collections.Generic;
namespace TimecardImport
{
public class NLTimecardLineEntry : PXGraph<NLTimecardLineEntry>
{
private static void DoPopulateTimeCard(Int32 employeeID, DateTime startDate, NLTimecardLine record)
{
TimeCardMaint graph = PXGraph.CreateInstance<TimeCardMaint>();
Int32 cardWeekID = PXWeekSelector2Attribute.GetWeekID(graph, startDate);
//look for an employee timecard with the current weekID
EPTimeCard card = PXSelectReadonly<EPTimeCard,
Where<EPTimeCard.employeeID, Equal<Required<EPTimeCard.employeeID>>,
And<EPTimeCard.weekId, Equal<Required<EPTimeCard.weekId>>>>>.SelectWindowed(graph, 0, 1, employeeID, cardWeekID);
if (card == null) //if a card was not found, create one
{
card = (EPTimeCard)graph.Document.Cache.CreateInstance();
card.WeekID = cardWeekID;
card.EmployeeID = employeeID;
card = graph.Document.Insert(card);
}
//at this point card is the card that we're going to work with
var detailLine = (EPTimecardDetail)graph.Activities.Cache.CreateCopy(
graph.Activities.Insert());
//detailLine.SetValueExt<detailLine.Date_Date>(record, record.InDate);
//detailLine.EarningTypeID = "RG";
//detailLine = graph.Activities.Update(detailLine);
graph.Save.Press();
}
}}
The error I'm getting is "The type or namespace name 'EPTimecardDetail' could not be found (are you missing a using directive or an assembly reference?)".
EPTimecardDetail is defined within PX.Objects.EP so I'm not sure why I'm having a problem there. Or, perhaps this is not the way to add records to the Details tab of the Employee Time Card screen?
For the namespace issue you can declare using PX.Object.EP and refer to the type as TimeCardMaint.EPTimecardDetail
Or you can declare using static PX.Objects.EP.TimeCardMaint and refer to the type as EPTimecardDetail
For inserting the record check the source code in file TimeCardMaint.cs There are examples on how to insert this DAC record.
Make sure the fields used for SQL joins like OrigNoteID and RefNoteID have the proper value (non null).
This example is from the Correct action in TimeCardMaint:
[PXUIField(DisplayName = Messages.Correct)]
[PXButton(ImageKey = PX.Web.UI.Sprite.Main.Release)]
public virtual IEnumerable Correct(PXAdapter adapter)
{
if (Document.Current != null)
{
EPTimeCard source = GetLastCorrection(Document.Current);
if (source.IsReleased != true)
return new EPTimeCard[] { source };
EPTimeCard newCard = (EPTimeCard)Document.Cache.CreateInstance();
newCard.WeekID = source.WeekID;
newCard.OrigTimeCardCD = source.TimeCardCD;
newCard = Document.Insert(newCard);
newCard.EmployeeID = source.EmployeeID;
PXNoteAttribute.CopyNoteAndFiles(Document.Cache, source, Document.Cache, newCard, true, true);
bool failed = false;
Dictionary<string, TimeCardSummaryCopiedInfo> summaryDescriptions = new Dictionary<string, TimeCardSummaryCopiedInfo>();
foreach (EPTimeCardSummary summary in Summary.View.SelectMultiBound(new object[] { source }))
{
string key = GetSummaryKey(summary);
if (!summaryDescriptions.ContainsKey(key))
{
string note = PXNoteAttribute.GetNote(Summary.Cache, summary);
var info = new TimeCardSummaryCopiedInfo(summary.Description, note);
summaryDescriptions.Add(key, info);
}
}
foreach (EPTimecardDetail act in TimecardActivities.View.SelectMultiBound(new object[] { source }))
{
EPTimecardDetail newActivity = PXCache<EPTimecardDetail>.CreateCopy(act);
newActivity.Released = false;
newActivity.Billed = false;
newActivity.NoteID = null;
newActivity.TimeCardCD = null;
newActivity.TimeSheetCD = null;
newActivity.OrigNoteID = act.NoteID; //relation between the original activity and the corrected one.
newActivity.Date = act.Date;
newActivity.Billed = false;
newActivity.SummaryLineNbr = null;
newActivity.NoteID = null;
newActivity.ContractCD = null;
isCreateCorrectionFlag = true;
try
{
newActivity = Activities.Insert(newActivity);
}
catch (PXSetPropertyException ex)
{
failed = true;
Activities.Cache.RaiseExceptionHandling<EPTimecardDetail.summary>(act, act.Summary, new PXSetPropertyException(ex.MessageNoPrefix, PXErrorLevel.RowError));
continue;
}
newActivity.TrackTime = act.TrackTime; //copy as is.
isCreateCorrectionFlag = false;
newActivity.ApprovalStatus = ActivityStatusAttribute.Completed;
newActivity.RefNoteID = act.NoteID == act.RefNoteID ? newActivity.NoteID : act.RefNoteID;
newActivity.ContractCD = act.ContractCD;
PXNoteAttribute.CopyNoteAndFiles(Activities.Cache, act, Activities.Cache, newActivity);
Activities.Cache.SetValue<EPTimecardDetail.isCorrected>(act, true);
Activities.Cache.SetStatus(act, PXEntryStatus.Updated);
}
if (failed)
{
throw new PXException(Messages.FailedToCreateCorrectionTC);
}
foreach (EPTimeCardItem item in Items.View.SelectMultiBound(new object[] { source }))
{
EPTimeCardItem record = Items.Insert();
record.ProjectID = item.ProjectID;
record.TaskID = item.TaskID;
record.Description = item.Description;
record.InventoryID = item.InventoryID;
record.CostCodeID = item.CostCodeID;
record.UOM = item.UOM;
record.Mon = item.Mon;
record.Tue = item.Tue;
record.Wed = item.Wed;
record.Thu = item.Thu;
record.Fri = item.Fri;
record.Sat = item.Sat;
record.Sun = item.Sun;
record.OrigLineNbr = item.LineNbr;//relation between the original activity and the corrected one.
}
foreach (EPTimeCardSummary summary in Summary.Select())
{
string key = GetSummaryKey(summary);
if (summaryDescriptions.ContainsKey(key))
{
PXNoteAttribute.SetNote(Summary.Cache, summary, summaryDescriptions[key].Note);
Summary.Cache.SetValue<EPTimeCardSummary.description>(summary, summaryDescriptions[key].Description);
}
}
return new EPTimeCard[] { newCard };
}
return adapter.Get();
}
I see so many people struggling to copy or moving files around in SharePoint online, that I decided to write a small demo console app to show how to do it.
We will be using the CreateCopyJobs method, available on CSOM to copy a folder from one site collection to another. This method can be used to copy or move files between site collections or even on the same SC, betwen different libraries or folders inside a library.
The method works exactly as the UI, when you try to copy or move something in a library.
1 - Create new .NET console app. We will be using PnP, so go to your project NuGet manager and add SharePointPnPCoreOnline
2 - add to the usings of your class the following:
using Microsoft.SharePoint.Client;
using Newtonsoft.Json;
using OfficeDevPnP.Core;
3 - Define the following class to receive the status of the job that we will be checking.
class CopyJobProgress
{
public string Event;
public string JobId;
public string CorrelationId;
}
4 - Now add this sample main method:
static void Main(string[] args)
{
var siteUrl = "https://...-admin.sharepoint.com";
var userName = "admin#...";
var password = "....";
AuthenticationManager authManager = new AuthenticationManager();
using (var ctx = authManager.GetSharePointOnlineAuthenticatedContextTenant(siteUrl, userName, password))
{
var web = ctx.Web;
ctx.Load(web);
ctx.ExecuteQuery();
string sourceFile = "https://....sharepoint.com/sites/<site>/<library>/<file or folder>";
string destinationPath = "https://....sharepoint.com/sites/<site>/<destination library>";
var createJobInfo = ctx.Site.CreateCopyJobs(new string[] { sourceFile }, destinationPath,
new CopyMigrationOptions() { IsMoveMode = false, IgnoreVersionHistory = true,
AllowSchemaMismatch = true, NameConflictBehavior = MigrationNameConflictBehavior.Replace });
ctx.ExecuteQueryRetry();
Dictionary<string, CopyJobProgress> eventsFound = new Dictionary<string, CopyJobProgress>();
bool jobEndFound = false;
while (!jobEndFound)
{
var progress = ctx.Site.GetCopyJobProgress(createJobInfo[0]);
ctx.ExecuteQuery();
foreach (string log in progress.Value.Logs)
{
CopyJobProgress progressRes = (CopyJobProgress)JsonConvert.DeserializeObject(log, typeof(CopyJobProgress));
if (!eventsFound.ContainsKey(progressRes.Event))
{
Console.WriteLine(DateTime.Now + " - " + progressRes.Event + " - CorrelationId: " + progressRes.CorrelationId);
eventsFound[progressRes.Event] = progressRes;
}
if (progressRes.Event == "JobEnd")
{
jobEndFound = true;
}
}
if (!jobEndFound)
System.Threading.Thread.Sleep(2000);
}
Console.WriteLine("Done!");
}
}
I am newbie in COM. I am having a trouble on creating a plugin for an own software that would intercept traffic on a third party software by the clsid:
All information by the third party owners -->
*clsid: 0BBB797E-D6A8-40F9-B5D1-8E72F4729A03
*event to receive data - OnRecvData(NetworkData) //NetworkData type of string
*event to send data - OnSendData(NetworkData) //NetworkData type of string
I have referenced Invoke method using Reflection on COM Object and tried to get the methods, events, properties that the created instance contains.
Here is the code I have used ->
class Program
{
private const string WORD_CLSID = "{0BBB797E-D6A8-40F9-B5D1-8E72F4729A03}";
public static void Main()
{
try
{
Type comType = Type.GetTypeFromCLSID(new Guid(WORD_CLSID));
var instance = Activator.CreateInstance(comType);
Console.WriteLine("//////////////////");
Console.WriteLine("Created an instance of: " + comType.Name + "-->\nCLSID = " + WORD_CLSID);
var invokedData = comType.InvokeMember("NetworkData",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.InvokeMethod, null, instance, null);
Console.WriteLine("NetworkData ->" + invokedData);
Console.WriteLine("\nEVENTS ----");
var comEvents = comType.GetEvents();
foreach (var comEvent in comEvents)
Console.WriteLine(comEvent);
if (comEvents.Count() == 0)
Console.WriteLine("0");
var comMethods = comType.GetMethods();
Console.WriteLine("\nMETHODS --");
foreach (var comMethod in comMethods)
{
var methodDetails = string.Format("{0} {1}({2})", comMethod.ReturnParameter, comMethod.Name,
string.Join(",", comMethod.GetParameters().Select(p => p.ParameterType.Name)));
Console.WriteLine("\t" + methodDetails);
}
var comProperties = instance.GetType().GetProperties();
Console.WriteLine("\nPROPERTIES----");
foreach (var comProperty in comProperties)
Console.WriteLine(comProperty);
if (comProperties.Count() == 0)
Console.WriteLine(0);
Console.WriteLine("\n--------------------------OVER");
}
catch (COMException ex)
{
Console.WriteLine("Unable to instantiate object. MESSAGE: " + ex.Message);
}
Console.Read();
}
}
and I get error of type: HRESULT 0x80020006 Unknown name.
How can I resolve this type of problem?
i am getting below error while run this program
i am using SharePoint server 2010 and recently i am install danish language pack in SharePoint server for client environment . but after this when ever i am run below code
i am getting below exceptions
org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentException: Bad Request
at org.apache.chemistry.opencmis.client.bindings.spi.atompub.AbstractAtomPubService.convertStatusCode(AbstractAtomPubService.java:453)
at org.apache.chemistry.opencmis.client.bindings.spi.atompub.AbstractAtomPubService.read(AbstractAtomPubService.java:601)
at org.apache.chemistry.opencmis.client.bindings.spi.atompub.NavigationServiceImpl.getChildren(NavigationServiceImpl.java:86)
at org.apache.chemistry.opencmis.client.runtime.FolderImpl$2.fetchPage(FolderImpl.java:285)
at org.apache.chemistry.opencmis.client.runtime.util.AbstractIterator.getCurrentPage(AbstractIterator.java:132)
at org.apache.chemistry.opencmis.client.runtime.util.AbstractIterator.getTotalNumItems(AbstractIterator.java:70)
at org.apache.chemistry.opencmis.client.runtime.util.AbstractIterable.getTotalNumItems(AbstractIterable.java:94)
at ShareTest1.main(ShareTest1.java:188)
public class ShareTest
{
static Session session = null;
static Map<String,Map<String, String>> allPropMap=new HashMap<String,Map<String, String>>();
static void getSubTypes(Tree tree)
{
ObjectType objType = (ObjectType) tree.getItem();
if(objType instanceof DocumentType)
{
System.out.println("\n\nType name "+objType.getDisplayName());
System.out.println("Type Id "+objType.getId());
ObjectType typeDoc=session.getTypeDefinition(objType.getId());
Map<String,PropertyDefinition<?>> mp=typeDoc.getPropertyDefinitions();
for(String key:mp.keySet())
{
PropertyDefinition<?> propdef=mp.get(key);
HashMap<String,String> propMap=new HashMap<String,String>();
propMap.put("id",propdef.getId());
propMap.put("displayName",propdef.getDisplayName());
System.out.println("\nId="+propMap.get("id")+" DisplayName="+propMap.get("displayName"));
System.out.println("Property Type = "+propdef.getPropertyType().toString());
System.out.println("Property Name = "+propdef.getPropertyType().name());
System.out.println("Property Local Namespace = "+propdef.getLocalNamespace());
if(propdef.getChoices()!=null)
{
System.out.println("Choices size "+propdef.getChoices().size());
}
if(propdef.getExtensions()!=null)
{
System.out.println("Extensions "+propdef.getExtensions().size());
}
allPropMap.put(propdef.getId(),propMap);
}
List lstc=tree.getChildren();
System.out.println("\nSize of list "+lstc.size());
for (int i = 0; i < lstc.size(); i++) {
getSubTypes((Tree) lstc.get(i));
}
}
}
public static void main(String[] args)
{
/**
* Get a CMIS session.
*/
String user="parag.patel";
String pwd="Admin123";
/*Repository : Abc*/
String url="http://sharepointind1:34326/sites/DanishTest/_vti_bin/cmis/rest/6B4D3830-65E5-49C9-9A02-5D67DB1FE87B?getRepositoryInfo";
String repositoryId="6B4D3830-65E5-49C9-9A02-5D67DB1FE87B";
// Default factory implementation of client runtime.
// default factory implementation
SessionFactory factory = SessionFactoryImpl.newInstance();
Map<String, String> parameter = new HashMap<String, String>();
// user credentials
parameter.put(SessionParameter.USER, "parag.patel");
parameter.put(SessionParameter.PASSWORD, "Admin123");
// connection settings
parameter.put(SessionParameter.ATOMPUB_URL, "http://sharepointind1:34326/sites/DanishTest/_vti_bin/cmis/rest/6B4D3830-65E5-49C9-9A02-5D67DB1FE87B?getRepositoryInfo");
parameter.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
parameter.put(SessionParameter.REPOSITORY_ID, "6B4D3830-65E5-49C9-9A02-5D67DB1FE87B");
parameter.put(SessionParameter.LOCALE_ISO3166_COUNTRY, "DK");
parameter.put(SessionParameter.LOCALE_ISO639_LANGUAGE, "da");
parameter.put(SessionParameter.LOCALE_VARIANT, "");
parameter.put(SessionParameter.AUTHENTICATION_PROVIDER_CLASS, CmisBindingFactory.STANDARD_AUTHENTICATION_PROVIDER);
// create session
Session session = factory.createSession(parameter);
if(repositoryId!=null)
{
parameter.put(SessionParameter.REPOSITORY_ID, repositoryId);
session=factory.createSession(parameter);
RepositoryInfo repInfo=session.getRepositoryInfo();
System.out.println("Repository Id "+repInfo.getId());
System.out.println("Repository Name "+repInfo.getName());
System.out.println("Repository cmis version supported "+repInfo.getCmisVersionSupported());
System.out.println("Sharepoint product "+repInfo.getProductName());
System.out.println("Sharepoint version "+repInfo.getProductVersion());
System.out.println("Root folder id "+repInfo.getRootFolderId());
try
{
AclCapabilities cap=session.getRepositoryInfo().getAclCapabilities();
OperationContext operationContext = session.createOperationContext();
int maxItemsPerPage=5;
//operationContext.setMaxItemsPerPage(maxItemsPerPage);
int documentCount=0;
session.setDefaultContext(operationContext);
CmisObject object = session.getObject(new ObjectIdImpl(repInfo.getRootFolderId()));
Folder folder = (Folder) object;
System.out.println("======================= Root folder "+folder.getName());
ItemIterable<CmisObject> children = folder.getChildren();
long to=folder.getChildren().getTotalNumItems();
System.out.println("Total Children "+to);
Iterator<CmisObject> iterator = children.iterator();
while (iterator.hasNext()) {
CmisObject child = iterator.next();
System.out.println("\n\nChild Id "+child.getId());
System.out.println("Child Name "+child.getName());
if (child.getBaseTypeId().value().equals(ObjectType.FOLDER_BASETYPE_ID))
{
System.out.println("Type : Folder");
Folder ftemp=(Folder) child;
long tot=ftemp.getChildren().getTotalNumItems();
System.out.println("Total Children "+tot);
ItemIterable<CmisObject> ftempchildren = ftemp.getChildren();
Iterator<CmisObject> ftempIt = ftempchildren.iterator();
int folderDoc=0;
while (ftempIt.hasNext()) {
CmisObject subchild = ftempIt.next();
if(subchild.getBaseTypeId().value().equals(ObjectType.DOCUMENT_BASETYPE_ID))
{
System.out.println("============ SubDoc "+subchild.getName());
folderDoc++;
documentCount++;
}
}
System.out.println("Folder "+child.getName()+" No of documents="+(folderDoc));
}
else
{
System.out.println("Type : Document "+child.getName());
documentCount++;
}
}
System.out.println("\n\nTotal no of documents "+documentCount);
}
catch(CmisPermissionDeniedException pd)
{
System.out.println("Error ********** Permission Denied ***************** ");
pd.printStackTrace();
}
catch (CmisObjectNotFoundException co) {
System.out.println("Error ******** Root folder not found ***************");
co.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
}
else
{
System.out.println("Else");
Repository soleRepository=factory.getRepositories(
parameter).get(0);
session = soleRepository.createSession();
}
}
}
here it is my lib which i used in above code .
chemistry-opencmis-client-api-0.9.0
chemistry-opencmis-client-bindings-0.9.0
chemistry-opencmis-client-impl-0.9.0
chemistry-opencmis-commons-api-0.9.0
chemistry-opencmis-commons-impl-0.9.0
log4j-1.2.14
slf4j-api-1.6.1
slf4j-log4j12-1.6.1
it works fine when i am trying to connect repository (url) which is created in english language .
but when try to connect with the danish .repository then getting error.
The best thing you can do is to increase the SharePoint log level for CMIS. Sometimes the logs provide a clue.
The SharePoint 2010 CMIS implementaion isn't a 100% spec compliant. OpenCMIS 0.12.0 contains a few workarounds for SharePoint 2010 and 2013. Most of them a little things like an extra requied URL parameter that isn't in the spec. I wouldn't be supprised if this is something similar.
I am doing this in SharePoint 2010, but wouldn't be surprised if the problem exists in SharePoint 2007 and has the same solution.
I have a runtime security trimmer on my BDC data. I was expecting the security trimmer to give me URLs based off of the "default" profile URL defined in the model. Unfortunately, that is not the case. It gives me a URL like:
bdc3://amms_amms/default/00000000%252d0000%252d0000%252d0000%252d000000000000/1971/amms/1973?s_id=ibqaaaaaaaaa=&s_ce=07nk0004080g10003o03vvf
I need to get the properties of this object (really just the primary key value). Any idea how I do this with the BDC object model? The following link seems to provide some help, but I haven't seen anything that consumes the URL above.
http://msdn.microsoft.com/en-us/library/ee556400.aspx
Update: I see that SharePoint 2007 has an AccessChecker (http://msdn.microsoft.com/en-us/library/aa981124.aspx) and 2010 likely has this as well (can't find good documentation for 2010 on this). We can't easily have security descriptors in the database, but the AccessChecker method might suffice.
Digging a little further I see that Microsoft.Office.Server.Search.Connector.BDC.BdcSecurityTrimmer is what is likely what is used by the AccessChecker in SharePoint 2010. It appears that this does a query to the DB per URL. Seems inefficient even if it does do it on multiple threads (which the 2007 documentation claims to do). I think I would prefer to batch up the information into a single web service call, but am on the fence...
OK, here's a simplification of my previous answer. It appears that you can totally avoid reflection:
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;
}
Note that I tried avoiding using the UriParser from Microsoft.Office.Server.Search.Connector using code like:
string id = HttpUtility.ParseQueryString(new Uri(url).Query)["s_id"];
ids[i] = Identity.Deserialize(id.ToUpper()).GetIdentifierValues()[0].ToString();
Unfortunately, this worked for some Id's and not others. I decided not to investigate any further and just use the special UriParser. In one example the ids I was looking for were "5,20,21,7,8,6,14,19,17,18,4" but this second approach gave me "5,20,21,24581,8,24580,24588,24593,17,24592,4". That messed me up for a few minutes since the first 3 were correct.
I'm not sure it is the best approach, but I got this to work by using Reflector to reverse engineer Microsoft.Office.Server.Search.Connector.BDC.BdcSecurityTrimmer. I only needed the identity value so that simplified this a little.
Below is my code that takes an array of documentCrawlUrls provided to the security trimmer and translates them into an array of primary keys as defined in my BDC model file. Once I have those I can determine the security trimming using more custom .NET code.
In CheckAccess() of my security trimmer (ISecurityTrimmer2) I have:
String[] ids = GetIds(documentCrawlUrls);
Then I have the following private method:
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;
}
I didn't want to rewrite the SPBdcUri class and it is internal, so I cheat with reflection. I currently only use one of the out parameters so I can improve on efficiency. I may re-write the portions of SPBdcUri that I need instead of resorting to reflection.
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, here's my "using" statements:
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;