I currently working with AD and I fetch data from AD and store to file. Since I don't need some status code, I am interested only to check If user account is 512- Enable or 514 - Disable and convert to bool value. Here is my code
public static List<Korisnik> VratiKorisnike()
{
List<Korisnik> lstADUsers = new List<Korisnik>();
string sDomainName = "sasaos";
string DomainPath = "LDAP://" + sDomainName;
string constring = #"Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=DesignSaoOsig1; Integrated Security=True";
string Query = "SELECT * FROM tblZaposleni_AD";
DataTable table = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter(Query, constring);
adapter.Fill(table);
string txt = "";
string fileLoc = #"C:\output.txt";
foreach (DataRow row in table.Rows)
{
string line = "";
foreach (DataColumn column in table.Columns)
{
line += "," + row[column.ColumnName].ToString();
}
txt += line.Substring(1);
}
using (var sw = new StreamWriter(fileLoc))
{
sw.WriteLine(txt);
}
Console.WriteLine("Ok");
DirectoryEntry searchRoot = new DirectoryEntry(DomainPath);
DirectorySearcher search = new DirectorySearcher(searchRoot);
search.Filter = "(&(objectClass=user)(objectCategory=person))";
search.PropertiesToLoad.Add("samaccountname"); // Username
search.PropertiesToLoad.Add("displayname"); // display name
search.PropertiesToLoad.Add("userAccountControl"); // isEnabled
search.PropertiesToLoad.Add("pwdLastSet"); //passwordExpires
DataTable resultsTable = new DataTable();
resultsTable.Columns.Add("samaccountname");
resultsTable.Columns.Add("displayname");
resultsTable.Columns.Add("Neaktivan");
resultsTable.Columns.Add("dontexpirepassword");
SearchResult result;
SearchResultCollection resultCol = search.FindAll();
if (resultCol != null)
{
for (int counter = 0; counter < resultCol.Count; counter++)
{
string UserNameEmailString = string.Empty;
result = resultCol[counter];
if (result.Properties.Contains("samaccountname")
&& result.Properties.Contains("displayname"))
{
int userAccountControl = Convert.ToInt32(result.Properties["userAccountControl"][0]);
string samAccountName = Convert.ToString(result.Properties["samAccountName"][0]);
int isEnable;
int Dont_Expire_Password;
if (userAccountControl > 0)
{
isEnable = 0;
}
else
{
isEnable = 1;
}
if ((userAccountControl & 65536) != 0)
{
Dont_Expire_Password = 1;
}
else
{
Dont_Expire_Password = 0;
}
Korisnik korisnik = new Korisnik();
korisnik.Username = (result.Properties["samaccountname"][0]).ToString();
korisnik.DisplayName = result.Properties["displayname"][0].ToString();
korisnik.isEnabled = Convert.ToBoolean(result.Properties["userAccountControl"][0]);
DataRow dr = resultsTable.NewRow();
dr["samaccountname"] = korisnik.Username.ToString();
dr["displayname"] = korisnik.DisplayName.ToString();
dr["neaktivan"] = Math.Abs(isEnable);
dr["dontexpirepassword"] = Dont_Expire_Password;
resultsTable.Rows.Add(dr);
lstADUsers.Add(korisnik);
}
}
var json = JsonConvert.SerializeObject(resultCol, Formatting.Indented);
var res = json;
Console.WriteLine("Ispis uspjesno obavljen");
Console.ReadLine();
File.WriteAllText(fileLoc, json);
}
return lstADUsers;
}
Any idea how to resolve this issue I would be very thankfull
So fat what I try
if (userAccountControl == 512)
{
dr["neaktivan"] = "Account Enabled";
}
if (userAccountControl == 514)
{
dr["neaktivan"] = "Account Disabled";
}
Doesn't show in my output.txt any result
{
"Path": "LDAP://sarajevoosigura/CN=Aldin Smajović,OU=Sarajevo,OU=People,DC=sarajevoosiguranje,DC=ba",
"Properties": {
"displayname": [
"John Smith"
],
"useraccountcontrol": [
514
],
"samaccountname": [
"jsmith"
],
"adspath": [
"LDAP://test/CN=JohnSmith,OU=New York,OU=People,DC=sasa,DC=ba"
],
"pwdlastset": [
132295140030347373
]
}
},
Don't think about the numbers 512 or 514, since they aren't actually relevant to what you're trying to find. The userAccountControl attribute is a bit flag, meaning that each bit (0 or 1) in the binary value is a flag that means something (1 is on and 0 is off). The decimal representation of all those bits could be all kinds of values. For example, the decimal value could be 512 or 514 or even 65538 (if the account is disabled and has "don't expire password"). So ignore the decimal value.
The second bit is the flag for "disabled". If the second bit is 1, the account is disabled. That's what you want to find.
John's answer does work in finding that, but it's (slightly) overly complicated.
You're already doing a proper test for the "don't expire password" flag:
if ((userAccountControl & 65536) != 0)
65536 is 10000000000000000 in binary. So that if statement is saying "if the 17th bit is set". You just need to do exactly the same thing for the 2nd bit to figure out if it's disabled:
if (userAccountControl & 2 != 0)
{
isEnable = 1;
}
else
{
isEnable = 0;
}
You can read more about the "Logical AND operator &" here: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators#logical-and-operator-
Related
I have below json data I need to apply CAdES-BES Signature with Automatic JSON Canonicalization. Please find my json data below. Helpful link from https://www.example-code.com/Csharp/itida_egypt_cades_bes_json_canonicalization.asp. I follow the steps but still digital signature is not applying. Its returns normal json data.
[HttpGet]
[Route("api/invoiceLines/")]
public IHttpActionResult getEInvoiceLines()
{
Chilkat.Crypt2 crypt = new Chilkat.Crypt2();
crypt.VerboseLogging = true;
Chilkat.Cert cert = new Chilkat.Cert();
cert.VerboseLogging = true;
// Set the smart card PIN, which will be needed for signing.
cert.SmartCardPin = "1245345";
// There are many ways to load the certificate.
// This example was created for a customer using an ePass2003 USB token.
// Assuming the USB token is the only source of a hardware-based private key..
bool success = cert.LoadFromSmartcard(#"E"); //Is this Right way To load certificate ?
Chilkat.JsonObject cmsOptions = new Chilkat.JsonObject();
// Setting "DigestData" causes OID 1.2.840.113549.1.7.5 (digestData) to be used.
cmsOptions.UpdateBool("DigestData", true);
cmsOptions.UpdateBool("OmitAlgorithmIdNull", true);
// Indicate that we are passing normal JSON and we want Chilkat do automatically
// do the ITIDA JSON canonicalization:
cmsOptions.UpdateBool("CanonicalizeITIDA", true);
crypt.CmsOptions = cmsOptions.Emit();
// The CadesEnabled property applies to all methods that create CMS/PKCS7 signatures.
// To create a CAdES-BES signature, set this property equal to true.
crypt.CadesEnabled = true;
crypt.HashAlgorithm = "sha256";
Chilkat.JsonObject jsonSigningAttrs = new Chilkat.JsonObject();
jsonSigningAttrs.UpdateInt("contentType", 1);
jsonSigningAttrs.UpdateInt("signingTime", 1);
jsonSigningAttrs.UpdateInt("messageDigest", 1);
jsonSigningAttrs.UpdateInt("signingCertificateV2", 1);
crypt.SigningAttributes = jsonSigningAttrs.Emit();
// By default, all the certs in the chain of authentication are included in the signature.
// If desired, we can choose to only include the signing certificate:
crypt.IncludeCertChain = false;
EInvoiceModel.Example ds = new EInvoiceModel.Example();
//Start issuer details
ds.issuer = new EInvoiceModel.Issuer();
ds.issuer.type = "B";
ds.issuer.id = "113317713";
ds.issuer.name = "Issuer Company";
//Start issuer address details
ds.issuer.address = new EInvoiceModel.Address();
ds.issuer.address.branchID = "1";
ds.issuer.address.country = "EG";
ds.issuer.address.governate = "Cairo";
ds.issuer.address.regionCity = "Nasr City";
ds.issuer.address.street = "stree1";
ds.issuer.address.buildingNumber = "Bldg. 0";
ds.issuer.address.postalCode = "68030";
ds.issuer.address.floor = "1";
ds.issuer.address.room = "123";
ds.issuer.address.landmark = "7660 Melody Trail";
ds.issuer.address.additionalInformation = "beside Town Hall";
//Start Receiver details
ds.receiver = new EInvoiceModel.Receiver();
ds.receiver.type = "B";
ds.receiver.id = "3125617";
ds.receiver.name = "Receiver company";
//Start Receiver address datails
ds.receiver.address = new EInvoiceModel.AddressReceiver();
ds.receiver.address.country = "EG";
ds.receiver.address.governate = "Cairo";
ds.receiver.address.regionCity = "Nasr City";
ds.receiver.address.street = "stree1";
ds.receiver.address.buildingNumber = "Bldg. 0";
ds.receiver.address.postalCode = "68030";
ds.receiver.address.floor = "1";
ds.receiver.address.room = "123";
ds.receiver.address.landmark = "7660 Melody Trail";
ds.receiver.address.additionalInformation = "beside Town Hall";
//Document type & version
ds.documentType = "i";
ds.documentTypeVersion = "1.0";
DateTime d = new DateTime();
ds.dateTimeIssued = d; //Invoice date
ds.taxpayerActivityCode = "9478"; //needed info
ds.internalID = "WADIn1234"; //Internal Invoice number
ds.salesOrderReference = "So1234"; //So number //optional
ds.salesOrderDescription = "SO1234"; //So additional Info //optional
ds.proformaInvoiceNumber = "SoPro123"; //optional
//Invoiceline Start
ds.invoiceLines = new List<EInvoiceModel.InvoiceLine>
{
new EInvoiceModel.InvoiceLine
{
description = "Computer1",
itemType = "GPC",
itemCode = "10001774",
unitType = "EA",
quantity = 2,
internalCode = "IC0",
salesTotal = 23.99,
total = 2969.89,
valueDifference = 7.00,
totalTaxableFees = 817.42,
netTotal = 880.71,
itemsDiscount = 5.00,
unitValue = new EInvoiceModel.UnitValue
{
currencySold = "EUR",
amountEGP = 189.40,
amountSold = 10.00,
currencyExchangeRate = 18.94,
},
discount = new EInvoiceModel.Discount
{
rate = 7,
amount = 66.29
},
taxableItems = new List<EInvoiceModel.TaxableItem>
{
new EInvoiceModel.TaxableItem
{
taxType = "T1",
amount = 272.07,
subType = "T1",
rate = 12
}
}
}
}; //Invoice Lines End
//Items total Discount and Sales/NetAmount
ds.totalDiscountAmount = 76.29;
ds.totalSalesAmount = 1609.90;
ds.netAmount = 1533.61;
//Tax Total Start
ds.taxTotals = new List<EInvoiceModel.TaxTotal>
{
new EInvoiceModel.TaxTotal
{
taxType = "T1",
amount = 477.54,
}
};//Tax Total End
//Total Sales Amount & discounts
ds.totalAmount = 5191.50;
ds.extraDiscountAmount = 5.00;
ds.totalItemsDiscountAmount = 14.00;
string strResultJson = JsonConvert.SerializeObject(ds);
//System.IO.File.WriteAllText(#"C:\inetpub\wwwroot\path.json", strResultJson);
// File.WriteAllText(#"ds.json", strResultJson);
// string jsonToSign = "{ ... }";
string jsonToSign = strResultJson;
// Create the CAdES-BES signature.
crypt.EncodingMode = "base64";
// Make sure we sign the utf-8 byte representation of the JSON string
crypt.Charset = "utf-8";
string sigBase64 = crypt.SignStringENC(jsonToSign);
// return Ok(ds);
return Ok(sigBase64);
}
public static string SerializeObject2(object obj, int indent = 0)
{
var sb = new StringBuilder();
if (obj != null)
{
string indentString = new string(' ', indent);
if (obj is string || obj.IsNumber())
{
sb.Append($"\"{obj}\"");
}
else if (obj.GetType().BaseType == typeof(Enum))
{
sb.Append($"\"{obj.ToString()}\"");
}
else if (obj is Array)
{
var elems = obj as IList;
sb.Append($"{indentString}- [{elems.Count}] :\n");
for (int i = 0; i < elems.Count; i++)
{
sb.Append(SerializeObject2(elems[i], indent + 4));
}
}
else
{
Type objType = (obj).GetType();
PropertyInfo[] props = objType.GetProperties();
foreach (PropertyInfo prop in props)
{
if (prop.GetIndexParameters().Length == 0)
{
object propValue = prop.GetValue(obj);
var elems = propValue as IList;
if (elems != null)
{
sb.Append($"\"{prop.Name.ToUpper()}\"");
foreach (var item in elems)
{
sb.Append($"\"{prop.Name.ToUpper()}\"");
sb.Append(SerializeObject2(item, indent + 4));
}
}
else
{
if (Assembly.GetExecutingAssembly().DefinedTypes.Select(p => p.Assembly).ToList().Contains(prop.PropertyType.Assembly))
{
sb.Append($"\"{prop.Name.ToUpper()}\"");
sb.Append(SerializeObject2(propValue, indent + 4));
}
else
{
sb.Append($"\"{prop.Name.ToUpper()}\"\"{propValue}\"");
}
}
}
else if (objType.GetProperty("Item") != null)
{
int count = -1;
if (objType.GetProperty("Count") != null &&
objType.GetProperty("Count").PropertyType == typeof(int))
{
count = (int)objType.GetProperty("Count").GetValue(obj, null);
}
for (int i = 0; i < count; i++)
{
object val = prop.GetValue(obj, new object[] { i });
sb.Append(SerializeObject2(val, indent + 4));
}
}
}
}
}
return sb.ToString();
}
I need to upload a file and place it in the same row inside Access of the name that´s been typed by the user.
tried to use a different query:
Recordset rs = db.OpenRecordset("SELECT * FROM tbl_reg WHERE nome_user = #nome ", RecordsetTypeEnum.dbOpenDynaset, 0, LockTypeEnum.dbOptimistic);
Also tried removing the WHERE, and yes it does select the whole table, whenever i place the WHERE, I catch a "Too few parameters. Expected 1."
if (FileUpload1.HasFile)
{
try
{
string fileExtension = Path.GetExtension(FileUpload1.FileName);
if (fileExtension.ToLower() == ".doc" || fileExtension.ToLower() == ".docx" || fileExtension.ToLower() == ".pdf")
{
if (FileUpload1.PostedFile.ContentLength > 1024000)
{
StatusLabel.ForeColor = System.Drawing.Color.Red;
StatusLabel.Text = "Status do upload: O arquivo deve ter menos de 1000 kb!";
}
else
{
string conexaoAccess = ConfigurationManager.ConnectionStrings["conexaoAccess"].ToString();
using (OleDbConnection conexaodb = new OleDbConnection(conexaoAccess))
{
conexaodb.Open();
OleDbCommand cmd = new OleDbCommand("UPDATE tbl_reg SET titulo_trab = #trab WHERE nome_user = #nome", conexaodb);
var parTrab = cmd.CreateParameter();
parTrab.ParameterName = "#trab";
parTrab.DbType = DbType.String;
parTrab.Value = mdl.trab;
cmd.Parameters.Add(parTrab);
var parNome = cmd.CreateParameter();
parNome.ParameterName = "#nome";
parNome.DbType = DbType.String;
parNome.Value = mdl.nome;
cmd.Parameters.Add(parNome);
int rowsChanged = cmd.ExecuteNonQuery();
//arquivo
try
{
Random r = new Random();
int n = r.Next();
DBEngine dbe = new DBEngine();
Database db = dbe.OpenDatabase("C:\\Users\\Willian\\Documents\\dbPIM\\dbpim.accdb", false, false, "");
Recordset rs = db.OpenRecordset("SELECT * FROM tbl_reg WHERE nome_user = #nome ", RecordsetTypeEnum.dbOpenDynaset, 0, LockTypeEnum.dbOptimistic);
rs.MoveFirst();
rs.Edit();
Recordset2 rs2 = (Recordset2)rs.Fields["Campo1"].Value;
rs2.AddNew();
Field2 f2 = (Field2)rs2.Fields["campo"];
f2.LoadFromFile("C:\\temp\\test" + n + fileExtension.ToLower());
rs2._30_Update();
rs2.Close();
rs._30_Update();
rs.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Expected output: The file gets attached to the .mdb if the name typed matches any name in a row.
The first query is executing just fine, but the openRecordSet one isn´t, at all.
I am searching Active Directory for users in a specific OU. I am only getting the users that have logged on in the last 30 days.
My search filter Query is:
string query = "(&(objectCategory=person)(objectClass=user)((lastLogon<=" + new DateTime(DateTime.Now.AddDays(-30).Ticks) + ")(mail=*))";
I get search filter is invalid
I have used:
string query = "(&(objectCategory=person)(objectClass=user)((lastLogon=*)(mail=*))";
With no error
I have modified the last logon as follows:
(lastLogon<=1)
I am calling a method that does this
public static DataTable GetADusers() {
try {
string ou = "OU";
using(PrincipalContext ctx = new PrincipalContext(ContextType.Domain, Environment.UserDomainName, ou)) {
UserPrincipal user = new UserPrincipal(ctx);
using(PrincipalSearcher ps = new PrincipalSearcher(user)) {
DataTable results = new DataTable();
results.Columns.Add("DisplayName ");
results.Columns.Add("FirstName");
results.Columns.Add("Initial");
results.Columns.Add("LastName");
results.Columns.Add("mail");
results.Columns.Add("SamAccountName");
results.Columns.Add("DistinguishedName");
results.Columns.Add("lastLogon");
int count = 0;
int ctNull = 0;
foreach(Principal p in ps.FindAll()) {
UserPrincipal u = p as UserPrincipal;
if (u != null) {
DirectoryEntry entry = (DirectoryEntry) p.GetUnderlyingObject();
DirectorySearcher search = new DirectorySearcher(entry);
string query = "(&(objectCategory=person)(objectClass=user)((lastLogon<=" + new DateTime(DateTime.Now.AddDays( - 30).Ticks) + ")(mail=*))";
search.Filter = query;
search.PropertiesToLoad.Add("DisplayName");
search.PropertiesToLoad.Add("GivenName");
search.PropertiesToLoad.Add("Initials");
search.PropertiesToLoad.Add("sn");
search.PropertiesToLoad.Add("mail");
search.PropertiesToLoad.Add("SamAccountName");
search.PropertiesToLoad.Add("DistinguishedName");
search.PropertiesToLoad.Add("lastLogon");
SearchResultCollection mySearchResultColl = search.FindAll();
foreach(SearchResult sr in mySearchResultColl) {
DataRow dr = results.NewRow();
DirectoryEntry de = sr.GetDirectoryEntry();
dr["EmployeeID"] = de.Properties["EmployeeID"].Value;
dr["DisplayName "] = de.Properties["DisplayName"].Value;
dr["FirstName"] = de.Properties["GivenName"].Value;
dr["Initial"] = de.Properties["Initials"].Value;
dr["LastName"] = de.Properties["sn"].Value;
dr["mail"] = de.Properties["mail"].Value;
dr["SamAccountName"] = de.Properties["SamAccountName"].Value;
dr["DistinguishedName"] = de.Properties["DistinguishedName"].Value;
//prepare for last logon
if (de.Properties["lastLogon"] != null && de.Properties["lastLogon"].Count > 0) {
Int64 lastLogonThisServer = new Int64();
IADsLargeInteger lgInt = (IADsLargeInteger) de.Properties["lastLogon"].Value;
lastLogonThisServer = ((long) lgInt.HighPart << 32) + lgInt.LowPart;
dr["lastLogon"] = DateTime.FromFileTime(lastLogonThisServer).ToString();
}
else {
dr["lastLogon"] = DateTime.MinValue.ToString();
ctNull++;
}
results.Rows.Add(dr);
count++;
}
}
}
Console.WriteLine(count);
Console.WriteLine("Null");
Console.WriteLine(ctNull);
return results;
}
}
}
catch(NullReferenceException ex) {
Console.WriteLine("data error" + ex);
DataTable dt = new DataTable();
return dt;
}
}
The above function works well!
There must be a way to check if the last logon is over 30 days old. I would appreciate any help. Thank You!
The answer below is correct thanks
I had to add the following code to place the data into the database:
if (de.Properties["LastLogonTimestamp"] != null && de.Properties["LastLogonTimestamp"].Count > 0)
{
Int64 lastLogonDateThisServer = new Int64();
IADsLargeInteger lgInt = (IADsLargeInteger)de.Properties["LastLogonTimestamp"].Value;
lastLogonDateThisServer = ((long)lgInt.HighPart << 32) + lgInt.LowPart;
dr["LastLogonTimestamp"] = DateTime.FromFileTime(lastLogonDateThisServer).ToString();
}
else
{
dr["LastLogonTimestamp"] = DateTime.MinValue.ToString();
ctNull++;
}
I placed it below the lastLogon
For the query filter: I had to reverse the < to get the data from now to that 30 day mark.
string query = "(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2)(!userAccountControl:1.2.840.113556.1.4.803:=65536)(userAccountControl:1.2.840.113556.1.4.803:=262144)(userPrincipalName=1*#mil)(lastlogon>=" + DateTime.Now.AddDays(-90).ToFileTime() + ")(lastLogonTimestamp>=" + DateTime.Now.AddDays(-90).ToFileTime() + ")(mail=*))";
In your query, you have two parentheses in front of lastLogon when you don't need them:
((lastLogon<=...
That's why you're getting the "search filter is invalid" error. That should be:
(lastLogon<=...
But you are also calculating the value wrong. You have this:
new DateTime(DateTime.Now.AddDays( - 30).Ticks)
But lastLogon does not use ticks.
Later on in your code, you are using FromFileTime to read back the lastLogon. Likewise, you can use ToFileTime to convert a date to the format you can use in the query. Like this:
DateTime.Now.AddDays(-30).ToFileTime()
But keep in mind that lastLogon does not replicate - it is only accurate on the last domain controller that the user authenticated against. So if your domain has more than one domain controller, you won't get an accurate value for most accounts.
The lastLogonTimestamp attribute was created for just this reason. It replicates at least every 2 weeks, so you know the value is accurate within 2 weeks. You can use the same format for that:
string query = "(&(objectCategory=person)(objectClass=user)(lastLogonTimestamp<="
+ DateTime.Now.AddDays(-30).ToFileTime() + ")(mail=*))";
You can read more about the lastLogonTimestamp attribute here: https://blogs.technet.microsoft.com/askds/2009/04/15/the-lastlogontimestamp-attribute-what-it-was-designed-for-and-how-it-works/
I'm building an app for Android 4.0 (Ice Cream Sandwich) and higher, and would like to get the device owner's user profile info such as:
DisplayName, Email, Phone, Job Title, Company, Office Location, Website and Url
I've tried different methods from different Stackoverflow posts that I read, including going to the phone's accounts to querying the user profile (ContactsContract.Profile.ContentUri). No dice. I've checked the permissions for ReadOwnerData and ReadProfile.
Right now I'm querying the Contacts with this code, but the managed query is returning with a count of 0.
var c = act.ManagedQuery (ContactsContract.Profile.ContentUri, null, null, null, null);
int count = c.Count;
string[] columnNames = c.GetColumnNames();
bool b = c.MoveToFirst();
int position = c.Position;
if (position == 0) {
do {
for (int j = 0; j < columnNames.Length; j++) {
string columnName = columnNames[j];
try {
string columnValue = c.GetString(c.GetColumnIndex(columnName));
} catch {}
if (c.GetString(c.GetColumnIndex("is_user_profile")) == "1") {
if (c.GetString(c.GetColumnIndex("has_email")) == "1") {
//var cEmail = ManagedQuery (ContactsContract.Data.ContentUri, null, ContactsContract.Data.InterfaceConsts.HasPhoneNumber + "!=0 AND (" + ContactsContract.Data.InterfaceConsts.Mimetype + "=? OR " + ContactsContract.Data.InterfaceConsts.Mimetype + "=?)", new String[]{ ContactsContract.CommonDataKinds.Email.ContentItemType, ContactsContract.CommonDataKinds.Phone.ContentItemType, ContactsContract.Contacts.InterfaceConsts.Id }, null);
var cEmail = act.ManagedQuery (ContactsContract.CommonDataKinds.Email.ContentUri, null, ContactsContract.CommonDataKinds.Email.InterfaceConsts.Type + " = ?", new String[]{ c.GetString(c.GetColumnIndex(BaseColumns.Id)) }, null);
string[] columnNamesEmail = cEmail.GetColumnNames();
if (cEmail.Count > 0) {
cEmail.MoveToFirst();
do {
sEmail = cEmail.GetString(cEmail.GetColumnIndex(ContactsContract.CommonDataKinds.Email.InterfaceConsts.Type));
//sEmail = cEmail.GetString(cEmail.GetColumnIndex(ContactsContract.CommonDataKinds.Email.InterfaceConsts.Data));
//sEmail = cEmail.GetString(cEmail.GetColumnIndex(ContactsContract.CommonDataKinds.Email.InterfaceConsts.ContactId));
} while (cEmail.MoveToNext());
}
cEmail.Close();
}
if (c.GetString(c.GetColumnIndex("has_phone_number")) == "1") {
var cPhone = act.ManagedQuery (ContactsContract.CommonDataKinds.Phone.ContentUri, null, ContactsContract.CommonDataKinds.Phone.InterfaceConsts.ContactId + " = ?", new String[]{ c.GetString(c.GetColumnIndex(BaseColumns.Id)) }, null);
string[] columnNamesPhone = cPhone.GetColumnNames();
if (cPhone.Count > 0) {
cPhone.MoveToFirst();
do {
sPhone = cPhone.GetString(cPhone.GetColumnIndex(ContactsContract.CommonDataKinds.Phone.InterfaceConsts.Type));
} while (cPhone.MoveToNext());
}
cPhone.Close();
}
}
}
} while (c.MoveToNext());
}
c.Close();
This part of the code returns with a count of 0:
if (cEmail.Count > 0) {
Can someone point out how I can rewrite this query?
var cEmail = act.ManagedQuery (ContactsContract.CommonDataKinds.Email.ContentUri, null, ContactsContract.CommonDataKinds.Email.InterfaceConsts.Type + " = ?", new String[]{ c.GetString(c.GetColumnIndex(BaseColumns.Id)) }, null);
Or should I go back to querying the user profile or accounts? Here's the code I was using for them:
Accounts:
Account[] accounts = AccountManager.Get (Context).GetAccounts ();
foreach (Account acc in accounts) {
--- can only get DisplayName and ID
}
User Profile:
var uri = ContactsContract.Profile.ContentUri;
string[] projection = {
ContactsContract.CommonDataKinds.StructuredName.DisplayName,
ContactsContract.CommonDataKinds.Email.Address,
ContactsContract.CommonDataKinds.Phone.Number,
ContactsContract.CommonDataKinds.Organization.Title,
ContactsContract.CommonDataKinds.Organization.Company,
ContactsContract.CommonDataKinds.Organization.OfficeLocation,
ContactsContract.CommonDataKinds.Website.Url };
var cursor = ManagedQuery (uri, projection, null, null, null);
if (cursor.MoveToFirst ()) {
do {
sDisplayName = cursor.GetString (cursor.GetColumnIndex (projection [0]));
sEmail = cursor.GetString (cursor.GetColumnIndex (projection [1]));
sPhone = cursor.GetString (cursor.GetColumnIndex (projection [2]));
sTitle = cursor.GetString (cursor.GetColumnIndex (projection [3]));
sCompany = cursor.GetString (cursor.GetColumnIndex (projection [4]));
sOfficeLocation = cursor.GetString (cursor.GetColumnIndex (projection [5]));
sWebsite = cursor.GetString (cursor.GetColumnIndex (projection [6]));
} while (cursor.MoveToNext());
}
what would be the best way to compare two data table. i populate two data table reading two different xml and now i need to compare and return the difference in terms of datatable.my compare logic was
private DataTable CompareDataTables(DataTable dtFirst, DataTable dtSecond)
{
int result = 0;
bool flag = false;
DataTable dtNoRows = new DataTable();
dtNoRows.Columns.Add("Result");
DataTable dtDiff = new DataTable();
dtDiff.Columns.Add("Field Name");
dtDiff.Columns.Add("Old Value");
dtDiff.Columns.Add("New Value");
DataRow dr = null;
if (dtFirst.Columns.Count == dtSecond.Columns.Count)
{
for (int i = 0; i <= dtFirst.Columns.Count - 1; i++)
{
try
{
DateTime.Parse(dtFirst.Rows[0][dtFirst.Columns[i].ColumnName.ToString()].ToString().Trim());
flag = true;
}
catch (Exception ex)
{
flag = false;
}
if (!flag)
{
if (dtFirst.Rows[0][dtFirst.Columns[i].ColumnName.ToString()].ToString().Trim().ToUpper() != dtSecond.Rows[0][dtSecond.Columns[i].ColumnName.ToString()].ToString().Trim().ToUpper())
{
dr = dtDiff.NewRow();
dr["Field Name"] = dtFirst.Columns[i].ColumnName.ToString();
dr["Old Value"] = dtFirst.Rows[0][dtFirst.Columns[i].ColumnName.ToString()].ToString().Trim();
dr["New Value"] = dtSecond.Rows[0][dtSecond.Columns[i].ColumnName.ToString()].ToString().Trim();
dtDiff.Rows.Add(dr);
}
}
else
{
result = DateTime.Compare(DateTime.Parse(dtFirst.Rows[0][dtFirst.Columns[i].ColumnName.ToString()].ToString()), DateTime.Parse(dtSecond.Rows[0][dtSecond.Columns[i].ColumnName.ToString()].ToString()));
if (result != 0)
{
dr = dtDiff.NewRow();
dr["Field Name"] = dtFirst.Columns[i].ColumnName.ToString();
dr["Old Value"] = DateTime.Parse(dtFirst.Rows[0][dtFirst.Columns[i].ColumnName.ToString()].ToString().Trim()).ToString("MM/dd/yyyy") + " - " + DateTime.Parse(dtFirst.Rows[0][dtFirst.Columns[i].ColumnName.ToString()].ToString().Trim()).ToString("hh:mm:ss");
dr["New Value"] = DateTime.Parse(dtSecond.Rows[0][dtSecond.Columns[i].ColumnName.ToString()].ToString().Trim()).ToString("MM/dd/yyyy") + " - " + DateTime.Parse(dtSecond.Rows[0][dtSecond.Columns[i].ColumnName.ToString()].ToString().Trim()).ToString("hh:mm:ss");
dtDiff.Rows.Add(dr);
}
flag = false;
}
}
}
return dtDiff;
}
my code is working fine but i need to the is there any best way out. please guide me.
you can use LINQ to comparing tables values(two table must have the same structure)
bool flag = false;
if (dtFirst.Columns.Count == dtSecond.Columns.Count)
{
for (int i = 0; i <= dtFirst.Columns.Count - 1; i++)
{
String colName = dtFirst.Columns[i].ColumnName;
var colDataType = dtFirst.Columns[i].DataType.GetType();
var colValue = dtFirst.Columns[i];
flag = dtSecond.AsEnumerable().Any(T => typeof(T).GetProperty(colName).GetValue(T, typeof(colDataType)) == colValue);
}
}
var qry1 = dtDuplicate.AsEnumerable().Select(a => new { SchoolID = a["SchoolMID"].ToString()});
var qry2 = dsValadateSchoolInfo.Tables[1].AsEnumerable().Select(b => new { SchoolID = ["SchoolMID"].ToString() });
var exceptAB = qry1.Except(qry2);
DataTable dtMisMatch = (from a in dtDuplicate.AsEnumerable()
join ab in exceptAB on a["SchoolMID"].ToString() equals ab.SchoolID
select a).CopyToDataTable();