Archive
event.returnValue is not working after UR 12 – Fix
We use event.returnValue=false statement, to stop the event execution. (i.e., I can stop my crm form’s save action, if I write event.returnValue=false statement on my onsave() event).
After I upgraded to UR12, I was getting script error, if I use the event.returnValue statement.
Reason
- Update Rollup 12 and December 2012 Service Update support additional browsers by generating HTML that supports W3C standards.
- This requires removing dependencies on HTML components (HTC) that are specific to Internet Explorer.
- Hence event.returnValue statement has been deprecated
Fix
- Use context.getEventArgs().preventDefault() function to cancel the event execution
How do I use this
- First to get “context”, enable the OnSave event handler to pass the execution context as the first parameter to the OnSave event handler.
- Open customization form -> Form Properties and in “Handler Properties” window, select the “Pass execution ….” checkbox
-
- Next in your Jscript , read the context as first parameter
function onsave(context) {
// Prevent the event execution
context.getEventArgs().preventDefault();
}
Get more details on latest CRM JScript changes from this link
🙂
CRM online instance opening only in Mobile version – Fix
The other day, when I upgraded to IE 11 browser and when I browse my CRM online URL, I was getting only mobile version (i.e., http:// Orgname.crm5.dynamics.com/m/default.aspx).
Even if i explicitly provide the URL http:// Orgname.crm5.dynamics.com/default.aspx, it was redirecting to Mobile version Reason
- CRM online is not compatible with IE 11
Fix
- Add CRM online site to IE 11 compatibility list
- Go to Tools -> Compatibility View Settings
- Add the “dynamics.com” website to compatibility view settings by click on “Add”
- If its “OnPremise” add CRM server name to compatibility view settings.
- Refresh the browser
🙂
Retrieve records with Fetchxml using Jscript – CRM 2011
Retrieve the records using FetchXML is a convenient way as we can form the FetchXML easily using the ‘Advanced Find’ .
Once you have the FetchXML ready, below is the JScript to execute and read the result set.
- In this sample, I am fetching records from custom entity “Bikes” which has relationship with ‘Contact’ entity. (i.e., Fetch all the bikes of a Contact whose full name contains ‘Raj’)
- Note – I am using “xrmservicetoolkit” helper Jscript which is available in CodePlex. You just need to download the Jscript and refer to your CRM form.
function getBikesByContactName() {
var fetchXml =
“<fetch mapping=’logical’>” +
“<entity name=’raj_bike’>” +
“<attribute name=’raj_name’ />” +
“<attribute name=’createdon’ />” +
“<link-entity name=’contact’ from=’contactid’ to=’raj_customerid’ alias=’ad‘>” +
“<attribute name=’fullname’ />” +
“<filter type=’and’>” +
“<condition attribute=’fullname’ operator=’like’ value=’%raj%’ />” +
“</filter>” +
“</link-entity>” +
“</entity>” +
“</fetch>”;
// Execute the fetch
var bikes = XrmServiceToolkit.Soap.Fetch(fetchXml);
// Get the results by loop through ‘bikes’
for (var indxBikes = 0; indxBikes < bikes.length; indxBikes++) {
alert(“Bike Name – “+bikes[indxBikes].attributes.raj_name.value);
alert(“Created On – “+bikes[indxBikes].attributes.createdon.value);
// Get the related entity (i.e., Contact) attributes using LinkEntity alias)
alert(“Related entity attribute (Contact Name) – ” + bikes[indxBikes].attributes.ad.fullname.value);
}
}
🙂
Filtering Lookup view based on custom logic CRM 2011
In one of my requirement, I have to filter my lookup view results based on another lookup field value.
I have 2 Lookup fields on my form
- Product
- Product Category
When I click on “Product” lookup, I have to show only Products with category as “Product Category” field value.
We can achieve this requirement using Jscript by following below steps
- Create a new view with our filter
- Use the SDK method addCustomView, to add newly created view for the lookup dialog box
- Set this view as default view
- Disable the view selector to avoid user to select other views from Lookup dialog
- Put above logic in a function register it on “onchange” event of “Product Category” field
Below is the Jscript function
function createAndSetLookupView() {
// Some GUID but only needs to be unique among the other available views for the lookup
var viewId = “{CB6F8184-D7C2-4664-9FAB-18FD9DCDB22A}”;
// Name of the view
var viewDisplayName = “My filtered view”;
// Prepare the xml with columns to display and filter
// Tip : Use Advanced Find to prepare th FetchXML
var fetchXml = “<fetch version=’1.0′ ” +
“output-format=’xml-platform’ ” +
“mapping=’logical’>” +
“<entity name=’new_product’>” +
“<attribute name=’new_productid’ />” +
“<attribute name=’new_name’ />” +
“<attribute name=’new_categoryid’ />” +
“<attribute name=’createdon’ />” +
“<order attribute=’new_name’ ” +
“descending=’false’ />” +
“<filter type=’and’>” +
“<condition attribute=’new_categoryid’ ” +
“operator=’eq’ ” +
“uiname='” + {categoryName} + “‘ ” +
“uitype=’new_category’ ” +
“value='” + {categoryGUID} + “‘ />” +
“</filter>” +
“</entity>” +
“</fetch>”;
var layoutXml = “<grid name=’resultset’ ” +
“object=’1′ ” +
“jump=’new_name’ ” +
“select=’1′ ” +
“icon=’1′ ” +
“preview=’2′>” +
“<row name=’result’ ” +
“id=’new_productid’>” +
“<cell name=’new_name’ ” +
“width=’150′ />” +
“<cell name=’new_categoryid’ ” +
“width=’150′ />” +
“<cell name=’createdon’ ” +
“width=’100′ />” +
“</row>” +
“</grid>”;
try {
// Lookup field which you want to add new view
var lookupControl = Xrm.Page.ui.controls.get(“new_productid”);
// Add the created view to Product lookup and set this view as default
lookupControl.addCustomView(viewId, “new_product”, viewDisplayName, fetchXml, layoutXml, true);
//Disable “View Selection” dropdown of “Product” lookup dialog
document.getElementById(“new_productid”).setAttribute(“disableViewPicker”, “1”);
}
catch (e) {
alert(“Error in createAndSetLookupView() – ” + e.description);
}
}
🙂
The server was unable to process the request due to an internal error – plugin registration tool
The other day my plugin registration tool suddenly stopped connecting to my CRM server and was getting below error
Unhandled Exception: System.ServiceModel.FaultException: The server was unable to process the request due to an internal error
Below steps helped me to resolve the issue
- Go to “Plugin Registration Tool” physical folder
- Delete existing “Microsoft.Crm.Sdk.Proxy.dll” and “Microsoft.Xrm.Sdk.dll”
- Get back the 2 .dlls either from CRM SDK or from “C:\Program Files\Microsoft Dynamics CRM\Server\bin” path of CRM server machine
- Paste them in “Plugin Registration Tool” folder
- Reset the IIS
- Open the Plugin Registration Tool and try to connect to the server
🙂
Retrieve associated records (N:N related)
In CRM, If you create N:N relationship between 2 entities, it creates an intermediate entity (i.e., Relationship Entity) with 3 fields
- Primary key field of “Relationship Entity”
- Entity 1 Primary Key field
- Entity 2 Primary Key field
In this sample, I have 2 custom entities “Bike” and “Bond” with N:N association. (i.e., A ‘Bike’ can have N no of ‘Bonds’ and a ‘Bond’ can be associate with N ‘Bikes’)
To get all the ‘Bonds’ of ‘Bike’ with name “Honda”, below is the query expression.
string entity1 = “raj_bike”;
string entity2 = “raj_bond”;
string relationshipEntityName = “raj_bike_bond”;
QueryExpression query = new QueryExpression(entity1);
query.ColumnSet = new ColumnSet(true);
LinkEntity linkEntity1 = new LinkEntity(entity1, relationshipEntityName, “raj_bikeid”, “{Entity 1 Primary key field (i.e.,raj_bikeid)}“, JoinOperator.Inner);
LinkEntity linkEntity2 = new LinkEntity(relationshipEntityName, entity2, “raj_bondid”, “{Entity 2 Primary key field (i.e.,raj_bondid)}“, JoinOperator.Inner);
linkEntity1.LinkEntities.Add(linkEntity2);
query.LinkEntities.Add(linkEntity1);
// Add condition to match the Bike name with “Honda”
linkEntity2.LinkCriteria = new FilterExpression();
linkEntity2.LinkCriteria.AddCondition(new ConditionExpression(“raj_bikename”, ConditionOperator.Equal, “Honda”));
EntityCollection collRecords = service.RetrieveMultiple(query);
Note : To retrieve columns from Entity 2, set ‘Alias’ to ‘LinkEntity2’.
🙂
Associate Campaign with related items using Jscript – CRM 2011
We can associate 2 entity records having N:N relationship using “AssociateRequest” SDK message. (How to associate)
But you get below error when you try to associate a Campaign record with Campaign related items such as Marketing List, Product, or Salesliterature using “AssociateRequest” SDK message.
Associate is not supported for CampaignItem Platform
To associate a Campaign, we have an exclusive SDK message “AddItemCampaignRequest”.
Below is the Jscript to associate Campaign with related records
function associateCampaignItem (campaignId, associateRecordId, associateRecordSchemaName) {
var requestMain = “”
requestMain += “<s:Envelope xmlns:s=\”http://schemas.xmlsoap.org/soap/envelope/\”>”;
requestMain += ” <s:Body>”;
requestMain += ” <Execute xmlns=\”http://schemas.microsoft.com/xrm/2011/Contracts/Services\” xmlns:i=\”http://www.w3.org/2001/XMLSchema-instance\”>”;
requestMain += ” <request i:type=\”b:AddItemCampaignRequest\” xmlns:a=\”http://schemas.microsoft.com/xrm/2011/Contracts\” xmlns:b=\”http://schemas.microsoft.com/crm/2011/Contracts\”>”;
requestMain += ” <a:Parameters xmlns:c=\”http://schemas.datacontract.org/2004/07/System.Collections.Generic\”>”;
requestMain += ” <a:KeyValuePairOfstringanyType>”;
requestMain += ” <c:key>CampaignId</c:key>”;
requestMain += ” <c:value i:type=\”d:guid\” xmlns:d=\”http://schemas.microsoft.com/2003/10/Serialization/\”>” + campaignId + “</c:value>”;
requestMain += ” </a:KeyValuePairOfstringanyType>”;
requestMain += ” <a:KeyValuePairOfstringanyType>”;
requestMain += ” <c:key>EntityId</c:key>”;
requestMain += ” <c:value i:type=\”d:guid\” xmlns:d=\”http://schemas.microsoft.com/2003/10/Serialization/\”>” + associateRecordId + “</c:value>”;
requestMain += ” </a:KeyValuePairOfstringanyType>”;
requestMain += ” <a:KeyValuePairOfstringanyType>”;
requestMain += ” <c:key>EntityName</c:key>”;
requestMain += ” <c:value i:type=\”d:string\” xmlns:d=\”http://www.w3.org/2001/XMLSchema\”>” + associateRecordSchemaName + “</c:value>”;
requestMain += ” </a:KeyValuePairOfstringanyType>”;
requestMain += ” </a:Parameters>”;
requestMain += ” <a:RequestId i:nil=\”true\” />”;
requestMain += ” <a:RequestName>AddItemCampaign</a:RequestName>”;
requestMain += ” </request>”;
requestMain += ” </Execute>”;
requestMain += ” </s:Body>”;
requestMain += “</s:Envelope>”;
var req = new XMLHttpRequest();
var OrgServicePath = “/XRMServices/2011/Organization.svc/web”;
var serverUrl = Xrm.Page.context.getServerUrl() + OrgServicePath;
req.open(“POST”, serverUrl, true)
// Responses will return XML. It isn’t possible to return JSON.
req.setRequestHeader(“Accept”, “application/xml, text/xml, */*”);
req.setRequestHeader(“Content-Type”, “text/xml; charset=utf-8”);
req.setRequestHeader(“SOAPAction”, “http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute”);
var successCallback = null;
var errorCallback = null;
req.onreadystatechange = function () { AddItemCampaignResponse(req); };
req.send(requestMain);
}
function AddItemCampaignResponse(req) {
if (req.readyState == 4) {
if (req.status == 200) {
alert(“Success”);
}
else {
alert(“Error – ” + req.responseXML);
}
}
}
How do I use
- Lets try to associate ‘Campaign’ with ‘Marketing List’ item using above script
- Pass the required arguments as specified below
var campaignId = “”; //Campaign GUID
var marketinglistId = “”; //Marketinglist GUID
var schemaName = “”; // Marketinglist entity Schema Name
associateCampaignItem(campaignId, marketinglistId, schemaName);
Below is the C# code to form the ‘AddItemCampaignRequest’
var request = new AddItemCampaignRequest { CampaignId = campaignId, EntityId = marketinglistId, EntityName = {Marketinglist entity Schema Name} };
🙂
Consuming WCF service from Jscript using JQuery
I recently got a requirement to host a WCF service in Azure and consume it client side using Jscript.
In this article, I am providing details on how to consume WCF service from Jscript with the help of JQuery.
In below example, service is a simple “Products.svc” contain 1 method “GetProducts()” and returns List<Product> (“Product” is custom class)
WCF Service
- Service Contract (IProductService.cs)
[ServiceContract(Namespace = “http://ABCproducts”,
Name = “IProductService”,
SessionMode = SessionMode.NotAllowed,
ProtectionLevel = ProtectionLevel.None)]
public interface IProductService{
[OperationContract]
[WebInvoke(
Method = “POST”,
BodyStyle = WebMessageBodyStyle.Wrapped,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
List<Product> GetProducts();
}
[DataContract]
public class Product{
string id = string.Empty;
string name = string.Empty;
[DataMember]
public string ProductId{
get { return id; }
set { id = value; }
}
[DataMember]
public string ProductName{
get { return name; }
set { name = value; }
}
}
- Service (ProductService.svc)
public List<Product> GetProducts(){
List<Product> products = new List<Product>();
Product P1 = new Product();
P1.Id = “1”;
P1.Name = “Mango”;
Product P2 = new Product();
P2.Id = “2”;
P2.Name = “Apple”;
products.Add(P1);
products.Add(P2);
return products;
}
- Service Binding (Web.config)
- Very important note is, the service endpoint has to be “webHttpBinding”; otherwise we get “Cannot process the message because the content type application\json was not the expected…” error.
- webHttpBinding is the REST-style binding, where you can hit a service URL and get back a result in either XML or JSON from the service.
- Add a “EndPointBehavior” with “webHttp” stack element.
- Below is the service configuration mentioned in my web.config file
<services>
<service name=”ProductService”>
<endpoint address=”” behaviorConfiguration=”endPtBehaviorJSon”
binding=”webHttpBinding” bindingConfiguration=”bindingWebHttp”
name=”wsBindingBFS” contract=”IProductService” />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name=”endPtBehaviorJSon“>
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
Jscript
- Since we are using JQuery, refer “JQuery.1.4.1.min.js” file
- In this example we are getting output in json format. (Observe “dataType property mentioned as “json”)
- “getProducts” is the function which communicate to service and gets “Product” collection as response in JSon format.
- The response comes in special format (i.e., WCF Service method name+Result) (i.e, GetProductsResult)
function getProducts() {
var serviceURL = “http://{Server Name}/ProductService.svc/GetProducts“;
$.ajax({
type: “POST”,
contentType: “application/json; charset=utf-8”,
url: serviceURL,
processData: false,
dataType: “json”,
//If the call succeeds
success:
function (response) {
retrieveProducts(response)
},
//If the call fails
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(“Error while retrieval – ” + XMLHttpRequest.responseText);
}
});
}
function retrieveProducts(response) {
// Result collection come as Response.{MethodName}+”Result”
if (response && response.GetProductsResult) {
$.each(response.GetProductsResult, function (i) {
alert(
“Product ID: ” + this.ProductId +
” Product Name: ” + this.ProductName);
});
}
}
Copy a security role programmatically – CRM 2011
In one of the requirement, we have to create a new security role by copying an existing role in a Plug-in.
The whole requirement break down to 3 steps
- Create a new security role
- Get all the existing role privileges by using “RetrieveRolePrivilegesRoleRequest”
- “RetrieveRolePrivilegesRoleResponse” contain, “RolePrivileges” property, with collection of privileges & access level
-
- Add the retrieved role privileges to the newly created role by using “AddPrivilegesRoleRequest”
Below is the code for step 2 & 3
Guid existingRoleId = new Guid(“C85F0FFF-4C80-E211-A877-1CC1DE79B4CA”);
Guid newRoleId = new Guid(“B6690FFF-4C80-E211-A877-1CC1DE79B4CA”);
// Step 2
RetrieveRolePrivilegesRoleRequest getPrivilagesRequest = new RetrieveRolePrivilegesRoleRequest();
getPrivilagesRequest.RoleId = existingRoleId;
RetrieveRolePrivilegesRoleResponse privilagesResponse = (RetrieveRolePrivilegesRoleResponse)service.Execute(getPrivilagesRequest);
if (privilagesResponse != null && privilagesResponse.RolePrivileges != null){
// Step 3
AddPrivilegesRoleRequest addPrivilagesRequest = new AddPrivilegesRoleRequest();
addPrivilagesRequest.Privileges = privilagesResponse.RolePrivileges;
addPrivilagesRequest.RoleId = newRoleId;
AddPrivilegesRoleResponse addPrivilagesResponse = (AddPrivilegesRoleResponse)service.Execute(addPrivilagesRequest);
}
🙂
Unable to install CRM 2011 Report Extension – Reboot required error
I was getting below “Reboot Required” message when I tried to install “CRM 2011 Report Extension” (i.e., CRM2011-Bids-ENU-i386)
- I restarted my machine and I retried to install, still I was getting same error.
- As mentioned in the error message, I checked the log file under “C:\Users\{curr_user}\appdata\Roaming\Microsoft\MSCRM\Logs\BIDSExtensionsSetup.log” path, there it was written as
Reboot required — Key Found: HKCU\Software\Microsoft\Windows\CurrentVersion\RunOnce
Fix –
- Seems a known issue
- We need to delete the “RunOnce” key from “Registry” (Path – HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce)
- Refer KB Article from Microsoft.
After deletion of “RunOnce” key from Registry, I was able to install CRM 2011 Report Extension.
🙂