Plugin Create Pre-Operation add related entity - dynamics-crm

So when an entity is created, I want to search for some other entities and relate them. However I get a not-exists error if I update the other entities with the entity ref of the newly created one, and that makes sense because it's PRE create.
So I updated it like so thinking this would do the trick, but I'm getting an "unknown error" from somewhere deep in the heart of CRM outside of my control:
var newEntity = (Entity)localContext.PluginExecutionContext.InputParameters["Target"];
var allUnits = localContext.OrganizationService.RetrieveMultiple(....); //grabs the units that will be used
newEntity.RelatedEntities.Add(new Relationship("ntcp_equipment_unit"), new EntityCollection(allUnits.Entities));
Result:
System.ServiceModel.FaultException`1 occurred
Message: A first chance exception of type 'System.ServiceModel.FaultException`1' occurred in Microsoft.Crm.Extensibility.dll
Additional information: An unexpected error occurred.

I'm not sure what your error is, but I would change the plugin to be Create, Post-Operation. It's still within the database transaction, but now the Target will exist so attempting to add the relationship will succeed rather than fail.

Related

Change record owner in Dynamics CRM plugin

I am writing a Post PLugin changing the owner. When the owner has a substitution manager, the owner is changed to the substitution manager. I tried a service.Update and an AssignRequest, but these throw an exception.
When I post the request my entity cannot update (and then throws "The request channel time out while waiting for reply after 10:00:00"). But like I see there is no recursion, because when I logged it I have only one repetition of log and it has stopped before or on line with update.
var assignedIncident = new AssignRequest
{
Assignee = substManagerRef, //get it throw another method, alreay checked in test it`s correct
Target = new EntityReference ("incident", incedentId)
};
service.Execute(assignedIncident);
I tried to write target in another way
Target = postEntityImage.ToEntityReference()
I tried to write simple update but the problem is the same.
Entity incident = new Entity("incident" , incidentId);
incident["ownerid"] = substManagerRef:
service.Update(incident);
Can somebody help me with that? Or maybe show the way to solve it)
The plugin is triggering itself and gets in a loop. The system only allows a maximum of 8 calls deep within plugins and that is the reason it throws an error and rolls back the transaction.
To solve this issue redesign your plugin in the following way:
Register your plugin on the Update message of your entity in the PreValidation stage.
In the plugin pick up the Target property from the InputParameters collection.
This is an Entity type. Modify or set the ownerid attribute on this Entity object.
That is all. You do not need to do an update, your modification is now passed into the plugin pipeline.
Note: for EntityReference attributes this technique only works when your plugin is registered in the PreValidation stage. For other regular attributes it also works in the PreOperation stage.

X++ doesn't skip AOS validation when it should

I've created a custom batchable class that is normally ran by a menu item calling SysOperationServiceController with the custom class name as the parameter. The custom class is marked as RunOn Server. In the code that I'm executing, I'm trying to delete a LogisticsLocation record, however, it's failing with error: "Cannot delete a record in Addresses (LogisticsPostalAddress).
The corresponding AOS validation failed." After stepping thru the logic of LogisticsPostalAddress.aosValidateDelete() code, I've found no good reason why this should fail, but this is not the reason for my question.
My goal is to attempt to bypass this AOS validation by logisticsLocation.skipAOSValidation(true). After working around the permission violation errors that I was getting, I found that I had to assert a SkipAOSValidationPermission first before skipping AOS validation. However, even though I do this, the aosValidateDelete() logic is still being hit. I'm also trying to avoid doing logisiticsLocation.doDelete() because I do want it to before the standard DeleteAction logic and cascade down to also delete the corresponding records.
Ultimately, my goal is to delete this record without error. And I cannot see any reason why it should fail, there is a DeleteAction with a Restricted option on LogisticsPostalAddress, however, it's for a table that doesn't have a relating record for. The logic inside LogisticsPostalAddress.aosValidateDelete() doesn't make sense altogether, which is why I'm looking to bypass. So my real question remains, why does it still attempt to AOS validate when I specifically tell it not to and I've jumped thru all the security hoops to do so? And how do I really skip this validation?
My Code:
while select dirPartyPostalAddressView
where dirPartyPostalAddressView.Party == dirPartyRecId //some local variable established earlier
join forUpdate logisticsLocation
where logisticsLocation.RecId == dirPartyPostalAddressView.Location
{
if (isRunningOnServer())
{
CodeAccessPermission::revertAssert();
skipValidPermission = new SkipAOSValidationPermission();
skipValidPermission.assert();
logisticsLocation.skipAosValidation(true);
}
logisticsLocation.delete();
}

