CallerOrigin property of Plugin Context


We had one of our workflow running on create of lead which was updating one of the attribute in the lead. When the workflow was updating the record one of our plugin registered on the post update event of the lead was getting triggered. This was resulting in an error , so we had to update the post update plugin to include the callerOrigin to handle the things properly

if (context.CallerOrigin.ToString() != “Microsoft.Crm.Sdk.AsyncServiceOrigin”)

////////// our logic

}

CallerOrigin -Using it we can determine the origin of the call. Possible Values are

Static Property Description
Application Gets the caller orgin for the application.
AsyncService Gets the caller orgin for the async service.
WebServiceApi Gets the caller orgin for the Web services.

Bye…

Used SharedVariables in Microsoft Dynamics CRM 4.0


Today we wrote a plugin which was making use of new shared variables concept for plugin in Microsoft Dynamics CRM 4.0

We had one of our plugin registered in post create event of opportunity which was generating a unique number/id for that opportunity record (i.e auto-numbering).
Than we had to write one more plugin again for the same post create event of opportunity but in that plugin we wanted to access the value of that auto generated unique id.
So first what we did was changing the rank of the above two plugin i.e. execution order, if we are registering through plugin-registration tool.
For first plugin which used to generate the unique id we set the rank as 1
and for the second plugin we set it as 2.
But still we were not able to access the value of the unique id attribute in the second plugin.
Than we finally thought of making use of shared variables concept.

The SharedVariables property allows plug-ins to share data with each other. So the plugin which is getting fired first could put some data in the SharedVariables propertybag which than could be accessed by a plugin which is getting fired later.The order of execution of plugin depends on the rank set for it. However we should be careful of not creating too much dependencies among plug-ins.

So, in our first plugin we put the value in the shared variable
context.Properties.Add( new PropertyBagEntry(“MySharedVariable”, myAutoNumber));
and accessed it in the second plugin as following
String mySharedVariable = (string)context.[“MySharedVariable”];

Bye..

Checking for null or blank value in case of post update plugin using ForceSubmit


We were supposed to write a plugin against say entity A which would be updating a related entity B  only if the value of one of the attribute(string)  in entity A is blank.

The plugin was a post update one , so even though we had registered pre/post image with that particular attribute and as it was null, the property/value wasn’t getting passed.

So there was no way to access it in the entity images.

Only way to access the value was to make use of query expression class to get the value saved in the table for that entity. But we decided to use another approach.

Normally if we set a ForceSubmit on a particular field it is passed as one of the property of inputparameters of the context.

So what we did was set ForceSubmit on the field and then converted the inputparameters properties as Dynamic Entity and were able to get the value of that attribute even in case when it was null/blank.

DynamicEntity entity = (DynamicEntity)context.InputParameters.Properties[“Target”];

if (entity.Properties.Contains(“new_attSchemaName”))
{
String   myAttrValue = (string)entity.Properties[“new_attSchemaName”];
if (myAttrValue == “”)
{

//

Bye..

Update in pre update plugin in CRM


In previous version i.e. 3.0  on updating certain field in pre/post update used to lead to circular reference.

The only way to update in case of crm 3.0 was to modify the entityxml recieived as ref parameter for preUpdate event handler.

In CRM 4.0 to do the same we can add/update the properties passed as inputparameters to the context for pre-update.

public void Execute(IPluginExecutionContext context)
{
DynamicEntity entity = (DynamicEntity)context.InputParameters.Properties[“Target”];
if (entity.Name == EntityName.lead.ToString())
{

// firstname and lastname are already properties of the entity which are not null and

// therefore are passed as inputparamters

String firstName = “Nishant”;
entity.Properties[“firstname”] = firstName;

String lastName = “Rana”;
entity.Properties[“lastname”] = lastName;

//or setting a value of a field whose value is null i.e. not passed as inputparameter
StringProperty subject = new StringProperty(“subject”, “Test Subject”);
entity.Properties.Add(subject);

}
}

The above plugin is registered for lead’s pre-update event.

Using service.update would lead to “server is unable to process the request error” as it automatically checks for the circular reference, if the crmService has been created using context.CreateCrmService() method.

For CRM 3.0 refer this wonderful article

http://www.stunnware.com/crm2/topic.aspx?id=Callout2

Bye…

System.Data.SqlClient.SqlException: Setuser failed because of one of the following reasons: the database principal does not exist, its corresponding server principal does not have server access, this type of database principal cannot be impersonated, or you do not have permission.


We got this error while executing our plugin. Within plugin we were making sql call to fileteredViews.

For impersonation we were making use of SETUSER keyword.

The plugin was working fine in development and test server. But started giving the error in case of Production.

We replaced SETUSER with EXECUTE AS USER and everything was fine than.

http://blogs.msdn.com/crm/archive/2007/05/21/writing-crm-callouts-with-filtered-views.aspx

Bye…

Configuration Information for Plugin


Instead of creating a separate .config file for saving configuration info, now we can specify the configuration information for a plugin while we are registering it.

We just need to create a constructer for the plugin class

public class SharingEntity : IPlugin
{

string lscTempId = “”;
string lsuTempId = “”;

public SharingEntity(string unsecureConfiguration, string secureConfiguration)
{
XmlDataDocument doc = new XmlDataDocument();
doc.LoadXml(secureConfiguration);

lscTempId = doc.SelectSingleNode(“//LeadSharingCreate”).InnerText;
lsuTempId = doc.SelectSingleNode(“//LeadSharingUpdate”).InnerText;

………………….

The config info is specified as following
<Config>
<LeadSharingCreate>8a08c5ec-b6cd-dd11-a48d-00164145e126</LeadSharingCreate>
<LeadSharingUpdate>88E6872C-B7CD-DD11-A48D-00164145E126</LeadSharingUpdate>
</Config>

We have put the above info in the Secure Configuration area of the plugin registration dialog box, while registering the Step.

“The unsecureConfiguration is made available to plug-ins invoked both on the server and in the outlook client.The secureConfiguration is more secure and is only passed to the plug-in when it executes on the server. The secure configuration allows you to keep the information from being distributed to client machines that might be less secure.”