Custom Get Started Pane for help or video file


Let’s suppose we want to embed a video or html help file for Account entity on Get Started Pane of Account entity.

The default content for the get started pane is located with the Help content. The content is exposed in the application through attributes in the <SubArea> (SiteMap) element for specific entities. This content cannot be included in a solution and, therefore, cannot be transported with a solution.

To create custom get started pane content, the Microsoft Dynamics CRM SDK includes a set of files that replicate the appearance and behavior of the get started pane pages. These files are located at SDK\Resources\GetStartedPaneTemplate.

Below are steps to create custom get started pane.

Steps:

We want to place a custom video and help file on Get Started Pane of Account entity.

Step #1 Import solution “helpvisorcomponents_1_0_0_0” which is available at \sdk\resources\getstartedpanetemplate of CRM 2011 sdk.

Step #2 Create a virtual directory (Let’s say” Video”) on server in ISV folder of CRMWeb
and keep the video file there. Update the below url in helpvisortemplate1.htm file.
URL: http://<CrmServer>:5555/ISV/Video/newCRMjquery_ch9.wmv

Step #3 Edit the “helpvisortemplate.htm” file which is at \sdk\resources\getstartedpanetemplate\helpvisor\1033 of CRM 2011 Sdk and rename the file name as helpvisortemplate1.htm .

Step #4 Create html help file say Help.htm.

Step #5 Create below Web Resources in same solution with similar structure as below

sample_/1033/HelpVisorTemplate1.htm
sample_/1033/Content/Help.htm

Step #6 Add the Site Map to existing solution and export it for editing.

Step #7 Open customization.xml file from exported solution in edit mode.

Replace below code (Usually at 4 places)

<SubArea Id=”nav_accts” DescriptionResourceId=”Account_SubArea_Description” Entity=”account” GetStartedPanePath=”Accounts_Web_User_Visor.html” GetStartedPanePathAdmin=”Accounts_Web_Admin_Visor.html” GetStartedPanePathOutlook=”Accounts_Outlook_User_Visor.html” GetStartedPanePathAdminOutlook=”Accounts_Outlook_Admin_Visor.html” />
With below code
<!–
<SubArea Id=”nav_accts” DescriptionResourceId=”Account_SubArea_Description” Entity=”account” GetStartedPanePath=”Accounts_Web_User_Visor.html” GetStartedPanePathAdmin=”Accounts_Web_Admin_Visor.html” GetStartedPanePathOutlook=”Accounts_Outlook_User_Visor.html” GetStartedPanePathAdminOutlook=”Accounts_Outlook_Admin_Visor.html” />
–>

<SubArea Id=”nav_accts” DescriptionResourceId=”Account_SubArea_Description” Entity=”account” GetStartedPanePath=”$webresource:sample_/redir.htm?data=HelpVisorTemplate1.htm” GetStartedPanePathAdmin=”$webresource:sample_/redir.htm?data=HelpVisorTemplate1.htm” GetStartedPanePathOutlook=”$webresource:sample_/redir.htm?data=HelpVisorTemplate1.htm” GetStartedPanePathAdminOutlook=”$webresource:sample_/redir.htm?data=HelpVisorTemplate1.htm” />

Step #8 Save the customization.xml file
Step #9 Zip all the file with updated customization.xml
Step #10 Import the updated solution and publish all customization.
Step #11 the final output should look like as below.
Step #12 on click of video link; it will play a custom video (not out of box) file in media player and “Help”
link will open html help file.

 

Create contact and share the record which contains Lookup,Picklist and string datatype


This sample will show how to create Contact record in CRM 4.o through Web Application which contains Lookup, Picklist and String datatype.

I have created a custom entity(new_hobby) and created a 1-N relationship from Hobby to Contact. I have also created Team called CRM Team and added members to that team. Whenever a contact will be created, contact will be shared to the CRM Team which have only Read Access to that contact.

First create Web Reference to CrmService and MetaDataService  to create proxy class and include this into project with the help of using statement.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using CrmPractice.CrmSdk;
using System.Web.Services.Protocols;
using CrmPractice.MetaDataSdk;
namespace CrmPractice
{
public partial class _Default : System.Web.UI.Page
{
public static Dictionary<string, string> dics = new Dictionary<string, string>();
public static Dictionary<string, string> AddDics = new Dictionary<string, string>();
List<ListItem> HobbyList = new List<ListItem>();
List<ListItem> Addlist = new List<ListItem>();
string teamId = string.Empty;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
CrmService service = GetCrmService();
CrmPractice.MetaDataSdk.MetadataService metadataService = GetMetaDataService();

//Populate Lookup Value
PopulateLookupValue(service);

//Populate Picklist Value using metadataservice
GetPickListValue(metadataService);
}
}

