OrganizationServiceProxy
in CRM 2011/2013 Plugins to use Early binding.
CRM 2011/2013 had an option to create a plugins using Early
binding or Late bindings.
If late binding is used, then the attributes values should be
hardcoded or create a constant class that contains the attribute names to achieve
it.
Early bound classes will contains the objects of entities in
which it can be used to do the CRUD operation etc. and there is no need of
hardcoding the attribute names. There are advantages and disadvantages working
with Early and Late binding. But I am not going to explain in this blog. The
below blogs will gives more information on overview, differences and how to use
it.
To use early bound types in a CRM2011 plugin and
enable this, It should either be add a ProxyTypesBeavior(), or set
.EnableProxyTypes. However, both of these properties apply to an
OrganizationServiceProxy class, and do not exist on the IOrganizationService
interface.
So if it uses IOrganizationService and try to do the CRM
transactions like the below, it fails in the highlighted red color in the bewlow example with an error “Attribute
regardingobjecttypecode must not be NULL if attribute regardingobjectid is not NULL”
protected void ExecuteTestPlugin(LocalPluginContext localContext)
{
if (localContext == null)
{
throw new ArgumentNullException("localContext");
}
IPluginExecutionContext context = localContext.PluginExecutionContext;
IOrganizationService service = localContext.OrganizationService;
XrmServiceContext sContext = new XrmServiceContext (service);
Opportunity opportunity = ((Entity)context.InputParameters["Target"]).ToEntity< XrmServiceContext >();
try
{
//to
do business logic
Opportunity opp = new Opportunity()
{
Name = “bla bla bla”,
OpportunityId =
opportunityClose.OpportunityId.Id
};
service.Update(opp);//Fail in this part
}
catch (FaultException<OrganizationServiceFault> e)
{
new InvalidPluginExecutionException("Error Test Plugin : " + e);
throw;
}
catch (Exception e)
{
new InvalidPluginExecutionException("Error Test Plugin : " + e);
throw;
}
}
To avoid this error, there is a below work around which will
work like a charm.
If the Plugin project created using Developer tool kit, then
in the “Plugin.cs” class, the below highlighted code should be added.
internal LocalPluginContext(IServiceProvider serviceProvider)
{
if (serviceProvider == null)
{
throw new ArgumentNullException("serviceProvider");
}
//
Obtain the execution context service from the service provider.
this.PluginExecutionContext =
(IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
//
Obtain the tracing service from the service provider.
this.TracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
//
Obtain the Organization Service factory service from the service provider
IOrganizationServiceFactory
factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
factory.GetType().GetProperty("ProxyTypesAssembly").SetValue(factory,
typeof(XrmServiceContext).Assembly, null);
//
Use the factory to generate the Organization Service.
this.OrganizationService = factory.CreateOrganizationService(this.PluginExecutionContext.UserId);
}
Happy Coding :)