Why is CRM 2011 Entity Relationship null in this plugin code?
this is a working example of a plugin that I have written for CRM 2011. I have created a 'Create' step in the plugin registration tool for this plugin. This executes fine. I also have an 'Update' step registered for the plugin. This fails to execute because the primary contact returned is null. These steps are both registered as asynchronous.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk;
using System.ServiceModel;
using System.IO;
using System.Net;
namespace CRMNewsletterPlugin
{
public class NewsletterSignup : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
// Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
tracingService.Trace("Begin load");
// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
tracingService.Trace("We have a target.");
// Obtain the target entity from the input parmameters.
Entity entity = (Entity)context.InputParameters["Target"];
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
if (!entity.GetAttributeValue<bool>("new_receivesnewsletter"))
{
try
{
//check if the account number exist
string emailAddress = entity.GetAttributeValue<string>("emailaddress1");
EntityReference primaryContact = entity.GetAttributeValue<EntityReference>("primarycontactid");
// UPDATE STEP FAILS HERE
if (primaryContact == null)
{
tracingService.Trace("Primary Contact is null");
}
Entity contact = service.Retrieve("contact", primaryContact.Id, new Microsoft.Xrm.Sdk.Query.ColumnSet(new string[] { "fullname" }));
string fullname = contact.GetAttributeValue<string>("fullname");
string name = entity.GetAttributeValue<string>("name");
WebRequest req = WebRequest.Create("http://localhost");
string postData = "cm-name=" + fullname + "&cm-ddurhy-ddurhy=" + emailAddress + "&cm-f-jddkju=" + name;
tracingService.Trace(postData);
byte[] send = Encoding.Default.GetBytes(postData);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = send.Length;
tracingService.Trace("Sending info");
Stream sout = req.GetRequestStream();
sout.Write(send, 0, send.Length);
sout.Flush();
sout.Close();
tracingService.Trace("Info sent");
WebResponse res = req.GetResponse();
StreamReader sr = new StreamReader(res.GetResponseStream());
string returnvalue = sr.ReadToEnd();
tracingService.Trace(returnvalue);
entity.Attributes["new_receivesnewsletter"] = true;
service.Update(entity);
tracingService.Trace("Newsletter field set");
}
catch (FaultException ex)
{
throw new InvalidPluginExecutionExceptio开发者_Go百科n("An error occurred in the plug-in.", ex);
}
}
}
}
}//end class
}
The entity contained in the InputParameters["Target"] only includes the changed fields that were submitted in the update, not all fields. Your plugin works for Create because InputParameters["Target"] always contains all fields during a Create obviously.
To fix this, you need to add a PreImage to your step in PluginRegistrationTool that includes the primarycontactid field. A PreImage will always include the values for the fields you specify as they were before the update.
The trick is to check for primarycontactid on InputParameters["Target"] first, because that would contain the latest value (if the user updated both new_receivesnewsletter and primarycontactid during the same save, for example). If InputParameters["Target"] doesn't contain primarycontactid, then fall back on your PreImage, accessed something like this (assuming you set your PreImage's alias to "preimage"):
context.PreEntityImages["preimage"].GetAttributeValue<EntityReference>("primarycontactid")
Hope that helps!
精彩评论