protected void btnSubmit_Click(object sender, EventArgs e)
{
try
{
CrmService service = GetCrmService();

//Create contact record
contact conts = new contact();
conts.firstname = txtFirstName.Text;
conts.lastname = txtLastName.Text;
conts.mobilephone = txtMobileNo.Text;

// Set Hobby Lookup value

Lookup hobbyLookup = new Lookup();
hobbyLookup.name = ddlHobby.SelectedItem.Value.ToString();
hobbyLookup.type = EntityName.new_hobby.ToString();
hobbyLookup.Value = new Guid(dics[ddlHobby.SelectedItem.Value.ToString()]);
conts.new_hobbyid = hobbyLookup;

// Set AddressType Picklist value

Picklist addPickList=new Picklist();
addPickList.name=ddlAddressType.SelectedItem.Value.ToString();
addPickList.Value=Convert.ToInt16(AddDics[ddlAddressType.SelectedItem.Value.ToString()]);

conts.address1_addresstypecode = addPickList;
conts.emailaddress1  = txtEmailId.Text;

//Create Contact
Guid contactId = service.Create(conts);

// Get Team id to share the record
teamId = GetTeamId(service);

// Share record with Team
ShareWithTeam(service, contactId.ToString(), teamId);

//Clear the field
ClearField();
}
catch(SoapException ex)
{
ex.Detail.InnerText.ToString();
}
}

/// <summary>

/// /Populate Hobbylist from CRM and bind it with DropDownlist

/// </summary>

/// <param name=”service”>CRM Service</param>

private void PopulateLookupValue(CrmService service)
{
try
{
ColumnSet cols = new ColumnSet();
cols.Attributes = new string[] { “new_name”, “new_hobbyid”, };

OrderExpression order = new OrderExpression();
order.AttributeName = “new_name”;
order.OrderType = OrderType.Ascending;

QueryExpression query = new QueryExpression();
query.ColumnSet = cols;
query.EntityName = EntityName.new_hobby.ToString();
query.Orders = new OrderExpression[] { order };

BusinessEntityCollection hobbies = service.RetrieveMultiple(query);

DropDownList hb = new DropDownList();
for (int i = 0; i < hobbies.BusinessEntities.Length; i++)
{
new_hobby hobby = (new_hobby)hobbies.BusinessEntities[i];
dics.Add(hobby.new_name.ToString(), hobby.new_hobbyid.Value.ToString());
HobbyList.Add(new ListItem(hobby.new_name.ToString(), hobby.new_hobbyid.Value.ToString()));
hb.Attributes.Add(hobby.new_name.ToString(), hobby.new_hobbyid.Value.ToString());
}

ddlHobby.DataSource = HobbyList;
ddlHobby.DataBind();
}
catch (SoapException ex)
{
ex.Detail.InnerText.ToString();
}
}

/// <summary>

/// Get Picklist value using metadata service and bind

/// it with dropdown

/// </summary>

/// <param name=”metaDataService”>MetaDataService</param>

private void GetPickListValue(MetadataService metaDataService)
{
try
{
DropDownList address = new DropDownList();

AttributeMetadata metadata = new AttributeMetadata();
RetrieveAttributeRequest attributeRequest = new RetrieveAttributeRequest();
attributeRequest.EntityLogicalName = EntityName.contact.ToString();
attributeRequest.LogicalName = “address1_addresstypecode”;

RetrieveAttributeResponse attributeResponse = (RetrieveAttributeResponse)metaDataService.Execute(attributeRequest);

PicklistAttributeMetadata addressType = (PicklistAttributeMetadata)attributeResponse.AttributeMetadata;
for (int i = 0; i < addressType.Options.Length; i++)
{
AddDics.Add(addressType.Options[i].Label.UserLocLabel.Label, addressType.Options[i].Value.Value.ToString());
Addlist.Add(new ListItem(addressType.Options[i].Label.UserLocLabel.Label, addressType.Options[i].Value.Value.ToString()));
}
ddlAddressType.DataSource = Addlist ;
ddlAddressType.DataBind();

}

catch (SoapException ex)

{

ex.Detail.InnerText.ToString();

}

}

