Get data from to field in new activity in CRM 2011 - c#

I create a new plugin for dynamic CRM 2011 for a costume Activity Entity.
this new activity have "to" field like Email and some other activities.
plugin are working on Create and Update steps for activity.
my problem is when i want to get "to" field value the below line of code return false value and i don't know what i have done. in fact i can fetch other custom field and just the "to" field does not work.
if (entity3.Attributes.Contains("to"))
and this is whole code:
public void Execute(IServiceProvider serviceProvider)
{
if (serviceProvider == null)
{
throw new ArgumentNullException("serviceProvider");
}
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
if (context.InputParameters.Contains("Target") && (context.InputParameters["Target"] is Entity))
{
Entity entity2 = (Entity)context.InputParameters["Target"];
if (entity2.LogicalName == "EntityAtivity")
{
QueryExpression expression3 = new QueryExpression("EntityAtivity");
ColumnSet set2 = new ColumnSet();
set2.AllColumns = true;
expression3.ColumnSet = set2;
ConditionExpression item = new ConditionExpression();
item.AttributeName = "activityid";
CurrentGuid = (Guid)entity2.Attributes["activityid"];
item.Values.Add(this.CurrentGuid);
FilterExpression expression5 = new FilterExpression();
expression5.Conditions.Add(item);
expression3.Criteria = expression5;
EntityCollection entitys2 = service.RetrieveMultiple(expression3);
foreach (Entity entity3 in entitys2.Entities)
{
this.dbGuid = (Guid)entity3.Attributes["activityid"];
if (entity3.Attributes.Contains("to"))
{
try
{
foreach (Entity entity10 in ((EntityCollection)entity3.Attributes["to"]).Entities)
{
this.dbTo.Add(((EntityReference)entity10.Attributes["partyid"]).LogicalName);
this.dbToId.Add(((EntityReference)entity10.Attributes["partyid"]).Id);
}
}
catch (Exception)
{
this.dbTo.Clear();
}
}
} // foreach
}//if (entity2.LogicalName == "EntityAtivity")
}//if (context.InputParameters.Contains("Target") && (context.InputParameters["Target"] is Entity))
}
any know what i should done to correct plugin?

Your question and answer is hard to understand because your English could use some work, but I believe your issue is that you're looking for an attribute in the target of a value that hasn't been set. If an attribute hasn't been set or updated, it will not show up in the target of the the plugin. As #AndyMeyers says, you should use the PreImage and PostImage images to define what attributes you always want to be included in the processing of your plugin.

So i solve my problem.
i create 2 steps, for Create and Update.
when i disable the Create Step and create pre image for update step, plug in fetch to field and show the values.

Related

How to insert or update properties in Active Directory Users and Groups

I am making a windows application that sync the source data to Active Directory.
This application works like this.
Choose Source Data(Department, User)
Mapping user or department attributes from source data
When Application service is run, it create groups and users in Active Directory
And also it sets the attributes to users and groups.
When I try to set group or user attributes(properties), it throws exception message like this.
in DirectoryEntry.CommitChanges(); block
The directory
service cannot perform the requested operation on the RDN attribute of an object.
I tried to solve it, but it's really hard to me because I`m not good at Active directory...
Code is below, Please share your knowledge.
//ppk: department key column, pk:user key column, row : Source DataTable's row
void CreateADUser(string ppk,string pk,DataRow row)
{
//password
string pass = GetPass(pk,row,LogSections.AD);
//OU
DirectoryEntry addept = adm.FindOU(ppk);
//principal path
string sOU = adm.GetPrincipalPath(addept);
var aduser = adm.CreateNewUser(sOU, pk, pass, pk, null, null, adm.sDomain);
SetAdUserProperties(pk, pass, row);
MoveUser(ppk,pk);
}
void SetAdUserProperties(string pk,string pass,DataRow row)
{
if (row == null) return;
//list of mapped column(AD User attributes)
List<ADMapping> MappingPatterns = GetAdMappings(Words.User,false);
//Columns name of Source Data table's row
var colnames = Tool.GetColNames(row);
//get user proterties
var aduser = adm.GetUser(pk);
//directory entry of users
var de=aduser.GetUnderlyingObject() as DirectoryEntry;
//looping mapped column of user attributes
foreach (var ADMap in MappingPatterns)
{
string val = ADMap.Mapping;
//mapped columns value
val=Util.ReplaceColPattern(val, row);
SetProperty(de, ADMap.CN, val);
}
if (!string.IsNullOrWhiteSpace(pass))
{
var UserPkColumn = AppConfigHelper.GetAppString(Words.SourceUserPKColumn);
UserPkColumn = Util.GetActualColName(UserPkColumn);
aduser.SetPassword(pass);
QueryHelper.Update(QueryHelper.ConnectionString, Words.ShadowUserTable
,new SqlParameter[] { new SqlParameter("#passwd", pass) }
, new SqlParameter("#"+UserPkColumn,pk));
}
aduser.Save();
}
public void SetProperty(DirectoryEntry oDE, string sPropertyName, object sPropertyValue)
{
if (sPropertyValue != null && !string.IsNullOrWhiteSpace(sPropertyValue.ToString()))
{
if (oDE.Properties.Contains(sPropertyName))
{
oDE.Properties[sPropertyName].Value = sPropertyValue;
}
else
{
oDE.Properties[sPropertyName].Add(sPropertyValue);
}
try
{
oDE.CommitChanges(); //exception here.
oDE.Close();
}
catch (Exception)
{
}
}
}
I also asked this question to other forums, and finally got it.
Before DirectoryEntry.CommitChanges(); set UserPropertyCache property to true
and call the RefreshCache method.
It's hard to see what's the cause of the issue here as we're not seeing what attributes you are trying to set.
That said, you can't just add an attribute if it doesn't exist on your AD object so this part of your code definitely has an issue :
if (oDE.Properties.Contains(sPropertyName))
{
oDE.Properties[sPropertyName].Value = sPropertyValue;
}
else
{
//The following line will never work in this context
oDE.Properties[sPropertyName].Add(sPropertyValue);
}
If I had to make an educated guess, I'd say you're either trying to set an attribute that can't be set, or the User you're adding doesn't have all it's mandatory attributes set.

