Using CreateMultiEntityAssociation method of CRMServiceClient for 1: n records.


Hi,

CreateMultiEntityAssociation method of CrmServiceclient can be used for associating 1 : n records i.e. if we have one contact record that we want to associate with multiple opportunity record ( 1-n) then we can use that method. This way we wont have to update each individual record.

http://msdn.microsoft.com/en-us/library/microsoft.xrm.tooling.connector.crmserviceclient.createmultientityassociation.aspx

Sample Code


Uri organizationUri = new Uri("http://server/crmrog/XRMServices/2011/Organization.svc");
Uri homeRealmUri = null;
ClientCredentials credentials = new ClientCredentials();
credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultCredentials;
OrganizationServiceProxy orgProxy = new OrganizationServiceProxy(organizationUri, homeRealmUri, credentials, null);

CrmServiceClient crmServiceClient = new CrmServiceClient(orgProxy);
List<Guid> lstOpportunityGuid = new List<Guid>();
lstOpportunityGuid.Add(new Guid("9DDCE989-0738-E411-9878-00155D56FF56"));
lstOpportunityGuid.Add(new Guid("019E1598-0738-E411-9878-00155D56FF56"));
lstOpportunityGuid.Add(new Guid("EA393A91-0738-E411-9878-00155D56FF56"));
crmServiceClient.CreateMultiEntityAssociation("contact", new Guid("CF1FC3C0-0738-E411-9878-00155D56FF56"), "opportunity", lstOpportunityGuid, "opportunity_customer_contacts");

Hope it helps ..

Calling a Windows Authenticated WCF Service in a Plugin in CRM


Hi,

Suppose we need to call the service created here in our plugin

https://nishantrana.me/2014/09/05/configure-a-wcf-service-for-windows-authentication/

As plugin don’t have configuration file, we need to specify binding information in Code.

The sample code to call the WCF Service by passing Network Credentials


private static void CallWCFService()
{
BasicHttpBinding binding = new BasicHttpBinding();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

// Specify the endpointAddress
EndpointAddress endpointAddress = new EndpointAddress(new Uri("http://servername:port/Service1.svc"));

ServiceReference1.Service1Client client = new ServiceReference1.Service1Client(binding, endpointAddress);
if (client.ChannelFactory.Credentials != null)
client.ChannelFactory.Credentials.Windows.ClientCredential = new System.Net.NetworkCredential("username", "password", "domain");
if (client.ClientCredentials != null)
client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
MessageBox.Show(client.GetData(1));
}

Hope it helps ..

 

 

Updated SOAPLogger for CRM 2013 to generate JavaScript


Hi,

We have tool called SOAPLogger (..\SDK\SampleCode\CS\Client\SOAPLogger\) that generates Soap request and response based on the C# code.

I have updated the tool to generate JavaScript that neatly wraps the Soap Request.

The output.txt and JavaScript code generated by the tool

Download the tool (convert .doc to .zip format)

https://nishantrana.me/wp-content/uploads/2014/08/soaplogger.doc

 

Hope it helps..

Microsoft Fakes and LINQ (Custom Workflow Activity) in CRM


Hi,

Just sharing a sample code to test a custom workflow activity using Microsoft Fakes.

The custom workflow activity uses LINQ.

The custom workflow activity code