/// <summary>

/// Get CrmService

/// </summary>

/// <returns>CrmService</returns>

private CrmService GetCrmService()
{
CrmPractice.CrmSdk.CrmAuthenticationToken token = new CrmPractice.CrmSdk.CrmAuthenticationToken();
token.AuthenticationType = 0;
token.OrganizationName = “CMDev”;

CrmService service = new CrmService();
service.Url = http://<CrmServer>/mscrmservices/2007/crmservice.asmx;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
service.CrmAuthenticationTokenValue = token;
return service;
}

/// <summary>

/// Get Metadata service

/// </summary>

/// <returns>MetaDataService</returns>

private MetaDataSdk.MetadataService  GetMetaDataService()
{
CrmPractice.MetaDataSdk.CrmAuthenticationToken token = new CrmPractice.MetaDataSdk.CrmAuthenticationToken();
token.AuthenticationType = 0;
token.OrganizationName = “CMDev”;
MetaDataSdk.MetadataService  service = new MetaDataSdk.MetadataService();
service.Url = http://<CrmServer>/mscrmservices/2007/metadataservice.asmx;
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
service.CrmAuthenticationTokenValue = token;
return service;
}

/// <summary>

/// Get TeamId to share the record

/// </summary>

/// <returns>Team Id</returns>

private string GetTeamId(CrmService service)
{
// Query express to find out team id to share the rescord
QueryByAttribute query = new QueryByAttribute ();
query.EntityName =EntityName.team.ToString();

ColumnSet cols = new ColumnSet ();
cols.Attributes=new string[]{“teamid”};

query.ColumnSet = cols;query.Attributes =new string[] { “name”};
query.Values =new string[] { “CRM Team” };

BusinessEntityCollection retrieved = (BusinessEntityCollection)service.RetrieveMultiple(query);
if(retrieved.BusinessEntities.Length> 0 )
{
team newTeam = (team )retrieved.BusinessEntities[0];
CrmPractice.CrmSdk.Key teamGuid = (CrmPractice.CrmSdk.Key )newTeam.teamid;
teamId = teamGuid.Value.ToString();
}
return teamId;
}

private void ShareWithTeam(CrmService service,string recordId,string teamId)
{
// Create the SecurityPrincipal Object
SecurityPrincipal principal = new SecurityPrincipal();
principal.Type = SecurityPrincipalType.Team;

// PrincipalId is the Guid of the user to whom access is being granted
principal.PrincipalId = new Guid(teamId);

// Create the PrincipalAccess Object
PrincipalAccess principalAccess = new PrincipalAccess();

// Set the PrincipalAccess Object’s Properties
principalAccess.Principal = principal;

// Gives the principal access to read
principalAccess.AccessMask = AccessRights.ReadAccess;

// Create the Target Object for the Request
TargetOwnedContact  target = new TargetOwnedContact();

// EntityId is the Guid of the contact access is being granted to
target.EntityId = new Guid(recordId);

// Create the Request Object
GrantAccessRequest grant = new GrantAccessRequest();

// Set the Request Object’s properties
grant.PrincipalAccess = principalAccess;
grant.Target = target;

// Execute the Request
GrantAccessResponse granted = (GrantAccessResponse)service.Execute(grant);
}
private voidClearField()
{
txtFirstName.Text=””;
txtLastName.Text=””;
txtMobileNo.Text=””;
txtEmailId.Text=””;
}
}
} 

Hope its help you 🙂

Moving CRM Servers(Application and Database) to New DataCentre


One of our client wanted to move CRM Server from One Data Centre to different data centre but due to some constraint we could not move it by creating New Organization or by new deployment. We had only left option was update IP address manually.

Recently we moved our CRM Server from one data centre to new data centre due to which IP Address of both Application and Database Server was changed. We had updated new IP Address in Registry(MSCRMconfigdb,database,LocalSdkHost,metabase,ServerUrl,SQLRSServerUrl), Application Pool, Web.Config and custom application. But even after updating new IP address on above section  we were getting the following error.

A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 172.23.201.162:80

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 172.23.201.162:80

Source Error:

An unhandled exception was generated during the execution   of the current web request. Information regarding the origin and location of   the exception can be identified using the exception stack trace below.

Stack Trace:

 
[SocketException (0x274c): A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 172.23.201.194:80]
   System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress) +239
   System.Net.Sockets.Socket.InternalConnect(EndPoint remoteEP) +35
   System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Int32 timeout, Exception& exception) +224

