UnsafeNativeMethods exception with GroupPrincipal.getMembers() - .net-core

I recently started porting our .Net 4.6 web application to .Net Core 2.0 and am having some problems regarding the access to System.DirectoryServices.AccountManagement
I want to access GroupPrincipal.getMembers() but keep getting an UnsafeNativeMethods exception:
System.DirectoryServices.Interop.UnsafeNativeMethods+IAds.GetInfoEx(object vProperties, int lnReserved)
System.DirectoryServices.DirectoryEntry.RefreshCache(String[] propertyNames)
System.DirectoryServices.AccountManagement.RangeRetriever.GetNextChunk()
System.DirectoryServices.AccountManagement.RangeRetriever.MoveNext()
System.DirectoryServices.AccountManagement.ADDNLinkedAttrSet.GetNextEnum()
System.DirectoryServices.AccountManagement.ADDNLinkedAttrSet.MoveNextMemberEnum()
System.DirectoryServices.AccountManagement.ADDNLinkedAttrSet.MoveNext()
System.DirectoryServices.AccountManagement.FindResultEnumerator.MoveNext()
AspNetCore._Views_Groups_Show_cshtml+<ExecuteAsync>d__0.MoveNext() in Show.cshtml
+
#foreach (var p in Model.GetMembers())
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
The code in the Show.cshtml:
#using System.DirectoryServices.AccountManagement
#model GroupPrincipal
#foreach (var p in Model.GetMembers())
{
...
}
The exception:
System.Exception: An operations error occurred.
Already tried moving the code from the view into the controller and marking it with unsafe but that doesn't help either.
Code is already running as domain admin, can access all users etc. Just the method calls don't work.
What's the correct way to handle this?

Ok, seems that I've found a solution/workaround:
I saw that it processes the principals and throws an exception after processing them.
So I just put the principals in another list and caught the exception.
The new list contains all principals and can be accessed without problems.
List<Principal> members = new List<Principal>();
try
{
members.AddRange(group.GetMembers());
}
catch (Exception)
{
; // do nothing
}
Must be a bug in the .NET core implementation of System.DirectoryServices.AccountManagement

Related

Realm doesn’t work with xUnite and .net core

I’m having issues running realm with xUnite and Net core. Here is a very simple test that I want to run
public class UnitTest1
{
[Scenario]
public void Test1()
{
var realm = Realm.GetInstance(new InMemoryConfiguration("Test123"));
realm.Write(() =>
{
realm.Add(new Product());
});
var test = realm.All<Product>().First();
realm.Write(() => realm.RemoveAll());
}
}
I get different exceptions on different machines (Windows & Mac) on line where I try to create a Realm instace with InMemoryConfiguration.
On Mac I get the following exception
libc++abi.dylib: terminating with uncaught exception of type realm::IncorrectThreadException: Realm accessed from incorrect thread.
On Windows I get the following exception when running
ERROR Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. at
System.Net.Sockets.NetworkStream.Read(Span1 destination) at
System.Net.Sockets.NetworkStream.ReadByte() at
System.IO.BinaryReader.ReadByte() at
System.IO.BinaryReader.Read7BitEncodedInt() at
System.IO.BinaryReader.ReadString() at
Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.LengthPrefixCommunicationChannel.NotifyDataAvailable() at
Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TcpClientExtensions.MessageLoopAsync(TcpClient client, ICommunicationChannel channel, Action1 errorHandler, CancellationToken cancellationToken) Source: System.Net.Sockets HResult: -2146232800 Inner Exception: An existing connection was forcibly closed by the remote host HResult: -2147467259
I’m using Realm 3.3.0 and xUnit 2.4.1
I’ve tried downgrading to Realm 2.2.0, and it didn’t work either.
The solution to this problem was found in this Github post
The piece of code from that helped me to solve the issue
Realm GetInstanceWithoutCapturingContext(RealmConfiguration config)
{
var context = SynchronizationContext.Current;
SynchronizationContext.SetSynchronizationContext(null);
Realm realm = null;
try
{
realm = Realm.GetInstance(config);
}
finally
{
SynchronizationContext.SetSynchronizationContext(context);
}
return realm;
}
Though it took a while for me to apply this to my solution.
First and foremost, instead of just setting the context to null I am using Nito.AsyncEx.AsyncContext. Because otherwise automatic changes will not be propagated through threads, as realm needs a non-null SynchronizationContext for that feature to work. So, in my case the method looks something like this
public class MockRealmFactory : IRealmFactory
{
private readonly SynchronizationContext _synchronizationContext;
private readonly string _defaultDatabaseId;
public MockRealmFactory()
{
_synchronizationContext = new AsyncContext().SynchronizationContext;
_defaultDatabaseId = Guid.NewGuid().ToString();
}
public Realm GetRealmWithPath(string realmDbPath)
{
var context = SynchronizationContext.Current;
SynchronizationContext.SetSynchronizationContext(_synchronizationContext);
Realm realm;
try
{
realm = Realm.GetInstance(new InMemoryConfiguration(realmDbPath));
}
finally
{
SynchronizationContext.SetSynchronizationContext(context);
}
return realm;
}
}
Further, this fixed a lot of failing unit tests. But I was still receiving that same exception - Realm accessed from incorrect thread. And I had no clue why, cause everything was set correctly. Then I found that the tests that were failing were related to methods where I was using async realm api, in particular realm.WriteAsync. After some more digging I found the following lines in the realm documentation.
It is not a problem if you have set SynchronisationContext.Current but
it will cause WriteAsync to dispatch again on the thread pool, which
may create another worker thread. So, if you are using Current in your
threads, consider calling just Write instead of WriteAsync.
In my code there was no direct need of using the async API. I removed and replaced with sync Write and all the tests became green again! I guess if I find myself in a situation that I do need to use the async API because of some kind of bulk insertions, I'd either mock that specific API, or replace with my own background thread using Task.Run instead of using Realm's version.

