Passing .FindOne() result to variable for gridView - C# .net - c#

I am using a directory search in a C# .NEt web page code behind. I do not know how to have the result added to the text of a cell. The results that are shown in column is the text "System.DirectoryServices.SearchResult". I supect that I am not passing the attribute correctly when I add the result to string.
String Name = userName;
DirectorySearcher ds = new DirectorySearcher();
ds.Filter = "samaccountname=" + Name;
ds.PropertiesToLoad.Add("userAccountControl");
SearchResult sr = ds.FindOne();
e.Row.Cells[5].Text = sr.ToString();
As you can see, I am passing sr.ToString() to the cell. This seems to be incorrect but I do not know how else to pass the result to a variable that I can then convert to string. I evne tried this:
var result1 = sr;
string result2 = result1.ToString();
e.Row.Cells[5].Text = result2;

From the msdn site on SearchResult. It looks like you want to set it to sr.Path? There is no overload for ToString() so it's just going to return the default for the object.

In the SearchResult - try something like sr["userAccountControl"].ToString(). The search result object is just an object. You have to tell what property to load out of it's collection. You can check PropertyNames property to see what's in the result object. Check out: http://msdn.microsoft.com/en-us/library/system.directoryservices.resultpropertycollection.aspx
for a reference of the object you are working with.

Related

How set OrderBy on GroupedEnumerable

My result set is not sorting. How do I set up OrderBy for type System.Linq.GroupedEnumerable
I've converted an application from Core 1.1 to 2.2. Everything ported over fine except one piece of logic that:
1) takes a response from a service call maps it to a GroupedEnumerable
2) takes the grouped set and passes it to a function that maps it to an object of type System.Linq.Enumerable.SelectEnumerableIterator.
The resulting object is properly populated but not sorted. I have tried the order by in the function parameter call and as a separate process afterwards.
//response = {myService.myClient.SearchNominationsResponse}
//groupedSet = {System.Linq.GroupedEnumerable<ServiceClients.myClient.NominationObject, long>}
//result = {System.Linq.Enumerable.SelectEnumerableIterator<System.Linq.IGrouping<long, ServiceClients.myClient.NominationObject>, app.ViewModels.EvaluationSummary>}
public IEnumerable<EvaluationSummary> GetEvaluationSummaries(string sortBy, string sortOrder, Filter filter = null)
{
var request = Mapper.MapSearchNominationRequest(filter);
request.IsDetailed = false;
var response = myService.SearchNominationsAsync(request).GetAwaiter().GetResult();
var groupedSet = response.mySet.GroupBy(n => n.SetId);
// I get a proper result but it is not sorted
var result = groupedSet.Select(
g => Mapper.MapEvaluationSummary(
g.OrderBy(g2 => sortBy + " " + sortOrder)
.Last()));
// Still not sorting
result = result.OrderBy(r => sortBy + sortOrder);
return result;
}
public EvaluationSummary MapEvaluationSummary(SetObject setIn)
{
var eval = new EvaluationSummary
{
setDate = setIn.Date,
setId = setIn.Id,
setTypeId = setIn.TypeId,
setTypeDescription = setIn.TypeDescription,
setStatusId = setIn.StatusId,
setStatusDescription = setIn.StatusDescription,
setBy = setIn.Manager,
setEmployee = setIn.employee
};
}
So in my view I have columns that list Date, Id, setEmployee. I can click on these values to issue a sort pattern and I can see that the sortBy and sortOrder variables are being passed in with proper values but the sorting is not happening.
I expect 'William' to appear before 'Bill' and then Bill to appear before 'William' when toggling the employee column header in my view.
Based off of the previous answers, I'm still not sure if I can substitute a property name in the LINQ with a variable. To fix my problem and move on I've implemented JS logic to sort my table headers. We had a custom JS that we use to format tables in our apps but it seems the sort functionality never worked. Anyway not an answer to my question but this is how I solved the problem:
Logic can be found at:
http://www.kryogenix.org/code/browser/sorttable/
-HaYen

How execute/run code from string variable at runtime

