Using CrmDeploymentService CRM 4.0


We have a new webservice in CRM 4.0 i.e. CrmDeploymentService

This is the end-point for this web service

http://<servername%5B:port%5D>/mscrmservices/2007/crmdeploymentservice.asmx

Using CrmDeploymentService we can do the following

Create/Delete/Disable/Enable/Update/Set Default an organization etc.

There are two types of Microsoft Dynamics CRM deployment entities: Organization and Server. The Deployment SDK provides programmatic access for manipulating the Organization entity. It does not currently enable you to write code against the Server entity for actions such as enabling and disabling a Microsoft Dynamics CRM server.

We have a separate sdk for the Deployement.

We can download the sdk at the following location

http://www.microsoft.com/downloads/details.aspx?FamilyId=2874D878-E28D-4530-A185-4DEE1FCDD12E&displaylang=en

Some basic examples of using the service

// Create an instance of CrmDeploymentService

CrmDeploymentService myDeployService = new CrmDeploymentService();

myDeployService.Credentials = System.Net.CredentialCache.DefaultCredentials;

myDeployService.Url = ” valid url”;

// To retrieve server license type information

RetrieveLicenseRequest myLicRequest = new RetrieveLicenseRequest();

RetrieveLicenseResponse myLicResponse = (RetrieveLicenseResponse)myDeployService.Execute(myLicRequest);

MessageBox.Show(“License Type “ + myLicResponse.LicenseType.ToString());

// To get the organization information

RetrieveAllRequest myRetriveAllRequest = new RetrieveAllRequest();

// only organization is supported ( other is Server)

myRetriveAllRequest.EntityName = EntityName.Organization;

RetrieveAllResponse myRetriveAllResponse = (RetrieveAllResponse)myDeployService.Execute(myRetriveAllRequest);

foreach(DeploymentEntity myEntity in myRetriveAllResponse.Entities)

{

Organization myOrganization = (Organization)myEntity;

MessageBox.Show(myOrganization.FriendlyName);

MessageBox.Show(myOrganization.Id.ToString());

MessageBox.Show(myOrganization.UniqueName);

}

//// To disable an organization

SetStateOrganizationRequest myOrgSetStateRequest = new SetStateOrganizationRequest();

myOrgSetStateRequest.EntityName = EntityName.Organization;

myOrgSetStateRequest.Id = new Guid(“4c7fc991-0a41-dd11-bfd9-001d7d22e1af”);

myOrgSetStateRequest.State = OrganizationState.Disabled;

SetStateOrganizationResponse myOrgSetStateResponse =(SetStateOrganizationResponse) myDeployService.Execute(myOrgSetStateRequest);

Bye …..

Writing a simple custom workflow activity in CRM 4.0


Let’s create our first Custom Workflow Activity for CRM 4.0.

Check this post as well

https://nishantrana.wordpress.com/2008/10/30/custom-workflow-activities-in-crm-40/

We’ll take here a very simple scenario just to understand how to write custom activity.

This Custom Activity will take as input First Name and Last Name from an entity ( say Lead) and will update it’s description attribute with (First Name + Last Name).

Create a new Workflow Activity Library within workflow project type in Visual Studio.

(Keep the version as 3.0)

Name it MyFirstCustomWFlowActivity

Add references to Microsoft.crm.sdk.dll and Microsoft.crm.sdktypeproxy.dll.

Add the following line of code in your Activity1.cs.

using Microsoft.Crm.Workflow;

using Microsoft.Crm.Sdk;

We are creating a simple activity, so here we can have our class inherit from Activity class instead of SequenceActivity.

Delete the following class Activity1.Designer.cs as our simple custom activity doesn’t require that.


Decorate the class with CrmWorkflowActivity attribute

The first parameter is the user friendly name of the custom activity that will appear in the Workflow Editor and second parameter is the name of group, it can be used for grouping similar custom workflow activity.

namespace MyFirstCustomWFlowActivity

{

[CrmWorkflowActivity(“Get First and Last Name”, “Custom Steps”)]

public class Activity1: Activity

{

}

}

Now create three dependency properties, two as input for first name and last name and one as output where we will have full name i.e. first name and last name combined.

To create dependency property

Right click inside the visual studio editor then select insert snippet and followed by Workflow then DependencyProperty – Property.

We have used CrmInput and CrmOutput Attribute to make the dependency property visible within the workflow editor and to provide a user friendly name to them.

public static DependencyProperty FirstNameProperty = System.Workflow.ComponentModel.DependencyProperty.Register(“FirstName”, typeof(string), typeof(Activity1));

[CrmInput(“First Name”)]

public string FirstName

{

get

{

return ((string)(base.GetValue(Activity1.FirstNameProperty)));

}

set

{

base.SetValue(Activity1.FirstNameProperty, value);

}

}

public static DependencyProperty LastNameProperty = System.Workflow.ComponentModel.DependencyProperty.Register(“LastName”, typeof(string), typeof(Activity1));