Ignore Duplicate Dection Rules in CRM upon Creation of an Account Within Plugin

I'm attempting to create an account within a Qualification Event Plugin. If I am creating an account with a name that matches exactly a name of an existing account, my Duplicate Detection Rule kicks in, and causes an exception to be thrown.
It was my understanding that duplicate detection rules were always warnings, not errors, and by default, you wouldn't get any errors or even notifications when running from a Plugin/SDK call Is this a new change to CRM? Is there a way to ignore Duplicate Detection Rules from a plugin?
Apparently you have to set the "SupressDuplicateDetection" Attribute in the create request:
Entity target = new Entity("account");
target["name"] = "I am a clone";
CreateRequest req = new CreateRequest();
req.Target = target;
req["SuppressDuplicateDetection"] = true;
CreateResponse response = (CreateResponse)_service.Execute(req);
This is intended, and apparently long standing behaviour based on MSDN documentation Run duplicate detection (listed as far back at CRM 2011).
Pass the duplicate detection optional parameter
SuppressDuplicateDetection by adding a value to the Parameters
property of the CreateRequest and UpdateRequest message requests. The
SuppressDuplicateDetection parameter value determines whether the
Create or Update operation can be completed:
true – Create or update the record, if a duplicate is found.
false - Do not create or update the record, if a duplicate is found.
Assuming false is the default as its a bool.
If the duplicate detection optional parameter is set to false and a
duplicate is found, an exception is thrown and the record is not
created or updated.

SharePoint Business Connectiviy Data Model Update method failing

I have an external list in SharePoint that references a BCDM I created inside visual studio. The entity as an ID that is auto generated in the database, which means it's read-only.
Create and read method works fine, I'm trying to implement the update method. I have set an input parameter that match my entity and I'm getting this error.
Failed to update a list item for this external list based on the Entity(External Content Type) ‘Notification’ in EntityNamespace ‘Namespace’. Details: The TypeDescriptor with name ‘Id’ in the Method ‘Microsoft.SharePoint.BusinessData.MetadataModel.Static.Method’ on Entity (External Content Type) with Name ‘Namespace’ in Namespace ‘Notification’ is marked ‘PreUpdaterField’, but is contained by another TypeDescriptor marked ‘PreUpdaterField’.
I tried every possible combinaison to make this work, make the id type descriptor read only, pre-updater field = true/ false/, updater field = true/false, removing it, adding another parameter outside the entity. NOTHING WORKS !!! Obviously, I'm about to commit a murder as something so simple just turned out to be the biggest waste of time in my programmation history. What can I do to make this works??
This has been resolved and is explained here:
http://www.dotnetmikael.com/2014/02/sharepoint-2013-bcdm-with-visual-studio.html

Entity framework Conflicting changes detected. This may happen when trying to insert multiple entities with the same key

I have entity User with a couple of one-to-one and many-to-many relations and Identity primary key, and generic repository which created on each request.
I have an registration form with client and server validation and i decided to turn off client validation to test how server would behave in such case.
I turned off client validation to test the registration form and put some invalid values so i get back form saying that i have some errors, after i fixed that i got very interesting error
saying:
_context.SaveChanges(); //towing the error below:
Conflicting changes detected. This may happen when trying to insert multiple entities with the same key
It was strange for me because i detached the entity User but when i found this How to clean-up an Entity Framework object context?
so instead detaching only User entity i decided to try to clean object context completely running that code:
var objectStateEntries = this.objectContext
.ObjectStateManager
.GetObjectStateEntries(EntityState.Added);
foreach (var objectStateEntry in objectStateEntries)
{
if(objectStateEntry.Entity != null)
this.objectContext.Detach(objectStateEntry.Entity);
}
So after that all working well and i didn't get Conflicting changes detected error any more, but i am still wondering why such situation was taking place, may be some one may explain?
You may find your answer here:
context.ObjectStateManager.GetObjectStateEntries(System.Data.Entity.EntityState.Added| System.Data.Entity.EntityState.Unchanged);

Resources