I have a DB ad Microsoft Identity Manager to generate user accounts from HR to MS Active Directory and so on.
I have a such code for generate unique email:
case "mailgenerate":
if (mventry["email"].IsPresent)
{
// Do nothing, the mail was already generated.
}
{
if (csentry["FIRST"].IsPresent && csentry["LAST"].IsPresent);
{
string FirstName = replaceRUEN(csentry["FIRST"].Value);
string LastName = replaceRUEN(csentry["LAST"].Value);
string email = FirstName + "." + LastName + "#test.domain.com";
string newmail = GetCheckedMail(email, mventry);
if (newmail.Equals(""))
{
throw new TerminateRunException("A unique mail could not be found");
}
mventry["email"].Value = newmail;
}
}
break;
//Generate mail Name method
string GetCheckedMail(string email, MVEntry mventry)
{
MVEntry[] findResultList = null;
string checkedmailName = email;
for (int nameSuffix = 1; nameSuffix < 100; nameSuffix++)
{
//added ; and if corrected
findResultList = Utils.FindMVEntries("email", checkedmailName,1);
if (findResultList.Length == 0)
{
// The current mailName is not in use.
return (checkedmailName);
}
MVEntry mvEntryFound = findResultList[0];
if (mvEntryFound.Equals(mventry))
{
return (checkedmailName);
}
// If the passed email is already in use, then add an integer value
// then verify if the new value exists. Repeat until a unique email is checked
checkedmailName = checkedmailName + nameSuffix.ToString();
}
// Return an empty string if no unique mailnickName could be created.
return "";
}
Problem:
When I run sync cycle for first time I get normal email like
duplicateuser1#test.domain.com
For next sync cycle this emails are updated to
duplicateuser#test.domain.com1
This code I'm also using to generate mailnickname and accountname without any problems.
Can anybody say why it is happens?
Thanks!
The problem is the line:
checkedmailName = checkedmailName + nameSuffix.ToString();
checkedmailName has a value like this: firstName.lastName#test.domain.com
So, you're doing this:
checkedmailName = firstName.lastName#test.domain.com + 1;
You need to do something like this:
checkedmailName = checkedmailName.Split('#')[0] + nameSuffix.ToString()+ "#" + checkedmailName.Split('#')[1];
Whith this, you're getting the part before #, adding a int value and then, appending the #+ domain.
Updated by author of thread I changed split -> Split and it works. Thanks!
Related
All I need is a more reliable and stable way of logging into multiple account (not all at once) using a loop that's all. I have already an example code that works but isn't all that stable.
string email_1 = "email_1";
string password_1 = "password_1";
string email_2 = "email_2";
string password_2 = "password_2";
int k = 1;
do
{
string e = null;
string p = null;
if (k == 1)
{
e = email_2;
p = password_2;
}
if (k == 2)
{
e = email_1;
p = password_1;
}
_driver.FindElement.(id("submit_email")).sendkeys(e);
IWebElement s = _driver.FindElement.(id("submit_password"));
s.Sendkeys(p);
s.Submit();
//do stuff
_driver.FindElement(id("logout")).Click();
k++;
} while (k <= 2);
Any ideas on how to make it more stable and reliable, or maybe a better approach to it?
You're gonna need to completely refactor this code. Have you ever practiced object oriented design?
Create this class:
public class Account // Stores the email and password of each account
{
public string Email;
public string Password;
public Account(string email, string password) // Constructor
{
Email = email;
Password = password;
}
}
Then use this class like so:
// Keep all the accounts in one place
List<Account> accounts = new List<Account>()
{
new Account("email_1", "password_1"), // Create a new account
new Account("email_2", "password_2") // Create another account
};
foreach(Account account in accounts)
{
_driver.FindElement.(id("submit_email)).sendkeys(account.Email);
IWebElement s = _driver.FindElement.(id("submit_password"));
s.Sendkeys(account.Password);
s.Submit();
// do stuff
_driver.FindElement(id("logout")).Click();
}
This code is highly expandable and reusable. If you want to add another account, you use the new Account(string, string), statement in the List and that's the only change that needs to be made.
Please help me, I'm facing a fatal problem here. If someone could fix this, I swear I will treat u to a huge drink whenever u step into my country (Vietnam). Ok here's the problem: I'm coding a webservice for multi connection simultaneously from tablet (around 100 clients). It ran well but recently whenever high traffic occurs, my webservice seems to stuck somehow and I need to copy - override the published file of webservice in order for it to run again (restart website in IIS is no use) ...
This is my w/s code for handling the data:
public string Info_Handling(string id, string name, string strDetails)
{
string checkExist = "";
string str = "";
string str2 = "";
MLL_Customer _customerClient = new MLL_Customer();
MLL_CustomerCategory _categoryClient = new MLL_CustomerCategory();
MLL_Product _productClient = new MLL_Product();
MLL_SampleProduct _sampleClient = new MLL_SampleProduct();
if (_customerClient.CheckExistCustomer(id, name.ToUpper(), 2) == 1) // SID & NAME
{
checkExist = "EXIST";
}
using (SqlConnection connection = new SqlConnection(ConfigurationSettings.AppSettings["Main.ConnectionString"]))
{
connection.Open();
SqlTransaction trans = connection.BeginTransaction("XXX");
try
{
// ID Example: 11 means VIP - 12 means Normal - 13 means ples... jkg
// First - Insert Customer
string strCustomerCategory = _categoryClient.SelectCategoryByID(id).ToString();
if (!checkExist.Equals("EXIST"))
{
Customer businessObject = new Customer();
businessObject.ID = sid;
businessObject.Name = name.ToUpper();
businessObject.CategoryID = strCustomerCategory;
str = "" + _customerClient.Insert(businessObject, connection, trans);
}
// Second Insert Product spliting from a string Ex: "TV&Laptop&CD"
string[] productDetails = strDetails.Split(new char[] { '&' });
object obj3;
SampleProduct objSample;
Product objProduct;
for (int j = 0; j < productDetails.Length; j++)
{
if (_productClient.CheckExist(id, productDetails[j])) == null) // Check if customer already owns this product
{
// Get the properties of sample product.
objSample = _sampleClient.SelectSampleProduct(productDetails[j]);
objProduct = new Product();
objProduct.SID = sid;
objProduct.Testcode = objSample.TestCode;
objProduct.Category = objSample.Category;
objProduct.Unit = objSample.Unit;
objProduct.Price = objSample.Price;
if (_productClient.Insert(objProduct, connection, trans) != 0)
{
str2 = str2 + "&" + objProduct.Testcode;
// return the code of product in order to see which product has been inserted successfully
}
}
}
trans.Commit();
SqlConnection.ClearAllPools();
}
catch (Exception exception)
{
str = "0";
str2 = exception.Message + exception.Source;
try
{
trans.Rollback();
}
catch (Exception)
{
}
}
}
if (!str2.Equals(""))
{
return (str + "&" + id + str2);
}
return ("0&" + sid + str);
}
I modified the code but this is basically how i roll. Could anyone plz tell me some solution. Deeply thank u.
1 more thing about ClearAllPools() method: I know how it works but I dont even know why I need it. Without this, my data will be messed up terrible. CategoryID of one customer will be assigned for another customer sometimes. ???? How could it happened ?? HELP
I am working on some code that creates an AD user programmatically (to be pulled into a MS DYnamics CRM 2013 environment), and the code works with one weird quirk. I have a list of UPN's created on our AD structure, but for some reason my AD users aren't resolving to them.
So, I have a list of UPN suffix's that include example.com. I set the username to be first.last#example.com, and it's not letting me use this to sign in to CRM. When I check the AD entry, I can see that it kind of correctly assigned the logon name to first.last#example.com, but #example.com appears in the list twice, the entry that was actually created and this new one. So it's not recognizing that #example.com is a pre-existing UPN suffix, and I can't use the first.last#example.com to sign in to CRM with, I have to use the example.local\first.last. I hope this made sense. Thank you very much.
So how do I tell then AD record when it signs in to use the pre-existing UPN and not... do whatever it's doing? Here's my code:
try
{
string connectionPrefix = "LDAP://" + ldapPath;// ldapPart;// ldapPath
var adminUsername = ConfigurationHelper.GetConfigSettingByName(orgservice,
"ADPasswordReset.AdminUsername", unsecureConfig, secureConfig);
var adminPassword = ConfigurationHelper.GetConfigSettingByName(orgservice,
"ADPasswordReset.AdminPassword", unsecureConfig, secureConfig);
if (CheckIfUserExists(getSAMNameFromUserName(userName), trace) == true)
{
throw new Exception("A User with that name already exists.");
}
DirectoryEntry dirEntry = new DirectoryEntry(connectionPrefix, adminUsername, adminPassword, AuthenticationTypes.Secure);
DirectoryEntry newUser;
string cn = firstName + " " + lastName;
newUser = dirEntry.Children.Add("CN=" + cn, "user"); //display name - This is the "Display" name that shows up on the AD list.
newUser.Properties["displayName"].Value = cn;
newUser.Properties["samAccountName"].Value = getSAMNameFromUserName(userName);//userName;
newUser.Properties["userPrincipalName"].Value = checkUserName(userName);
newUser.Properties["givenName"].Value = firstName; //Firstname
newUser.Properties["sn"].Value = lastName; //Lastname? -Surname
newUser.Properties["LockOutTime"].Value = 0; //unlock account. Set this to 0 to unlock the account.
newUser.CommitChanges();
oGUID = newUser.Guid.ToString();
//Must be handled after the previous stuff. Unsure why.
newUser.Invoke("SetPassword", new object[] { userPassword });
newUser.CommitChanges();
//For some reason, can't be handled before the password is set?
newUser.Properties["userAccountControl"].Value = 0x0200; //0x0200
newUser.CommitChanges();
dirEntry.Close();
newUser.Close();
}
public static string checkUserName(string userName)
{
if (!userName.Contains("#"))
{
return userName + "#example.local";
}
return userName;
}
public static string getSAMNameFromUserName(string domainUserName)
{
int stop;
string s = domainUserName;
if (s.Contains("#"))
{
stop = s.IndexOf("#");
return (stop > -1) ? s.Substring(0, stop) : string.Empty;
}
return domainUserName;// string.Empty;
}
In your code you set the UPN to example.local not example.com:
public static string checkUserName(string userName)
{
if (!userName.Contains("#"))
{
return userName + "#example.local";
}
return userName;
}
A user can only have one UPN even if the domain has multiple possible suffixes configured. If you want username#example.com to resolve, the user must have example.com set as it's suffix.
Thank you all who took the time to help.
Whitespace. Grrr, whitespace.
For anybody who comes across this thread in the future, the problem was that something during the AD creation was appending whitespace to my username and domain. So instead of "example.com" it was saving the domain as "example.com " (notice the whitespace at the end?). I .Trim()'d everything and it appears to be working just fine. :)
My new code becomes:
public static string checkUserName(string userName)
{
if (!userName.Contains("#"))
{
return userName.Trim() + "#domain.local".Trim();
}
return userName.Trim();
}
try
{
string connectionPrefix = "LDAP://" + ldapPath;// ldapPart;// ldapPath
var adminUserName = GetAdminUserName(orgservice, unsecureConfig, secureConfig);
var adminPassword = GetAdminPassword(orgservice, unsecureConfig, secureConfig);
if (CheckIfUserExists(getSAMNameFromUserName(userName), trace) == true)
{
trace.Trace("About to handle success. A User already exists: " + getSAMNameFromUserName(userName));
trace.HandleSuccess();
throw new Exception("User " + getSAMNameFromUserName(userName) + " already exists.");
}
DirectoryEntry dirEntry = new DirectoryEntry(connectionPrefix, adminUserName, adminPassword, AuthenticationTypes.Secure);
DirectoryEntry newUser;
string cn = firstName.Trim() + " " + lastName.Trim();
newUser = dirEntry.Children.Add("CN=" + cn, "user"); //display name - This is the "Display" name that shows up on the AD list.
newUser.Properties["displayName"].Value = cn;
newUser.Properties["samAccountName"].Value = getSAMNameFromUserName(userName).Trim();
newUser.Properties["userPrincipalName"].Value = checkUserName(userName).Trim();
newUser.Properties["givenName"].Value = firstName.Trim(); //Firstname
newUser.Properties["sn"].Value = lastName.Trim(); //Lastname? -Surname
//newUser.Properties["LockOutTime"].Value = 0; //unlock account. Set this to 0 to unlock the account.
newUser.CommitChanges();
oGUID = newUser.Guid.ToString();
//Must be handled after the previous stuff. Unsure why.
newUser.Invoke("SetPassword", new object[] { userPassword });
newUser.CommitChanges();
//For some reason, can't be handled before the password is set?
newUser.Properties["userAccountControl"].Value = 0x10200; //0x0200
newUser.CommitChanges();
//http://stackoverflow.com/questions/20710535/is-there-a-way-to-set-a-new-users-domain-suffix-through-the-userprincipal-class
newUser.Close();
dirEntry.Close();
//newUser.Close(); //Close user first, then dirEntry because of the heirarchy call?
}
catch (System.DirectoryServices.DirectoryServicesCOMException E)
{
System.DirectoryServices.DirectoryServicesCOMException newE = new System.DirectoryServices.DirectoryServicesCOMException(E.Message);
//DoSomethingwith --> E.Message.ToString();
throw newE;
}
I have the following code that creates a case in SugarCRM via C#.
I am asking, does anybody know how I would go about adding a reply on this case via c# to sugarCRM api?
NameValueCollection fieldListCollection = new NameValueCollection();
fieldListCollection.Add("id", string.Empty);
fieldListCollection.Add("name", "Something went wrong");
fieldListCollection.Add("description", "This software is not working");
fieldListCollection.Add("status", "test"); //New, Assigned, Closed, Pending Input, Rejected, Duplicate
fieldListCollection.Add("priority", "test"); //High, Medium, Low
fieldListCollection.Add("account_id", AccountId); // Don't pass this if you don't want to associate an account with it
fieldListCollection.Add("contact_id", ContactId); // Don't pass this if you don't want to associate with this contact with it
SugarCRM.name_value[] fieldList = new SugarCRM.name_value[fieldListCollection.Count];
int count = 0;
foreach (string name in fieldListCollection)
{
foreach (string value in fieldListCollection.GetValues(name))
{
SugarCRM.name_value field = new SugarCRM.name_value();
field.name = name; field.value = value;
fieldList[count] = field;
}
count++;
}
SugarCRM.new_set_entry_result result = SugarClient.set_entry(SessionID, "Cases", fieldList); //Accounts, Incidents, Contacts, Cases
Console.WriteLine("New ID: " + result.id);
I am using the following plugin which executes on update of an opportunity:
public class PreOpportunityWin : Plugin
{
public PreOpportunityWin() : base(typeof(PreOpportunityWin))
{
base.RegisteredEvents.Add(
new Tuple<int, string, string, Action<LocalPluginContext>>(20, "Update", "opportunity", new Action<LocalPluginContext>(ExecuteAutonumber)));
}
protected void ExecuteAutonumber(LocalPluginContext localContext)
{
Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)localContext.PluginExecutionContext;
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
//Organization Service
IOrganizationService service = localContext.OrganizationService;
//Tracing Service
ITracingService trace = (ITracingService)localContext.TracingService;
Entity Target = (Entity)context.InputParameters["Target"];
var entity = service.Retrieve(
Target.LogicalName, Target.Id, new ColumnSet(true));
var entityStatusCode = (OptionSetValue)entity.Attributes["statuscode"];
if (entityStatusCode.Value == 3)
{
//Code to execute if opportunity won
trace.Trace("In the execute block...");
//Depending on the retrieved name, generate the appropriate fetch xml
string fetchXml = null;
fetchXml = #"<fetch mapping='logical'>
<entity name='my_autonumber'><all-attributes/>
<filter type=""and"">
<condition attribute=""my_autonumberentity"" operator=""eq"" value=""opportunity"" />
<condition attribute=""my_name"" operator=""eq"" value=""The Autonumber Record"" />
</filter></entity></fetch>";
try
{
//Fetch the approiate autonumber record
EntityCollection result = service.RetrieveMultiple(new FetchExpression(fetchXml));
string nextIncrementNumber = string.Empty;
if (result.Entities.Count == 1)
{
Entity autoNumber = result.Entities[0];
//Lock the autonumber enity
lock (autoNumber)
{
if (!autoNumber.Attributes.Contains("my_counter"))
throw new InvalidPluginExecutionException("my_counter must contain a value");
if (!autoNumber.Attributes.Contains("my_incrementunit"))
throw new InvalidPluginExecutionException("my_IncrementUnit must contain a value");
int counter = Int32.Parse(autoNumber.Attributes["my_counter"].ToString());
int incrementUnit = Int32.Parse(autoNumber.Attributes["my_incrementunit"].ToString());
string prefix = autoNumber.Attributes.Contains("my_prefix") ? autoNumber.Attributes["my_prefix"].ToString() : string.Empty;
string prefixSeparator = autoNumber.Attributes.Contains("my_prefixseparator") ? autoNumber.Attributes["my_prefixseparator"].ToString() : string.Empty;
string suffix = autoNumber.Attributes.Contains("my_suffix") ? autoNumber.Attributes["my_suffix"].ToString() : string.Empty;
string suffixseparator = autoNumber.Attributes.Contains("my_suffixseparator") ? autoNumber.Attributes["my_suffixseparator"].ToString() : string.Empty;
string numberFormatter = autoNumber.Attributes.Contains("my_numberformatter") ? autoNumber.Attributes["my_numberformatter"].ToString() : string.Empty;
string fieldToUpdate;
if (autoNumber.Attributes.Contains("my_entityautonumberfield"))
fieldToUpdate = autoNumber.Attributes["my_entityautonumberfield"].ToString();
else
throw new InvalidPluginExecutionException("my_entityautonumberfield should not be empty");
nextIncrementNumber = BuildAutoNumber(entity, prefix, prefixSeparator, suffix, suffixseparator, counter, incrementUnit, numberFormatter, service);
//Set project number
entity.Attributes["new_projectnumber"] = nextIncrementNumber;
autoNumber.Attributes["my_counter"] = counter + incrementUnit;
service.Update(autoNumber);
}
}
}
catch (Exception ex)
{
throw new InvalidPluginExecutionException(string.Format("An error occured in Autonumber plugin: {0}", ex.ToString()));
}
}
}
}
//This function builds the autonumber itself
private string BuildAutoNumber(Entity entity, string prefix, string prefixSeparator, string suffix, string suffixSeparator, int counter, int incrementUnit, string numberFormatter, IOrganizationService service)
{
bool hasPrefix = false, hasSuffix = false;
string returnNumber = string.Empty;
prefix = "P";
if (!string.IsNullOrEmpty(prefix))
{
hasPrefix = true;
}
counter = counter + incrementUnit;
returnNumber = (hasPrefix ? prefix + prefixSeparator : "") + counter.ToString(numberFormatter) + (hasSuffix ? suffix + suffixSeparator : "");
return returnNumber;
}
}
This plugin execute on update of an opportunity, but it throws the following error:
This workflow job was canceled because the workflow that started it
included an infinite loop. Correct the workflow logic and try again.
I can't find an infinite loop anywhere, furthermore, I use pretty much the same code on create of an opportunity to append another autonumber in a different field. The only difference between the 2 plugins is this code that checks for the win state:
Entity Target = (Entity)context.InputParameters["Target"];
var entity = service.Retrieve(Target.LogicalName, Target.Id, new ColumnSet(true));
var entityStatusCode = (OptionSetValue)entity.Attributes["statuscode"];
if (entityStatusCode.Value == 3)
//Code to execute if opportunity won
Can someone elaborate on this error for me?
Somewhere you have a plug-in that generates a recurring loop you are not breaking out of, see my question about the my_autonumber entity.
The value to check is IPluginExecutionContext.Depth which tells you how many times you are looping.
After:
Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)localContext.PluginExecutionContext;
Insert this line:
if (context.Depth > 1) return;
This will terminate processing if the plug-in is executing more than once.
Be ware with using context.Depth.
Using context.Depth will fail your plugin, where you have another plugin which trigger this action in your plugin.
Now the Depth will be 2, but it was because there was another plugin call this plugin.
I am also facing this issue, any other solution apart using Context.Depth?