Hangfire and ASP.NET MVC

I'm currently using Hangfire in an ASP.NET MVC 5 project, which uses Ninject to use the same Context in RequestScope.
In Hangfire dashboard, I get random errors like:
System.Data.Entity.Core.EntityException: An error occurred while starting a transaction on the provider connection. See the inner exception for details. ---> System.Data.SqlClient.SqlException: New transaction is not allowed because there are other threads running in the session.
How can I make Entity, ASP.NET and Hangfire work without getting all those transaction errors?
I bet those errors can happen on the other side (in web).
We also encountered some issues like this with Hangfire along side Ninject. So we actually create a separate kernel for Hangfire, where everything is bound in thread scope. Something like this:
public class NinjectHangfire
{
public static IKernel CreateKernelForHangfire()
{
var kernel = new StandardKernel(/*modules*/);
try
{
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel).InThreadScope();
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>().InThreadScope();
//other bindings
}
catch
{
kernel.Dispose();
throw;
}
}
}
And then in Startup:
GlobalConfiguration.Configuration.UseNinjectActivator(NinjectHangfire.CreateKernelForHangfire());

Structure Map violates the constraint of type parameter 'CONCRETETYPE'

I have a web application developed in ASP.NET 2010. I have used the Dependency Injection with StructureMap in ASP.NET MVC. I'm trying to get started with Structure Map. I'm using
I've built a simple boot strapper, but when I run the website I get the following error:
StructureMap.Configuration.DSL.Expressions.CreatePluginFamilyExpression`1[System.Web.Mvc.IActionInvoker].Use:
type argument
'TestWebsite.Web.Controllers.Factories.InjectingActionInvoker'
violates the constraint of type parameter 'CONCRETETYPE'.
Code Block:
public static void ConfigureStructureMap()
{
ObjectFactory.Initialize(x =>
{
//registry per assembly recommended
x.AddRegistry<WebRegistry>();
x.AddRegistry<ServiceRegistry>();
x.AddRegistry<SHARE.Data.DataRegistry>();
});
//if a class needs configuring on load then this is done here. Inherit from IStartUpTask
ObjectFactory.GetAllInstances<IStartUpTask>()
.Where(x => x.IsEnabled).ToList()
.ForEach(t => t.Configure());
//This checks all is well. Not ideal to do in application_start though cause of calls to request object....
//ObjectFactory.AssertConfigurationIsValid();
}
public class WebRegistry : Registry
{
public WebRegistry()
{
For<IFormsAuthentication> ().Use<FormsAuthenticationService>();
For<IAuthentication>().Use<BasicMembership>();
Scan(x =>
{
x.AssemblyContainingType<IStartUpTask>();
x.AddAllTypesOf<IStartUpTask>();
x.WithDefaultConventions();
});
For<IActionInvoker>().Use<InjectingActionInvoker>();
SetAllProperties(c =>
{
c.OfType<IActionInvoker>();
c.WithAnyTypeFromNamespaceContainingType<UserService>(); //our services
c.WithAnyTypeFromNamespaceContainingType<AdminCookies>(); //cookie services
});
}
Could anyone please suggest on this issue. how it could be resolved? I am really getting troubled with it and need to resolve it asap. Any help would be greatly appreciated.
Thanks
Deepak
I do the following changes to run:
Remove the reference of MVC 3.0 DLL from website
Add the reference of MVC 2.0 DLL in website
Run the project and its working fine

SDL Tridion 2009: Creating components through TOM API (via Interop) fails

Am facing a problem, while creating components through TOM API using .NET/COM Interop.
Actual Issue:
I have 550 components to be created through custom page. I am able to create between 400 - 470 components but after that it is getting failed and through an error message saying that
Error: Thread was being aborted.
Any idea / suggestion, why it is getting failed?
OR
Is there any restriction on Tridion 2009?
UPDATE 1:
As per #user978511 request, below is error on Application event log:-
Event code: 3001
Event message: The request has been aborted.
...
...
Process information:
Process ID: 1016
Process name: w3wp.exe
Account name: NT AUTHORITY\NETWORK SERVICE
Exception information:
Exception type: HttpException
Exception message: Request timed out.
...
...
...
UPDATE 2:
#Chris: This is my common function, which is called in a loop by passing list of params. Here am using Interop dll's.
public static bool CreateFareComponent(.... list of params ...)
{
TDSE mTDSE = null;
Folder mFolder = null;
Component mComponent = null;
bool flag = false;
try
{
mTDSE = TDSEInitialize();
mComponent = (Component)mTDSE.GetNewObject(ItemType.ItemTypeComponent, folderID, null);
mComponent.Schema = (Schema)mTDSE.GetObject(constants.SCHEMA_ID, EnumOpenMode.OpenModeView, null, XMLReadFilter.XMLReadAll);
mComponent.Title = compTitle;
...
...
...
...
mComponent.Save(true);
flag = true;
}
catch (Exception ex)
{
CustomLogger.Error(String.Format("Logged User: {0} \r\n Error: {1}", GetRemoteUser(), ex.Message));
}
return flag;
}
Thanks in advance.
Sounds like a timeout, most likely in IIS which is hosting your custom page.
Are you creating them all in one synchronous request? Because that is indeed likely to time out.
You could instead create them in batches - or make sure your operations are done asynchronously and then polling the status regularly.
The easiest would just be to only create say 10 Components in one request, wait for it to finish, and then create another 10 (perhaps with a nice progress bar? :))
How you call TDSE object. I would like to mention here "Marshal.ReleaseComObject" procedure. Without releasing COMs objects can lead to enormous memory leaks.
Here is code for component creating:
private Component NewComponent(string componentName, string publicationID, string parentID, string schemaID)
{
Publication publication = (Publication)mTdse.GetObject(publicationID, EnumOpenMode.OpenModeView, null, XMLReadFilter.XMLReadContext);
Folder folder = (Folder)mTdse.GetObject(parentID, EnumOpenMode.OpenModeView, null, XMLReadFilter.XMLReadContext);
Schema schema = (Schema)mTdse.GetObject(schemaID, EnumOpenMode.OpenModeView, publicationID, XMLReadFilter.XMLReadContext);
Component component = (Component)mTdse.GetNewObject(ItemType.ItemTypeComponent, folder, publication);
component.Title = componentName;
component.Schema = schema;
return component;
}
After that please not forget to release mTdse ( in my case it is previously created TDSE object). Disposing "Components" object can be useful also after finish working with them.
For large Tridion batch operations I always use a Console Application and run it directly on the server.
Use Console.WriteLine to write to the output window and Console.ReadLine as the last line of code in the app (so the window stays open). I also use Log4Net as the logger.
This is by far the best approach if you have access to a remote session on the server - or can ask an admin to run it for you and give you access to the log folder via a network share.
As per #chris suggestions and part of immediate fix I have changed my web.config execution time out to 8000 seconds.
<httpRuntime executionTimeout="8000"/>
With this change, custom page is able to handle as of now.
Any more best suggestion, please post it.

Silverlight error while calling a service

I am trying to call a service from a silverlight application, but I am getting the following error.
Uncaught Error: Unhandled Error in Silverlight Application An exception occurred during the operation, making the result invalid. Check InnerException for exception details.
This works fine locally. I don't know if it make any sense, but locally if I add the url of the webservice on a browser, I am getting the details page of the service. In the other hand, on production server, it prompts me to download it.
Does anyone know something about this?
Thanks
public MainPage() {
InitializeComponent();
Loaded += new System.Windows.RoutedEventHandler(MainPage_Loaded);
}
private void MainPage_Loaded(object sender, System.Windows.RoutedEventArgs e) {
var newsFeedWcfClient = new NewsFeedWCFClient();
newsFeedWcfClient.GetNewsFeedItemsCompleted += newsFeedWcfClient_GetNewsFeedItemsCompleted;
newsFeedWcfClient.GetNewsFeedItemsAsync();
}
void newsFeedWcfClient_GetNewsFeedItemsCompleted(object sender, GetNewsFeedItemsCompletedEventArgs e) {
var source = (IList<NewsFeed>)e.Result;
IList<CustomNewsFeed> customNewsFeeds = new List<CustomNewsFeed>();
foreach (var item in source) {
customNewsFeeds.Add(new CustomNewsFeed() {
ProductID = item.Products.ProductID,
ProductTitle = item.Products.Title,
Status = item.Text,
Thumb = string.Format("{0}/{1}", item.Products.Product_Photos.Select(pp => pp.PhotoPath).FirstOrDefault(), item.Products.Product_Photos.Select(pp => pp.PhotoName).FirstOrDefault()),
UserID = item.User.Id,
UserName = item.User.Username
});
}
NewsFeedLB.ItemsSource = customNewsFeeds;
}
The fact that on the production server it "prompts you to download" would suggest that the production web server doesn't know what to do with your .svc or .asmx file. It is treating it like a normal file (.txt, .pdf etc).
Have you got all of the required items installed in production. For instance, you need the correct .NET runtime to be installed. Also, ASP.NET needs to be installed and then enabled.
To determine exactly what is happening I would recommend installing Fiddler and using it to trace what is happening when the Silverlight app calls the server. I have found this approach to be invaluable when troubleshooting Silverlight to Web Service communication problems.

Resources