Hi Developers,
I have been wondering about this issue for a week so far, I wouldn't have reached out for your help if it was not really needed.
Last week I started developing CRM Dynamics 365 online. I was asked to create an auto-generated field in Work Order entity that sets its value based on its service account. I have decided to do this through plugin development and I have successfully registered the plugin in the Pre-Operation of Create Step and I was able to debug my code and do the business logic correctly Backend wise. What I have found weird while debugging my code was
the new created field was not available in the entity.Attributes Call.
I neglected that as I thought since it doesn't contain any data yet maybe it is not available in the attributes, so I used entity.Attributes.add. But even though the value was set in the WO create Form after saving. I have been searching for what could be causing such an issue for about a week and your help will be much appreciated. Thank You.
using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using System.ServiceModel.Description; using System.Text; using System.Threading.Tasks; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; using Microsoft.Xrm.Sdk.Client; using Microsoft.Xrm.Sdk.Messages; using Microsoft.Xrm.Sdk.Discovery; namespace WorkOrder { public class WorkOrder : IPlugin { public void Execute(IServiceProvider serviceProvider) { // Extract the tracing service for use in debugging sandboxed plug-ins. // If you are not registering the plug-in in the sandbox, then you do // not have to add any tracing service related code. ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); // Obtain the execution context from the service provider. IPluginExecutionContext context = (IPluginExecutionContext) serviceProvider.GetService(typeof(IPluginExecutionContext)); // The InputParameters collection contains all the data passed in the message request. if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity) { // Obtain the target entity from the input parameters. Entity entity = (Entity)context.InputParameters["Target"]; // Verify that the target entity represents an entity type you are expecting. // For example, an account. If not, the plug-in was not registered correctly. if (entity.LogicalName != "msdyn_workorder") return; // Obtain the organization service reference which you will need for // web service calls. IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); var account = (Microsoft.Xrm.Sdk.EntityReference)(entity.Attributes["msdyn_serviceaccount"]); var actualAccount = service.Retrieve(account.LogicalName, account.Id, new ColumnSet(true)); var nameField = actualAccount.Id; try { QueryExpression query = new QueryExpression("msdyn_workorder"); query.ColumnSet.AddColumns("msdyn_serviceaccount", "new_workordernumber"); query.Criteria = new FilterExpression(); query.Criteria.AddCondition("msdyn_serviceaccount", ConditionOperator.Equal, nameField); Entity wo =service.RetrieveMultiple(query).Entities[0]; var x = entity.GetAttributeValue<string>("new_workordernumber"); var y = wo.GetAttributeValue<string>("new_workordernumber"); if (y == null) { entity.Attributes.Add("new_workordernumber", "1"); } else { entity.Attributes.Add("new_workordernumber", "2"); } } catch (FaultException<OrganizationServiceFault> ex) { throw new InvalidPluginExecutionException("An error occurred in MyPlug-in.", ex); } catch (Exception ex) { tracingService.Trace("MyPlugin: {0}", ex.ToString()); throw; } } } } }
*This post is locked for comments
Yes it exists as an unmanaged Field.
Does new_workordernumber exist on the workorder entity?
I've created this plugin on the pre-create of account and it works just fine.
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Linq;
using System.ServiceModel;
namespace MG
{
public class PreOperationaccountCreate : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = factory.CreateOrganizationService(context.UserId);
var entity = (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity) ? (Entity)context.InputParameters["Target"] : null;
if(entity != null)
entity["name"] = "THIS IS A TEST";
}
}
}
Yeah Pre- Operation Create synchronous
Are you sure that your plugin runs on pre-create and synchronous?
Unfortunately, even with this simple code no data updated on the form. when I debugged my code it retrieved the entity correctly with its correct .
First get rid of all the extra's and try this:
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Linq;
using System.ServiceModel;
namespace MG
{
public class WorkOrder : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// Extract the tracing service for use in debugging sandboxed plug-ins.
// If you are not registering the plug-in in the sandbox, then you do
// not have to add any tracing service related code.
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
// Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
// Obtain the target entity from the input parameters.
Entity entity = (Entity)context.InputParameters["Target"];
// Verify that the target entity represents an entity type you are expecting.
// For example, an account. If not, the plug-in was not registered correctly.
if (entity.LogicalName != "msdyn_workorder")
return;
entity.Attributes.Add("new_workordernumber", "THIS IS A TEST");
}
catch (FaultException<OrganizationServiceFault> ex)
{
throw new InvalidPluginExecutionException("An error occurred in MyPlug-in.", ex);
}
catch (Exception ex)
{
tracingService.Trace("MyPlugin: {0}", ex.ToString());
throw;
}
}
}
}
}
Still no data previewed on the form.
Thank you for your reply, the business logic is to create a WO number starting from 1 based on its service account. for example WO number for account x =1 WO number for account y =1 Second WO for account X = 2. I have just put static data to debug my code concerning the not being able to view the updated(created) field on the form.
I've optimized the code a little bit. But I see a few strange things. See the comments. And where is this part?
I was asked to create an auto-generated field in Work Order entity that sets its value based on its service account.
You retrieve the account but then nothing happens.
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Linq;
using System.ServiceModel;
namespace MG
{
public class WorkOrder : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// Extract the tracing service for use in debugging sandboxed plug-ins.
// If you are not registering the plug-in in the sandbox, then you do
// not have to add any tracing service related code.
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
// Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
// Obtain the target entity from the input parameters.
Entity entity = (Entity)context.InputParameters["Target"];
// Verify that the target entity represents an entity type you are expecting.
// For example, an account. If not, the plug-in was not registered correctly.
if (entity.LogicalName != "msdyn_workorder")
return;
// Obtain the organization service reference which you will need for
// web service calls.
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
try
{
if (entity.Contains("msdyn_serviceaccount"))
{
var accountId = entity.GetAttributeValue<EntityReference>("msdyn_serviceaccount").Id;
//This line is not needed
var account = service.Retrieve("account", accountId, new ColumnSet(true)); //ColumnSet(true) :(
//What does this line?
var nameField = account.Id;
//Why retrieve the first workorder??
var workOrder = RetrieveWorkOrder(service, nameField);
var x = entity.GetAttributeValue<string>("new_workordernumber");
if (workOrder != null)
{
var y = workOrder.GetAttributeValue<string>("new_workordernumber");
if (y == null)
{
entity.Attributes.Add("new_workordernumber", "1");
}
else
{
entity.Attributes.Add("new_workordernumber", "2");
}
}
}
}
catch (FaultException<OrganizationServiceFault> ex)
{
throw new InvalidPluginExecutionException("An error occurred in MyPlug-in.", ex);
}
catch (Exception ex)
{
tracingService.Trace("MyPlugin: {0}", ex.ToString());
throw;
}
}
}
private Entity RetrieveWorkOrder(IOrganizationService service, Guid nameField)
{
var query = new QueryExpression("msdyn_workorder");
query.TopCount = 1;
query.ColumnSet.AddColumns("msdyn_serviceaccount", "new_workordernumber");
query.Criteria.AddCondition("msdyn_serviceaccount", ConditionOperator.Equal, nameField);
var result = service.RetrieveMultiple(query);
if (result != null && result.Entities.Any())
return result.Entities.First();
return null;
}
}
}
Stay up to date on forum activity by subscribing. You can also customize your in-app and email Notification settings across all subscriptions.
André Arnaud de Cal... 291,188 Super User 2024 Season 2
Martin Dráb 230,030 Most Valuable Professional
nmaenpaa 101,156