[CrmInput(“Last Name”)]

public string LastName

{

get

{

return ((string)(base.GetValue(Activity1.LastNameProperty)));

}

set

{

base.SetValue(Activity1.LastNameProperty, value);

}

}

public static DependencyProperty FullNameProperty = System.Workflow.ComponentModel.DependencyProperty.Register(“FullName”, typeof(string), typeof(Activity1));

[CrmOutput(“Full Name”)]

public string FullName

{

get

{

return ((string)(base.GetValue(Activity1.FullNameProperty)));

}

set

{

base.SetValue(Activity1.FullNameProperty, value);

} }

Now comes the main part wherein we will override the Execute method and place our custom code to combine the first name and second name.

protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)

{

this.FullName = this.FirstName + this.LastName;

return ActivityExecutionStatus.Closed;

}

Now Sign the assembly

Right Click the project in Solution Explorer

Select Properties

Select Signing

Check Sign The Assembly Check box and Select an existing or new file.

Now build the assesbly.

Now we’ll register the assembly

Open the plugin registration tool

Select Register-Register New Assembly and Select the custom workflow assembly there (MyFirstCustomWFlowActivity.dll)

Click on Register Selected Plugins button to register it in the database.

Now open CRM and go to settings then workflow and create a new workflow there.

In Workflow editor you can see our custom steps group at Add Step.

Now you can proceed as you would with other workflow and add your business logic around the custom workflow activity.

Within Add Step you would be able to set value for first name and last name property within the form assistant panel.

And than we can add an Update step wherein we can get the fullname output property within local values section inside form assistant panel.

Bye..

Send Email in CRM using a Template (SendEmailFromTemplateRequest)


Hi using the following code we can send an email programmatically that uses the email-template withing CRM

Suppose you have created a web application and have a button named btnSendEmail over there.

Put the following code in it’s event handler

protected void btnSendEmail_Click(object sender, EventArgs e)

{

CrmAuthenticationToken token = new CrmAuthenticationToken();

token.AuthenticationType = 0; // AD ( On-Premise)

token.OrganizationName = “nameofyourorganization”;

CrmService myService = new CrmService();

myService.Credentials = System.Net.CredentialCache.DefaultCredentials;

myService.CrmAuthenticationTokenValue = token;

// Create an instance of email

email myEmail = new email();

//set the owner of the mail

myEmail.ownerid = new Owner();

myEmail.ownerid.type = EntityName.systemuser.ToString();

myEmail.ownerid.Value = new Guid(“26063267-7B85-DD11-B2E0-00164145E126”);

// specify the from part of the email

activityparty from = new activityparty();

from.partyid = new Lookup();

from.partyid.type = EntityName.systemuser.ToString();

// guid of the system user who is sending the mail

from.partyid.Value = new Guid(“24543267-7B85-DD11-B2E0-00164145E126”);

myEmail.from = new activityparty[] { from };

// specify the to part of the email

activityparty to = new activityparty();

to.partyid = new Lookup();

to.partyid.type = EntityName.systemuser.ToString();

to.partyid.Value = new Guid(“26063267-7B85-DD11-B2E0-00164145E126”);

myEmail.to = new activityparty[] { to };

TargetSendFromTemplateEmail myTargetSendFromTemplateEmail = new TargetSendFromTemplateEmail();

myTargetSendFromTemplateEmail.Email = myEmail;

SendEmailFromTemplateRequest mySendEmailFromTmpRequest = new SendEmailFromTemplateRequest();

// Specify entity instance id for RegardingID

mySendEmailFromTmpRequest.RegardingId = new Guid(“132C847E-028A-DD11-8E7E-00164145E126”);

// Specify the type of entity

mySendEmailFromTmpRequest.RegardingType = EntityName.opportunity.ToString();

// Specify the email instance to be sent

mySendEmailFromTmpRequest.Target = myTargetSendFromTemplateEmail;

// Specify the template to be used ( Either a global or created specfially for that entity)

mySendEmailFromTmpRequest.TemplateId = new Guid(“6963788F-048A-DD11-8E7E-00164145E126”);

SendEmailFromTemplateResponse mySendEmailFromTmpResponse =(SendEmailFromTemplateResponse)                                  myService.Execute(mySendEmailFromTmpRequest);

}

Bye….

0x80040220 SecLib::CrmCheckPrivilege failed. Returned hr = -2147220960 on UserId: dd80d8b7-6700-dd11-9838-001185e68627 and PrivilegeId: 0b609bc5-afb0-4576-8db0-7ad715375833 Platform


Hi,

We upgraded from CRM 3 to CRM 4, and certain users got this error while trying to access the CRM.

We realized that the users receiving this error had our own custom security role assigned to them. i.e System Primer.

When we assigned them any of the existing default security role there was no problem in accessing the CRM.

So the way we resolved was to assign a default security role and our own custom role to the user, so that he could access the system for the first time without any issues and

after the user has accessed it once than we removed the default security role.