Entity Framework 5 : One to Many with foreignKey Updated/Added/Deleted

When I update my member, I want to update his BankCheck too.
This is my database:
My bankCheck can be added, updated or deleted.
My member can be updated only (name, surname...)
I choose my member in my datagrid, and select Edit, my wpf app switch to an other page and display my member with Textbox etc.
I click on my button to add/edit/delete his bankCheck and I can edit the first bankCheck.
I delete the last bankCheck and I add an other (for example).
I press OK and I click on "Valid my Edit".
My program re-creates a new Member with his bankCheck and i made this:
private void EditMember(Member updatedMember)
{
try
{
using (var context = new KravMagaEntities())
{
context.Member.Attach(updatedMember);
context.Entry(updatedMember).State = EntityState.Modified;
context.SaveChanges();
}
ResetAllControls();
States.EnumToText(States.StatesEnum.UpdatingSuccess);
Application.Current.Dispatcher.Invoke(() =>
{
_managementService.IsVisibleAddTab(true);
_managementService.IsVisibleEditTab(false);
});
}
catch (Exception exception)
{
States.EnumToText(States.StatesEnum.Error, exception);
}
}
But I have this error:
A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.
I don't know how I can fix this error.
Thank you.
My code:
private void OnEditMemberBtnClicked(object sender, RoutedEventArgs e)
{
try
{
var isValidateCertificat = IsValidDate(BirthDateTxt);
var isValidateBirth = IsValidDate(CertificateDateTxt);
var isValidateAutorisation = IsValidDate(AutorizationDateTxt);
var isValidateReglement = IsValidDate(RuleDateTxt);
if (isValidateBirth && isValidateCertificat && isValidateAutorisation && isValidateReglement)
{
States.EnumToText(States.StatesEnum.Updating);
var typePaiement = BankCheckRadio.IsChecked.Value;
var typePaiementText = typePaiement ? "Chèque" : "Espèce";
var doctor = "";
var dateCertificate = "";
if (BankCheckRadio.IsChecked.Value)
{
doctor = DoctorTxt.Text;
dateCertificate = CertificateDateTxt.Text;
}
var editedMember = new Member
{
id_Member = _idForEdit,
name_Member = UppercaseChar(NameTxt.Text),
surname_Member = UppercaseChar(SurnameTxt.Text),
birthDate_Member = BirthDateTxt.Text,
autorizationDate_Member = AutorizationDateTxt.Text,
address_Member = UppercaseChar(AddressTxt.Text),
postalCode_Member = PostalCodeTxt.Text,
country_Member = UppercaseChar(CountryTxt.Text),
fixPhone_Member = FixPhoneTxt.Text,
mobilePhone_Member = MobilePhoneTxt.Text,
mail_Member = MailTxt.Text,
beginDate_Member = BeginDateCombo.Text,
ruleDate_Member = RuleDateTxt.Text,
subscription_Member = SubscriptionCombo.Text,
typePaiement_Member = typePaiement,
typePaiementText_Member = typePaiementText,
federationNumero_Member = FederationNumeroTxt.Text.ToUpper(),
level_Member = LevelCombo.Text,
certificate_Member = CertificateCheckbox.IsChecked.Value,
doctor_Member = UppercaseChar(doctor),
certificateDate_Member = dateCertificate,
problem_Member = UppercaseChar(ProblemTxt.Text, true),
emergencyName_Member = UppercaseChar(EmergencyNameTxt.Text),
emergencyPhone_Member = EmergencyPhoneTxt.Text,
BankCheck = _bankChecks
};
if (_bankChecks != null)
{
using (var context = new KravMagaEntities())
{
foreach (var bankCheck in _bankChecks)
{
bankCheck.idMember_BankCheck = editedMember.id_Member;
context.Entry(bankCheck).State = EntityState.Added;
}
context.SaveChanges();
}
}
new Task(() => EditMember(editedMember)).Start();
}
}
catch (Exception exception)
{
States.EnumToText(States.StatesEnum.Error, exception);
}
}
So as I see, you're updating only Member, not all the modified BankAccounts. You're updating navigation property of entities from both sides but calling SaveChanges() only on entity from one side. So your Member starts to refer another BankAccount while your BankAccounts still refer to the old Member. You need to mark all appropriate BankAccounts as modified along with your modified Member in the same place and then call SaveChanges() so everything will be saved (from comment).
To prevent adding a duplicate you can try to set the state of your entities to the State.Modified instead of State.Added.
The reason of that problem was that you were updating only entity from one side. If you have BankAccounts-Members relationship then in case you update the navtigation property for Member you should update a navigation property for BankAccount too and vice versa. If you just update some property (Member.Name or anything) you just set this Member's State to State.Modified without affecting any of other Member's, BankAccount's etc.
If the entity tracking is turned on for you then EF will automatically track entities that were modified and set appropriate states for them. But as I've seen from your issue, it's turned off for you so you have to manually set the state for each object you want to add/update/delete.