I am trying to execute code that's in a string variable to get an item from a dictionary
I have tried using CSharpCodeProvider like this:
var text = "IconDescription";
text = "\"" + text + "\"";
var field = "Outcome[" + text + "].Value";
field = "\"" + field + "\"";
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
ICodeCompiler icc = codeProvider.CreateCompiler()
parameters.GenerateExecutable = true;
CompilerResults results = icc.CompileAssemblyFromSource(parameters, field)
var dataTest = JsonConvert.DeserializeObject<DictionaryOutcome.Rootobject>(jsonText);
var t = new List<Outcome>();
var defaultOutcome = dataTest.Response.Outcome.KeyValueOfstringOutcomepQnxSKQu.Select(item => new Outcome
{
DataType = item.Value.DataType,
Value = item.Value.Value1,
Field = item.Key
}).ToList();
defaultOutcome.ToList().ForEach(item =>
{
t.Add(item);
});
the field variable's value is Outcome["IconDescription"].Value, and I want to execute this code to get the value from the Outcome dictionary, using the "IconDescription" Key, and get the value.
Is this possible?
I have tried the following:
var scriptOptions = ScriptOptions.Default
.WithReferences(typeof(Dictionary<string, Outcome>).FullName)
.WithImports("Outcome");
var scripts = CSharpScript.Create<object>(field, scriptOptions);
var resultsx = scripts.RunAsync(null, CancellationToken.None).Result;
And I am getting this error:
error CS0246: The type or namespace name 'Outcome' could not be found (are you missing a using directive or an assembly reference?)
I am struggling to even guess what you are trying to do, but as a starter, consider what you are actually doing by trying to compile that string you are constructing.
Outcome["SomeValue"].Value is not even close to being valid C# code:
it has no scope
it has no entry point
it imports no namespaces
it isn't terminated with a ;
the symbol Outcome is not defined
You're compiling this into an executable, so I don't see how it could have any knowledge of the list of results brought back from deserializing the JSON content, where you haven't specified where you're getting this from.
You haven't specified any evidence that explains why you need such an elaborate solution to merely extract some values from JSON, so a straightforward solution might be to use the built-in features of Newtonsoft.Json:
dataTest[0] selects the first element in the array, when the json object is an array;
dataTest[0]["Outcome"] selects the property Outcome of the first object, which may itself be an object
dataTest[0]["Outcome"]["Value"] selects the property Value of Outcome
All of the string indexes here can be known only at runtime and held in variables. I don't see why you need to do any scripting at all to do this.

Get "Home Directory" attribute from active directory