public sealed class MyCustomWorkflowActivity : CodeActivity
{
#region Public Properties

[Input("Stage Name")]
public InArgument<string> StageName { get; set; }

#endregion

#region Methods

/// <summary>
/// Executes the workflow activity.
/// </summary>
/// <param name="executionContext">
/// The execution context.
/// </param>
protected override void Execute(CodeActivityContext executionContext)
{
// Create the tracing service
var tracingService = executionContext.GetExtension<ITracingService>();

// Create the context
var context = executionContext.GetExtension<IWorkflowContext>();

var serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();

IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

try
{
using (var xrmServiceContext = new XrmServiceContext(service))
{
// get the business process workflow id
var workflow = (from w in xrmServiceContext.WorkflowSet
where w.Name == "Business Process Workflow Name"
select new Workflow { WorkflowId = w.WorkflowId }).FirstOrDefault();

if (workflow != null)
{
// get the stage name from the context's input parameter
var stageName = this.StageName.Get<string>(executionContext);
var stage = (from s in xrmServiceContext.ProcessStageSet
where s.StageName == stageName && s.ProcessId.Id == workflow.WorkflowId
select new ProcessStage { ProcessStageId = s.ProcessStageId }).FirstOrDefault();

if (stage != null)
{
// update the sales state in the case record to which the above business process flow is associated
var incident = new Incident
{
Id = context.PrimaryEntityId,
StageId = stage.ProcessStageId
};
service.Update(incident);
}
}
}
}
catch (FaultException<OrganizationServiceFault> e)
{
tracingService.Trace("Exception: {0}", e.ToString());
throw;
}

}

Unit Test Code


public void UnitTestCustomWorkflowActivity()
{

var workflowUserId = Guid.NewGuid();
var workflowCorrelationId = Guid.NewGuid();
var workflowInitiatingUserId = Guid.NewGuid();

var service = new Microsoft.Xrm.Sdk.Fakes.StubIOrganizationService();

var workflowContext = new Microsoft.Xrm.Sdk.Workflow.Fakes.StubIWorkflowContext();
workflowContext.UserIdGet = () =>
{
return workflowUserId;
};
workflowContext.CorrelationIdGet = () =>
{
return workflowCorrelationId;
};
workflowContext.InitiatingUserIdGet = () =>
{
return workflowInitiatingUserId;
};

// ITracingService
var tracingService = new Microsoft.Xrm.Sdk.Fakes.StubITracingService();
tracingService.TraceStringObjectArray = (f, o) =>
{
Debug.WriteLine(f, o);
};

// IOrganizationServiceFactory
var factory = new Microsoft.Xrm.Sdk.Fakes.StubIOrganizationServiceFactory();
factory.CreateOrganizationServiceNullableOfGuid = id =>
{
return service;
};

SetBpfStage target = new SetBpfStage();

var wfEntity = new Workflow();
wfEntity.Id = Guid.NewGuid();
wfEntity["name"] = "abcabcabc";
var wfEntity1 = new Workflow();
wfEntity1.Id = Guid.NewGuid();
wfEntity1["name"] = "abcabcabc";

var processStageEntity = new ProcessStage();
processStageEntity.Id = Guid.NewGuid();
processStageEntity["name"] = "abcabcabc";
service.ExecuteOrganizationRequest = r =>
{
RetrieveMultipleResponse response = null;
if (((Microsoft.Xrm.Sdk.Query.QueryExpression)((RetrieveMultipleRequest)r).Query).EntityName
== "workflow")
{
List<Entity> entities = new List<Entity> { wfEntity };

response = new RetrieveMultipleResponse
{
Results =
new ParameterCollection
{
{
"EntityCollection",
new EntityCollection
(entities)
}
}
};

return response;
}

if (((Microsoft.Xrm.Sdk.Query.QueryExpression)((RetrieveMultipleRequest)r).Query).EntityName
== "processstage")
{

List<Entity> entities = new List<Entity> { processStageEntity };

response = new RetrieveMultipleResponse
{
Results =
new ParameterCollection
{
{
"EntityCollection",
new EntityCollection
(entities)
}
}
};

return response;
}

return response;
};

service.UpdateEntity = (p) =>
{
};

var invoker = new WorkflowInvoker(target);
invoker.Extensions.Add<ITracingService>(() => tracingService);
invoker.Extensions.Add<IWorkflowContext>(() => workflowContext);
invoker.Extensions.Add<IOrganizationServiceFactory>(() => factory);

var inputs = new Dictionary<string, object>
{
{ "StageName", "New" }
};

invoker.Invoke(inputs);
}

Hope it helps..

Using LINQ in CRM 2013


There are few ways we can make use of LINQ to write queries against CRM.

Using the early bound entity classes along with the generated service context

Use the CrmSvcUtil tool to generated the early bound entity classes and service context

CrmSvcUtil.exe /url:http://<serverName>/<organizationName>/XRMServices/2011/Organization.svc

/out:<outputFilename>.cs /username:<username> /password:<password> /domain:<domainName>

/namespace:<outputNamespace> /serviceContextName:<serviceContextName>

 

Uri organizationUri = new Uri("http://server/orgname/XRMServices/2011/Organization.svc");
 Uri homeRealmUri = null;</pre>
<pre> ClientCredentials credentials = new ClientCredentials();
 credentials.Windows.ClientCredential = new System.Net.NetworkCredential("username", "password", "domain");
 OrganizationServiceProxy orgProxy = new OrganizationServiceProxy(organizationUri, homeRealmUri, credentials, null);
 orgProxy.EnableProxyTypes();
 IOrganizationService _service = (IOrganizationService)orgProxy; 
 
 var xrmServiceContext = new XrmServiceContext(_service);
 // get all contact record that has first name as Hugh
 var lstContact = (from c in xrmServiceContext.ContactSet
 where c.FirstName == "Hugh"
 select c).ToList();
 foreach(var contact in lstContact)
 {
 MessageBox.Show(contact.FullName);
 }


Using Early bound entity classes and OrganizationServiceContext

Suppose we have the early bound entity classes but haven’t generated the service context. In this case we can use OrganizationServiceContext

 


var xrmServiceContext = new OrganizationServiceContext(_service);

var lstContact = (from c in xrmServiceContext.CreateQuery<Contact>()
 where c.FirstName == "Hugh"
 select c).ToList();

foreach (var contact in lstContact)
 {
 MessageBox.Show(contact.FullName);
 }

Using Late bound and OrganizationServiceContext

Suppose we are not generating the early bound classes and using late binding

 

 


  var xrmServiceContext = new OrganizationServiceContext(_service);

 var lstContact = (from c in xrmServiceContext.CreateQuery("contact")
 where c["firstname"] == "Hugh"
 select c).ToList();

 foreach (var contact in lstContact)
 {
 MessageBox.Show(contact["fullname"].ToString());
 }

Hope it helps..

 

“the specified type is not a known entity type” error while using early bound entity classes in CRM 2013


Hi,

We were writing a custom workflow activity that was using LINQ (early bound).

Here we had used ILMerge to merge the early bound assemblies with the workflow assembly.

The solution was to place the following attribute in the AssemblyInfo.cs of the workflow assembly (same goes for Plugin Assembly)

[assembly: Microsoft.Xrm.Sdk.Client.ProxyTypesAssemblyAttribute()]

 

The helpful thread

http://social.microsoft.com/Forums/en-US/7c05f900-f930-46b3-a233-75a94ffca9c5/how-to-make-the-crm-2011-plugin-detect-types-from-early-bound-organisation-class?forum=crmdevelopment

Hope it helps..