Copy Records to another Screen in acumatica

I have 2 screen, inquiry and data entry.
and i want to copy Record from Screen1 to screen2, see picture below.
scree1 and Screen2
I use the following code:
public PXAction<FuncLocFilter> CreateFuncLoc;
[PXButton]
[PXUIField(DisplayName = "Create Functional Location")]
protected virtual void createFuncLoc()
{
FuncLocFilter row = Filter.Current;
BSMTFuncLoc FnLc = new BSMTFuncLoc();
FunLocEntry graph = PXGraph.CreateInstance<FunLocEntry>();
graph.FunLocations.Current.FuncLocCD = row.FuncLocCD;
graph.FunLocations.Current.StructureID = row.StructureID;
graph.FunLocations.Current.HierLevels = row.HierLevels;
graph.FunLocations.Current.EditMask = row.EditMask;
if (graph.FunLocations.Current != null)
{
throw new PXRedirectRequiredException(graph, true, "Functional Location");
}
}
but i encountered an error like the following:
Error
can someone please help solve this seemingly stupid question?
im sorry my english is bad.. :)
Thanks!
Below is a common pattern to create data records via code/programming in Acumatica
public PXAction<FuncLocFilter> CreateFuncLoc;
[PXButton]
[PXUIField(DisplayName = "Create Functional Location")]
protected virtual void createFuncLoc()
{
FuncLocFilter row = Filter.Current;
// 1. Create an instance of the BLC (graph)
FunLocEntry graph = PXGraph.CreateInstance<FunLocEntry>();
// 2. Create an instance of the BSMTFuncLoc DAC, set key field values (besides the ones whose values are generated by the system),
// and insert the record into the cache
BSMTFuncLoc FnLc = new BSMTFuncLoc();
FnLc.FuncLocCD = row.FuncLocCD;
FnLc = graph.FunLocations.Insert(FnLc);
// 3. Set non-key field values and update the record in the cache
FnLc.StructureID = row.StructureID;
FnLc.HierLevels = row.HierLevels;
FnLc.EditMask = row.EditMask;
FnLc = graph.FunLocations.Update(FnLc);
// 4. Redirect
if (graph.FunLocations.Current != null)
{
throw new PXRedirectRequiredException(graph, true, "Functional Location");
}

Sys.WebForms.PageRequestManagerServerErrorException: An entity object cannot be referenced by multiple instances of IEntityChangeTracker

Story:
I have a strange error when I try to save something I got this error message
An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
I really don’t know what that is and why is it appear, it appears only when I try to save something my insert and update is working, only when I try to save something in db from my Telerik grid
if (this.annualVacationList != null)
{
List<AnnualVacation> vacationToSave = this.annualVacationList;
IEnumerable<AnnualVacation> existing = paramUser.AnnualVacations;
foreach (AnnualVacation toSave in vacationToSave)
{
AnnualVacation existingItem = existing.Where(x => x.AnnualVacationId == toSave.AnnualVacationId).SingleOrDefault();
if (existingItem == null)
{
ctx.AddToAnnualVacations(toSave);
}
else
{
existingItem.FromDate = toSave.FromDate;
existingItem.ToDate = toSave.ToDate;
existingItem.WorkingTime = toSave.WorkingTime;
existingItem.VacationDays = toSave.VacationDays;
}
}
}
ctx.SaveChanges();
}
After debugging I have seen that the code brake down in the Project.Name.Designer.cs
..... O.o
public void AddToAnnualVacations(AnnualVacation annualVacation)
{
base.AddObject("AnnualVacations", annualVacation);
}
Heey
I got it by myself somehow viewstates are not Detaching the context and that was the problem I have just created
var tmp = new AnnualVacation
{
FromDate = toSave.FromDate,
ToDate = toSave.ToDate,
WorkingTime = toSave.WorkingTime,
VacationDays = toSave.VacationDays,
UserId = toSave.UserId
};
in the same if query that is above (if(existing Item==null)) and it works
but still thanks for everyone that tried to help me ^^