I'm trying to get Home Directory attribute value from active directory..
I used the following code:
public static void GetExchangeServerByWwidLdap(string wwid)
{
var exchange = string.Empty;
using (var ds = new DirectorySearcher())
{
ds.SearchRoot = new DirectoryEntry("GC:something");
ds.SearchScope = SearchScope.Subtree;
//construct search filter
string filter = "(&(objectclass=user)(objectcategory=person)";
filter += "(employeeid=" + wwid + "))";
ds.Filter = filter;
string[] requiredProperties = new string[] { "homeDirectory", "homemta" };
foreach (String property in requiredProperties)
ds.PropertiesToLoad.Add(property);
SearchResult result = ds.FindOne();
}
}
When I check result object data, I'm seeing only 2 values: "homemta" and "adspath".
Where is the "homeDirectory" value?
I entered AD website and searched the same values for same users - through the website I can see the all the data I searched for so I assuming that I have code issue somewhere.
What am I doing wrong?
You're trying to retrieve homeDirectory from global catalog.
It’s not there.
You can e.g. bind to the user by ADsPath property (i.e. “LDAP://…” string), then query the homeDirectory attribute of that user.
Or, if you only have a single domain, you can search within that domain instead of searching the GC. In this case you'll be able to retrieve all the properties you want.

In C# is there anyway to read a property directly (versus having to loop through PropertyNames)

I have the following code:
// Create a DirectorySearcher object.
DirectorySearcher mySearcher = new DirectorySearcher(entry);
mySearcher.SearchScope = SearchScope.Base;
// Use the FindOne method to find the user object.
SearchResult resEnt = mySearcher.FindOne();
foreach(string propKey in resEnt.Properties.PropertyNames)
{
foreach (var property in resEnt.Properties[propKey])
{
Console.WriteLine("{0}:{1}", propKey, property.ToString());
}
}
This works fine but I only need to get a single property called "mail". Is there anyway i can just read a single property without having to loop. I am looking for something like this:
var emailAddress = resEnt.Properties["mail"];
You probably want:
string emailAddress = (string)resEnt.Properties["mail"][0];
Note that you might want to do some checking here to make sure there is a valid "mail" property:
var mailProps = resEnt.Properties["mail"];
string emailAddress = mailProps.Count > 0 ? (string)mailProps[0] : string.Empty;
Updated to work
The example you have will return a single Property. The problem is that the return is a Collection. I recommend doing
// Or String if you know it's always a string
var mailCollection = resEnt.Properties["mail"].Cast<Object>();
var emailAddress = mailCollection.FirstOrDefault();
If you use FirstOrDefault it will return the first value or null. If you use Single or [0] you will have to perform a validation step before hand or catch the Exception that is thrown when no results are returned.
Use the cast operation in conjuntion with LINQ to get the first object.
var email = resEnt.Properties["mail"].Cast<object>.FirstOrDefault();

How to use LINQ to find if any Value in a ResultPropertyCollection contains a certain substring?

How to use LINQ to find if any Value in a ResultPropertyCollection contains a certain substring?
Background: After a renaming of my employer firm, I want to check whether all users have a proper new email alias, which are listed in Active Directory as proxyAddresses.
Directly accessing single values inside the ResultPropertyCollection works just fine, like so:
DirectorySearcher mySearcher = new DirectorySearcher(mySearchRoot, myFilter, myPropertiesList);
myResults = mySearcher.FindAll();
var query = from SearchResult myResult in myResults
where (myResult.Properties["proxyAddresses"][0].ToString().Contains ("WeNeedThis.com"))
select myResult;
But I fail at searching over all values inside the collection. I cant seem to find out what the proper type for the range variable is:
where (from WhatType? myAddress in myResult.Properties["proxyAddresses"]
where (myAddress.Contains("WeNeedThis.com"))
select myAddress)
How can I set up the where clause so it finds any occurence of the search string in any Value of proxyAddresses?
Answer: Turns out this is the correct where clause:
where ( ( from String myAddress in myResult.Properties["proxyAddresses"]
where myAddress.Contains("WeNeedThis.com")
select myAddress).ToList().Count == 0)
There were two mistakes intertwined: The outer where clause needs a boolean result from the result of the inner select, which is achieved by .ToList().Count == 0.
The type of the range variable is indeed String = myResult.Properties["proxyAddresses"][0].GetType(), although the Collection has no direct String members. I misinterpreted the resulting compiler error.
The type you're looking for I think is ResultPropertyValueCollection.
But, can't you omit the type and use type inference?
from myAddress in myResult.Properties["proxyAddresses"]
Also instead of using IndexOf(str) > 0 as your predicate, you could use Contains(str).
The System.DirectoryServices.ResultPropertyCollection PropertyNames is from type Hashtable+Keycollection. I would cast it and check it if it exist, then get the value out of it:
System.DirectoryServices.DirectorySearcher mySearcher = new DirectorySearcher(mySearchRoot, myFilter, myPropertiesList);
System.DirectoryServices.SearchResultCollection myResults = mySearcher.FindAll();
foreach (System.DirectoryServices.SearchResult result in myResults)
{
var propertyNames = result.Properties.PropertyNames.Cast<String>().ToList<String>();
if (!propertyNames.Contains("proxyaddresses"))
{
// This property does not exist. Abort.
continue;
}
List<string> proxyAddresses = result.Properties["proxyaddresses"].Cast<String>().ToList();
// Do something with proxyAddresses
}
You're going to need to use something like this:
var query =
from myAddress in
(myResult.Properties["proxyAddresses"] as IEnumerable).OfType<string>()
where myAddress
.ToLowerInvariant()
.Contains("WeNeedThis.com".ToLowerInvariant())
select myAddress ;
Does this help?
This worked for me
DirectorySearcher mySearcher = new DirectorySearcher(mySearchRoot, myFilter, myPropertiesList);
myResults = mySearcher.FindAll();
var query = myResults.Where(res =>res.GetDirectoryEntry().Properties["proxyAddresses"].Cast<string>().Any(addr => addr.Contains("WeNeedThis.com")));

Categories