[WebException: Unable to connect to the remote server]
   System.Net.HttpWebRequest.GetRequestStream(TransportContext& context) +1868309
   System.Net.HttpWebRequest.GetRequestStream() +13
   System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) +103
   Microsoft.Crm.Metadata.MetadataWebService.GetDataSet() +31
   Microsoft.Crm.Metadata.DynamicMetadataCacheLoader.LoadDataSetFromWebService(Guid orgId) +291
   Microsoft.Crm.Metadata.DynamicMetadataCacheLoader.LoadCacheFromWebService(LoadMasks masks, Guid organizationId) +42
   Microsoft.Crm.Metadata.DynamicMetadataCacheFactory.LoadMetadataCache(LoadMethod method, CacheType type, IOrganizationContext context) +408
   Microsoft.Crm.Metadata.MetadataCache.LoadCache(IOrganizationContext context) +339
   Microsoft.Crm.Metadata.MetadataCache.GetInstance(IOrganizationContext context) +388
   Microsoft.Crm.BusinessEntities.BusinessEntityMoniker..ctor(Guid id, String entityName, Guid organizationId) +116
   Microsoft.Crm.Caching.UserDataCacheLoader.LoadCacheData(Guid key, ExecutionContext context) +323
   Microsoft.Crm.Caching.ObjectModelCacheLoader`2.LoadCacheData(TKey key, IOrganizationContext context) +401
   Microsoft.Crm.Caching.BasicCrmCache`2.CreateEntry(TKey key, IOrganizationContext context) +84
   Microsoft.Crm.Caching.BasicCrmCache`2.LookupEntry(TKey key, IOrganizationContext context) +135
   Microsoft.Crm.BusinessEntities.SecurityLibrary.GetUserInfoInternal(WindowsIdentity identity, IOrganizationContext context, UserAuth& userInfo) +252
   Microsoft.Crm.BusinessEntities.SecurityLibrary.GetCallerAndBusinessGuidsFromThread(WindowsIdentity identity, Guid organizationId) +179
   Microsoft.Crm.Authentication.CrmWindowsIdentity..ctor(WindowsIdentity innerIdentity, Boolean publishCrmUser, Guid organizationId) +252
   Microsoft.Crm.Authentication.WindowAuthenticationProviderBase.Authenticate(HttpApplication application) +431
   Microsoft.Crm.Authentication.AuthenticationStep.Authenticate(HttpApplication application) +172
   Microsoft.Crm.Authentication.AuthenticationPipeline.Authenticate(HttpApplication application) +86
   Microsoft.Crm.Authentication.AuthenticationEngine.Execute(Object sender, EventArgs e) +525
   System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +68
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75

 

Actually It was still referring Old IP Address at some places. To resolve the issue we enable the trace log and get CrmServerReportInformation with help of “Create File” option of  CrmDiagTool 4.0  and came to know that DeploymentProperty Table(Column Name- ADSdkRootDomain, ADWebApplicationRootDomain and AsyncSdkRootDomain) of MSCRM_Config was still referring old IP Address. We have updated this column with new IP Address as below and everything start working fine.

USE MSCRM_CONFIG

Update DeploymentProperties SET NVarCharColumn = ‘New IP Address’  WHERE ColumnName= ‘AsyncSdkRootDomain’

Update DeploymentProperties SET NvarCharColumn = ‘New IP Address’  WHERE ColumnName = ‘ADSdkRootDomain’

Update DeploymentProperties SET NvarCharColumn = ‘New IP Address’  WHERE ColumnName = ‘ADWebApplicationRootDomain’

 

Hope this help you 🙂

Interacting Silverlight with CRM Forms


Silverlight application can get a reference to the Xrm.Page Object instance using either of following approaches.

1. Using HTML bridge feature of Silverlight

ScriptObject  xrm = (ScriptObject)HtmlPage.Window.GetProperty(“Xrm”);

ScriptObject  page= (ScriptObject)xrm.GetProperty(“Page”);

2. Using Dynamic Language Runtime

Using DLR you can utilize the dynamic language keywords which allow resolving method calls at runtime.

dynamic  xrm = (ScriptObject)HtmlPage.Window.GetProperty(“Xrm”);

 

Below is some important methods/property which is useful for Silverlight Application.

1. Getting the current Theme: This is useful if you are trying to style your Silverlight content in a similar way the user will see the web client. Valid Values are Default, Office12Blue, and Office14Silver.

var theme= xrm.Page.context.getCurrentTheme();

2.      Getting Org Name:

var orgName= xrm.Page.context.getOrgUniqueName();

3.      Getting the Server URL:

var serverUrl = xrm.Page.context.getServerUrl();

4.      Getting the User ID:

Knowing the user id that is working with the current page can be helpful when you need to do things like retrieve all the records that are owned by that person to present on the page.

 

var  userID = xrm.Page.context.getUserId();

5.      Getting the user’s Role:

var roles = xrm.Page.context.getUserRoles();

6.      Getting the entity logical Name:

String entityname =xrm.Page.data.entity.getEntityName();

7.      Getting the Entity Id:
Guid entityID = xrm.Page.data.entity.getId();

8.      Checking if Entity is Dirty:

By checking the dirty flag at the entity level you can quickly determine if there have been any changes to any of the fields. This doesn’t give you field level granularity you have to check each attribute if you need that.

bool isDirty = xrm.Page.data.entity.getIsDirty();

9.      Getting the Data as XML:

Using this feature you can get a string that represents the XML that would be sent to the server when the record is saved. The XML contains only the fields which have been modified.

String dataXml = xrm.Page.data.entity.getDataXml();

10.  Saving Data to the Server:

The save function allows you to simulate saving data to the CRM server just like if the user hit the save button in the ribbon.

Xrm.Page.data.entity.save()
or
Xrm.Page.data.entity.save(“saveandclose”)
or
Xrm.Page.data.entity.save(“saveandnew”)

11.  Working with the Entity Attributes

You can get to the attributes on an entity via the Attributes collection. The different attribute types can have special methods that are only for their specific type.The following shows which methods each type of attribute currently has.

All Attribute have these methods:

addOnChange,fireOnChange, getAttributeType,getFormat,getInitialValue, getIsDirty, getName, getParent,getRequiredLevel, getSubmitMode, getUserPrivelege, getValue, removeOnChange, setRequiredLevel, setSubmitMode, and setValue

Money,decimal,integer and double have these methods too:

getMax, getMin, and getPrecision

Boolean and Optioset attributes have these methods:

getInitalValue

Optionset attributes have these methods:

getOption, getOptions, getSelectedOption, and getText

 

12.  UI Methods:

The UI methods are high level methods located at Xrm.page.ui and are the starting point for working with the UI controls. This is also the starting point for looking for Controls and Tabs.

Refreshing the Ribbon:

This method is beyond helpful if you are doing any enable/display rules that depends on values on the form. After the value is changed on the form you can use this method to force the ribbon to re-evaluate the data in the form so the ribbon is updated.

refreshRibbon();

13.  Working with Form Controls:

The following methods are on all controls:

getControlType, getDisabled, getLabel, getName, getParent, setDisabled(all except web resources), setFocus, setLabel, and setVisible

The following methods are specific to Lookups;

addCustomeView, getDefaultView, and setDefaultView

The following methods are specific to Option Sets

adoption,clearOptions, and removeOption

The following methods are specific to Web Resources:

getData, getObject, setData, keep in mind the get/setData can only be used with Silverlight Web resources

The Following methods are specific to IFrames:

getSrc, setSrc, and getInitalUrl

The following methods are specific to Subgrids:

refresh

Differences between Data Migration and Data Import


As mentioned in CRM Sdk, below is the major differences between Data Migration and Data Import.

Data migration and data import use common entity model and messages. However, there are some important differences in the feature sets of the two operations as shown in the following table.

Feature Data Migration Data Import
Import data into Microsoft Dynamics CRM Yes (Only the system administrator can migrate data in the offline mode.) Yes (All users who have appropriate permissions can import data.)
Import data into custom entity types and attributes Yes Yes
Use multiple source files that contain related data Yes No (You can only import one file at a time.)
Assign entity instances to multiple users Yes No (All entity instances are assigned to one user.)
Update existing entity instances No Yes
Detect duplicates No (You can run duplicate detection after you migrate the data.) Yes
Delete all entity instances associated with one job Yes (Use bulk delete feature.) Yes (Use bulk delete feature.)
Automatically map data based on column headings in the source file No Yes
Set the value of the createdon attribute for the entity from source data Yes No
Customize Microsoft Dynamics CRM to match source data No (Custom entities and attributes can be created by Data Migration Manager.) No (Customization must be done before import.)
Apply complex data transformation mapping Yes No
Import state and status information Yes No

Populate Lookup value on selection of another Lookup


 Step 1.


Step 2.

Step 3.

Let me explain the scenario…

Suppose we have City Lookup on Lead entity and we want to populate Region (Lookup), State (Lookup) and Zone (Lookup) on selection of particular City from City Lookup. You need to write below code on OnChange event of City Lookup field.

if(crmForm.all.new_cityid.DataValue !=null)

{

    var citylookupValues = crmForm.all.new_cityid.DataValue;

    if(citylookupValues[0] !=null)

    {

        var cityID = citylookupValues[0].id;

        var regionID = GetAttributeValueFromID(“new_city”, cityID , “new_regionid”);

        var stateID = GetAttributeValueFromID(“new_city”, cityID , “new_stateid”);

        var zoneID = GetAttributeValueFromID(“new_region”, regionID , “new_zoneid”);   

        if(regionID != null)

        {

            //Create an array to set as the DataValue for the lookup control.

            var regionlookupData = new Array();

            //Create an Object add to the array.

            var regionlookupItem= new Object();

            //Set the id, typename, and name properties to the object.

            regionlookupItem.id = regionID;

            regionlookupItem.typename = ‘new_region’;

            regionlookupItem.name = regionName;

            // Add the object to the array.

            regionlookupData[0] = regionlookupItem;

            // Set the value of the lookup field to the value of the array.

            crmForm.all.new_regionid.DataValue = regionlookupData;

            crmForm.all.new_regionid.ForceSubmit = true;

 

        }

        if(stateID != null)

        {

            //Create an array to set as the DataValue for the lookup control.

            var statelookupData = new Array();

            //Create an Object add to the array.

            var statelookupItem = new Object();

            //Set the id, typename, and name properties to the object.

            statelookupItem.id = stateID;

            statelookupItem.typename = ‘new_state’;

            statelookupItem.name = stateName;

            // Add the object to the array.

            statelookupData[0] = statelookupItem;

            // Set the value of the lookup field to the value of the array.

            crmForm.all.new_stateid.DataValue = statelookupData;

            crmForm.all.new_stateid.ForceSubmit = true;

        }

        if(zoneID != null)

        {

            var zoneName = GetAttributeValueFromID(“new_zone”, zoneID, “new_name”);

            //Create an array to set as the DataValue for the lookup control.

            var zonelookupData = new Array();

            //Create an Object add to the array.

            var zonelookupItem = new Object();

            //Set the id, typename, and name properties to the object.

            zonelookupItem.id = zoneID;

            zonelookupItem.typename = ‘new_zone’;

            zonelookupItem.name = zoneName;

            // Add the object to the array.

            zonelookupData[0] = zonelookupItem;

            // Set the value of the lookup field to the value of the array.

            crmForm.all.new_zoneid.DataValue = zonelookupData;

            crmForm.all.new_zoneid.ForceSubmit = true;

        }

     }

}

else

{

     crmForm.all.new_regionid.DataValue = null;

    crmForm.all.new_stateid.DataValue = null;

    crmForm.all.new_zoneid.DataValue = null;

}

 

function  GetAttributeValueFromID(sEntityName, sGUID, sAttributeName)

{

    /*

    * sEntityName: the name of the CRM entity (account, etc.)

    * whose attribute value wish to look up

    * sGUID: string representation of the unique identifier of the specific object whose attrbuite value we wish to look up

    * sAttributeName – the schema name of the attribute whose value we wish returned

    */

 

    var sXml = “”;

    //var oXmlHttp = new ActiveXObject(“Msxml2.XMLHTTP”);

    var oXmlHttp = new ActiveXObject(“Msxml2.XMLHTTP.6.0”);

 

    //var serverurl = “http://10.10.40.50:5555&#8221;;

    var serverurl = “”;

 

    //set up the SOAP message

    sXml += “<?xml version=\”1.0\” encoding=\”utf-8\” ?>”;

    sXml += “<soap:Envelope xmlns:soap=\”http://schemas.xmlsoap.org/soap/envelope/\””

    sXml += ” xmlns:xsi=\”http://www.w3.org/2001/XMLSchema-instance\””

    sXml += ” xmlns:xsd=\”http://www.w3.org/2001/XMLSchema\”>”;

    sXml += “<soap:Body>”;

    sXml += “<entityName xmlns=\”http://schemas.microsoft.com/crm/2006/WebServices\”>” +

    sEntityName + “</entityName>”;

    sXml += “<id xmlns=\”http://schemas.microsoft.com/crm/2006/WebServices\”>” +

    sGUID + “</id>”;

    sXml += “<columnSet xmlns=\”http://schemas.microsoft.com/crm/2006/WebServices\””

    sXml += ” xmlns:q=\”http://schemas.microsoft.com/crm/2006/Query\””

    sXml += ” xsi:type=\”q:ColumnSet\”><q:Attributes><q:Attribute>” +

    sAttributeName + “</q:Attribute></q:Attributes></columnSet>”;

    sXml += “</soap:Body>”;

    sXml += “</soap:Envelope>”;

 

    // send the message to the CRM Web service

    oXmlHttp.Open(“POST”, serverurl +

    “/MsCrmServices/2006/CrmService.asmx”,false);

    oXmlHttp.setRequestHeader(“SOAPAction”,

    “http://schemas.microsoft.com/crm/2006/WebServices/Retrieve&#8221;);

    oXmlHttp.setRequestHeader(“Content-Type”, “text/xml; charset=utf-8”);

    oXmlHttp.setRequestHeader(“Content-Length”, sXml.length);

    oXmlHttp.send(sXml);

 

    // retrieve response and find attribute value

    //var result = oXmlHttp.responseXML.selectSingleNode(“//” + sAttributeName);

    var result = oXmlHttp.responseXML.selectSingleNode(“//*[local-name()=\””+  sAttributeName +”\”]”);

    if (result == null)

    {

    return “”;

    }

    else

    return result.text;

}

How to get Security Roles of current/online user


Below code shows how to get Security Roles of current User Using JScript which uses a RetrieveMultiple query …

function GetCurrentUserRoles()
{
var xml = “” +

“<?xml version=\”1.0\” encoding=\”utf-8\”?>” +

“<soap:Envelope xmlns:soap=\”” +

http://schemas.xmlsoap.org/soap/envelope/&#8221; +

“\” xmlns:xsi=\”http://www.w3.org/2001/XMLSchema-instance\”” +

” xmlns:xsd=\”http://www.w3.org/2001/XMLSchema\”>” +

GenerateAuthenticationHeader() +

” <soap:Body>” +

” <RetrieveMultiple xmlns=\”” +

http://schemas.microsoft.com/crm/2007/WebServices\”>” +

” <query xmlns:q1=\”” +

http://schemas.microsoft.com/crm/2006/Query&#8221; +

“\” xsi:type=\”q1:QueryExpression\”>” +

” <q1:EntityName>role</q1:EntityName>” +

” <q1:ColumnSet xsi:type=\”q1:ColumnSet\”>” +

” <q1:Attributes>” +

” <q1:Attribute>name</q1:Attribute>” +

” </q1:Attributes>” +

” </q1:ColumnSet>” +

” <q1:Distinct>false</q1:Distinct>” +

” <q1:LinkEntities>” +

” <q1:LinkEntity>” +

” <q1:LinkFromAttributeName>roleid</q1:LinkFromAttributeName>” +

” <q1:LinkFromEntityName>role</q1:LinkFromEntityName>” +

” <q1:LinkToEntityName>systemuserroles</q1:LinkToEntityName>” +

” <q1:LinkToAttributeName>roleid</q1:LinkToAttributeName>” +

” <q1:JoinOperator>Inner</q1:JoinOperator>” +

” <q1:LinkEntities>” +

” <q1:LinkEntity>” +

” <q1:LinkFromAttributeName>systemuserid</q1:LinkFromAttributeName>” +

” <q1:LinkFromEntityName>systemuserroles</q1:LinkFromEntityName>” +

” <q1:LinkToEntityName>systemuser</q1:LinkToEntityName>” +

” <q1:LinkToAttributeName>systemuserid</q1:LinkToAttributeName>” +

” <q1:JoinOperator>Inner</q1:JoinOperator>” +

” <q1:LinkCriteria>” +

” <q1:FilterOperator>And</q1:FilterOperator>” +

” <q1:Conditions>” +

” <q1:Condition>” +

” <q1:AttributeName>systemuserid</q1:AttributeName>” +

” <q1:Operator>EqualUserId</q1:Operator>” +

” </q1:Condition>” +

” </q1:Conditions>” +

” </q1:LinkCriteria>” +

” </q1:LinkEntity>” +

” </q1:LinkEntities>” +

” </q1:LinkEntity>” +

” </q1:LinkEntities>” +

” </query>” +

” </RetrieveMultiple>” +

” </soap:Body>” +

“</soap:Envelope>” +

“”;

var xmlHttpRequest = new ActiveXObject(“Msxml2.XMLHTTP”);

xmlHttpRequest.Open(“POST”, “/mscrmservices/2007/CrmService.asmx”, false);

xmlHttpRequest.setRequestHeader(“SOAPAction”,

http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple&#8221;);

xmlHttpRequest.setRequestHeader(“Content-Type”, “text/xml; charset=utf-8”);

xmlHttpRequest.setRequestHeader(“Content-Length”, xml.length);

xmlHttpRequest.send(xml);

var resultXml = xmlHttpRequest.responseXML;

return(resultXml);

}

For Complete Source Code for hiding tab/field based on Security Role Please Visit.

Jimmy Wang’s version.

Plug-ins vs. Workflows in Microsoft Dynamics CRM


 
 Both workflows and plug-ins can attach to exactly the same events. Well, plug-ins have available a couple of more events but essentially both work on top of the same event model.Remember also that workflows always run asynchronous and hence, the Asynchronous Processing Service must be running on the server in order to run.

Workflows are more suitable if:

  • you want to achieve simple tasks faster, such as sending an e-mail or creating / updating assigning records. These actions can be set up very quickly with a workflow without any need of writing code.
  • you want to easily scale things to managers (if they were setup for user records), as it is possible to assign records to them.
  • you want to allow an advanced user to make changes to logic. As using the integrated workflow designer is user-friendly, an advanced user would be able to edit an existing workflow and change some rules according to business changes.
  • the logic should be available to be run on demand. I mean, when you are within an entity and navigates to “workflows” option in the left pane, all workflows marked as available to run on demand can be executed making them independent of an event trigger.
  • you want to send emails making use of templates and attaching files.

Workflows also allow running child workflows which may make a lot of sense in some scenarios. Nevertheless, be careful if you need the child workflow results in order to make decisions on your main workflow, as child workflows always run asynchronous, which means that it will trigger the child workflow and continue. If you need your primary workflow to wait until child ends, you will need to write a custom activity.

On the other hand, plug-ins are more suitable if:

  • you need to manipulate data before is saved.
  • you need to make validations before submitting the operation.
  • you want to be able to cancel an operation based on your validations.
  • immediate response to the user is needed.
  • you need retrieve values and/or take actions after operation has been completed (i.e. getting and autogenerated id)

It is important to note that since Dynamics CRM 4, plug-ins can also be configured to run asynchronous (Mode attribute while registering plug-in). Nevertheless, pre-event asynchronous plug-ins are not supported. In this case, you will have to set it up as synchronous mode.

Another important thing about plug-ins is the Deployment option which says if the plug-in is going to be executed on the server and/or Outlook client. If both executions are set up and client goes offline and online, plug-in calls are triggered after synchronization so be prepared in this case to execute your code twice!

Regarding to security:

  • Workflows triggered automatically will run under the security context of the workflow owner. On the contrary, if executed on demand, the security context of the user who executed the workflow will be used.
  • Plug-ins execute under the security context of the CRM Web application pool identity (typically NETWORK SERVICE). As this account typically maps to generic CRM SYSTEM user this typically works fine.

However, within plug-ins you can make use of impersonation to work under the credentials of the user who is making the request. For doing so, you just need to pass True to the CreatCrmService method under the context object.If you need to always impersonate with a specific user, you can do that by passing True as above and setting impersonatinguserid attribute while registering the plug-in.It is important to know that plug-in impersonation does not work offline. The logged on user credentials are always used in this case.

Some other important url for reference are..
http://msdn.microsoft.com/en-us/library/dd393303.aspx
http://blogs.msdn.com/lezamax/archive/2008/04/02/plug-in-or-workflow.aspx.
Hope it helps..

Mail Merge Using Microsoft Dynamics CRM 4.0 and Microsoft Office Word


How to do a mail merge from Microsoft Outlook, using Dynamics CRM data and Microsoft Office Word. Outlook and Word version 2007 shown in this video

via Mail Merge Using Microsoft Dynamics CRM 4.0 and Microsoft Office Word.

Update Rollup 13 for Microsoft Dynamics CRM 4.0


Update Rollup 13 for Microsoft Dynamics CRM 4.0

http://blogs.msdn.com/b/crm/archive/2010/09/23/update-rollup-13-for-microsoft-dynamics-crm-4-0.aspx