This approach worked for us!!!!

Or another thing that worked was if we are assigning any custom role to users, we gave the write permission for user settings in that custom role.

the kb article for this error are

http://support.microsoft.com/kb/953962/en-us

http://support.microsoft.com/kb/952279/en-us

Bye

0x80041102 -the entity with ObjectTypeCode = 4408 was not found in the Metadata Cache. Platform


I was receiving this error while I was using the tool JSExportFromCRM – a useful tool to backup javascripts for CRM.

While looking for the same the solution I found was this

First I ran this query

SELECT * from entity WHERE objecttypecode = 4408

It returned nothing

Than I ran the following query and it

select * from organizationuibase where ObjectTypeCode = 4408

returned a row.

So ran the following query (i.e deleted that entry)

Delete from organizationuibase where ObjectTypeCode = 4408

And than again run the tool and it worked properly!!

Bye

Updating value in CRM entity in Callout written for Update event


 

Well we had a requriement in our case where we wanted to update a particular attribute value in our Crm’s opportunity entity in our update callout.

While looking for the same I came to know that if we are updating any attribute’s value in the entity against which we have attached our update callout, we will be lost in infinite loop.

Only way to do this is in the PreUpdate and there is a sample code for the same in sdk as well.(Unsupported)

public override PreCalloutReturnValue PreUpdate(CalloutUserContext userContext,CalloutEntityContext entityContext, ref string entityXml,ref string errorMessage)

Here we can see that the entityXml is passed to us as a reference. So any modification made to the entityXml would reflect back in that entity’s form as well.

Suppose this is the entityXml which we receive in our PreUpdate event

<?xml version=1.0 encoding=utf-16?>

<BusinessEntity xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:xsd=http://www.w3.org/2001/XMLSchema xsi:type=DynamicEntity Name=opportunity xmlns=http://schemas.microsoft.com/crm/2006/WebServices>

<Properties>

<Property xsi:type=KeyProperty Name=opportunityid>

<Value>57330ec3-6f5d-dd11-acd2-00164145e126</Value>

</Property>

<Property xsi:type=CrmFloatProperty Name=new_estimatedvalue>

<Value>1</Value>

</Property>

<Property xsi:type=CrmMoneyProperty Name=estimatedvalue>

<Value>77.5</Value>

</Property>

</Properties>

</BusinessEntity>

Now after running this code in our preUpdate event handler we can add a new property tag itself, which would be refering to the attribute we would like to update

// creating an xmlDocument

XmlDocument entityDoc = new XmlDocument();

// loading the entityXml in it

entityDoc.LoadXml(entityXml);

// the attribute which we would like to update

XmlElement totatForecastedValue = null;

// get the list of properties

XmlNodeList propertyList = entityDoc.GetElementsByTagName(“Property”);

XmlElement properties = (XmlElement)entityDoc.GetElementsByTagName(“Properties”)[0];

// creating an element with property tag

XmlElement totalForecastedElement = entityDoc.CreateElement(“Property”);

// creating an attribute type for the property tag

XmlAttribute typeAttrib = entityDoc.CreateAttribute(“type”);

totalForecastedElement.SetAttribute(“type”, http://www.w3.org/2001/XMLSchema-instance&#8221;, CrmFloatProperty”);

totalForecastedElement.SetAttribute(“Name”, “new_totalbilling”);

totatForecastedValue = entityDoc.CreateElement(“Value”);

// setting the value for the attribute

totatForecastedValue.InnerText = “10”;

totalForecastedElement.AppendChild(totatForecastedValue);

properties.AppendChild(totalForecastedElement);

 

//saving the output

StringWriter output = new StringWriter();

entityDoc.Save(output);

 

// assigning the same output to the entityXml

entityXml = output.ToString();

 

// Remove extra XML that will confuse CRM.

entityXml = entityXml.Replace(“xmlns=\”\””, “”);

entityXml = entityXml.Replace(“<?xml version=\”1.0\” encoding=\”utf-16\”?>”, “”);

The entityXml gets modified with the above code in this manner

<BusinessEntity xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:xsd=http://www.w3.org/2001/XMLSchema xsi:type=DynamicEntity Name=opportunity xmlns=http://schemas.microsoft.com/crm/2006/WebServices>

<Properties>

<Property xsi:type=KeyProperty Name=opportunityid>

<Value>57330ec3-6f5d-dd11-acd2-00164145e126</Value>

</Property>

<Property xsi:type=CrmFloatProperty Name=new_estimatedvalue>

<Value>1</Value>

</Property>

<Property xsi:type=CrmMoneyProperty Name=estimatedvalue>

<Value>77.5</Value>

</Property>

<Property xsi:type=CrmFloatProperty Name=new_totalbilling >

<Value>10</Value>

</Property>

</Properties>

</BusinessEntity>

 

And this way our entity gets updated as well.

And the same code in CRM 3.0 callout  works properly in case of upgrading the CRM 3.0 server to CRM 4.0 .

 

Bye..