ObjectStateManager does not contain an ObjectStateEntry with a reference to an object of type

I am using EISK (Employee Info Starter Kit) to develop an application. My entity diagram looks like this I try to update the application table via this code.
int apId = Convert.ToInt32(Request.QueryString["ApplicationID"]);
ApplicationBLL objGetApplication = new ApplicationBLL();
Appdec.YEP.BusinessEntities.Application objApplication =
objGetApplication.GetApplicationByApplicationID(apId);
objApplication.Status = (ddlStatus.SelectedValue == "0" ? false : true);
new ApplicationBLL(new Appdec.YEP.DataAccessLayer.DatabaseContext()).UpdateApplication(objApplication);
now the update method at bussiness logic is
[System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, true)]
public void UpdateApplication(Application updatedApplication)
{
// Validate Parameters
if (updatedApplication == null)
throw (new ArgumentNullException("updatedApplication"));
// Validate Primary key value
if (updatedApplication.ApplicationID.IsInvalidKey())
BusinessLayerHelper.ThrowErrorForInvalidDataKey("ApplicationID");
// Apply business rules
OnApplicationSaving(updatedApplication);
OnApplicationUpdating(updatedApplication);
//attaching and making ready for parsistance
if (updatedApplication.EntityState == EntityState.Detached)
_DatabaseContext.Applications.Attach(updatedApplication);
_DatabaseContext.ObjectStateManager.ChangeObjectState(updatedApplication, System.Data.EntityState.Modified);//this line throws the error
//ObjectStateManager does not contain an ObjectStateEntry with a reference to an object of type
int numberOfAffectedRows = _DatabaseContext.SaveChanges();
if (numberOfAffectedRows == 0)
throw new DataNotUpdatedException("No application updated!");
//Apply business workflow
OnApplicationUpdated(updatedApplication);
OnApplicationSaved(updatedApplication);
}
Can somebody tell me how to fix this error and update the tables.
the same error ocurres when i try to update other tables also. The insert works fine.
Hoping not to bother you. Best Regards.
So it already belongs to a context,and you should update that context.
It can't be attached to new context,
You can create a new instance of updatedApplication and copy all properties of updatedApplication to this new one and attach new entity to application.
Also change
if (newApp .EntityState == EntityState.Detached)
_DatabaseContext.Applications.Attach(newApp );
to
var newApp = Application ();
//Copy all propery of updatedApplication to newApp here
if (newApp .EntityKey == null || newApp .EntityKey.IsTemporary)
{
_DatabaseContext.Applications.AddObject(newApp );
}
else
{
_DatabaseContext.Applications.Attach(newApp );
}
_DatabaseContext.ObjectStateManager.ChangeObjectState(newApp , System.Data.EntityState.Modified);

Categories

Resources