RSS

Monthly Archives: November 2013

CRM 2013 – Field Level Notification

Introduction

In CRM 2011, there was no Out of Box Functionality to show client side notifications on the Entity. We have used JScripts functions to show alert messages using Web Resources. In CRM 2013, Microsoft has introduced some new methods to show notifications on client side.

Background

The requirement was, while entering data in an Account form, the Account Number must be greater than 4 digits, else we had to show a notification “The account number should be more than 4 digits” on the field level.

Code

We will use following two methods for our task.

  • setNotification(message) : To set the Notification near the field
  • clearNotification() : To remove the Notification from the field

Code can be used onChange or onSave event.

//Function To Set Notification On Field Level
function SetFieldNotification()
{
    //Get The Control
    var field = Xrm.Page.getControl("accountnumber");

    //Get The Count Of Digits In Acccount Number
    var numberOfDigit = CountDigit(field.getAttribute().getValue());

    //Check if digit count of Account Number is less than 4 or not
    if (numberOfDigit <= 4)
    {
        //Set The Notification
        field.setNotification("The account number should be more than 4 digits");
    }
    else
    {
        //Clear The Notification
        field.clearNotification();
    }
}

//Function To Get Count Of Digits
function CountDigit(number)
{
    return number.toString().length;
}

Output

Image The Screen shot displays the notification near Account Number field.

By Abhisek Sriramka
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

 
Leave a comment

Posted by on November 29, 2013 in WebResources

 

Tags: , , , , , , , , , , , , , , , , , ,

Avoiding Deadlock in Plugins

Introduction

Multiple operations with the same Entity inside a Plugin, causes Deadlocks in Plugins and might cancel the transaction. Let’s explore the Trick to avoid the Deadlocks.

Background

In one of my projects, there was a situation, when multiple operations had been done on the same Entity records. A Plugin was there, which was simultaneously updating a record lets say “C” and then from record “C” based on some condition record “B” was being updated and another Plugin was there which was updating values from record “B” to record “A”. And after it is done the final amount had to be shown in record “A” immediately as soon as the custom Popup (a Web Resource), that causes the operation in record “C” is closed and the Popup was being invoked from the ribbon of entity “A”.
As the user wanted to see the effect immediately there was no other option than to just make the Plugin Synchrounous. So, Create/Update and Retrieve operation at the same time was causing the transaction to be Deadlocked sometimes and was not allowing the user to Add/Update multiple records.

Code

In order to solve the issue, I tried several ways. Finally I found that in QueryExpression there is a property called “NoLock” while using RetrieveMultiple method.

Its simple to use but its effect is something worthy to be noted. The code snippet is,

QueryExpression queryCItems= new QueryExpression("new_entityc");
queryCItems.NoLock = true;
queryCItems.ColumnSet = new ColumnSet("new_totalamount");
queryCItems.Criteria.AddCondition("new_aid", ConditionOperator.Equal, entC.Id);

This solved the issue. 🙂

By Dibyasingh Tripathy
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

 
Leave a comment

Posted by on November 26, 2013 in CRM Plug-in

 

Tags: , , , , , , , , , , , , , , ,

Custom WorkFlow to Send Email with PDF formatted Report as Attachment

Introduction

In some cases, we have to send Email to customers with a Report in Pdf format as an attachment.

Background

Once I had the same requirement. To do this, we have to follow three steps.

  1. First to retrieve the Report,
  2. Second to convert the Report to Pdf format and
  3. Last to send an Email with the Pdf as attachment.

Code

To achieve this, I have written a Custom Workflow.
Here is the code snippet to get it done. This code is for CRM OnPremise only. I have not tried in CRM Online.

using System;
using System.Activities;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Crm.Sdk.Messages;
using CustomWorkflows.ReportService; //Have to add the Reporting Service as Web Reference

namespace SendReport
{
    public class SendReport : CodeActivity
    {
        protected override void Execute(CodeActivityContext executionContext)
        {
            try
            {
                IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();
                IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
                IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

                Guid accountId = context.PrimaryEntityId;
                byte[] result = null;

                CustomWorkflows.ReportService.ReportExecutionService rs = new ReportExecutionService();

                // Credential to connect with CRM
                rs.Credentials = new System.Net.NetworkCredential(username, password, domain);

                // Setting the URL of the Reporting Server
                rs.Url = "http://test10:80/ReportServer/ReportExecution2005.asmx";

                string reportPath = "/Test_MSCRM/TestReport";
                // Specify the report path from the reporting server
                // Note: To get the report name, report must be published for the external use.
                // To do this edit the report from CRM and publish it for external use.
                // After publishing it for external use report name will be visible in the reporting server instead of the report id.

                string format = "PDF";
                string historyID = null;
                string devInfo = @"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";
                string encoding;
                string mimeType;
                string extension;
                Warning[] warnings = null;
                string[] streamIDs = null;

                ExecutionInfo execInfo = new ExecutionInfo();
                ExecutionHeader execHeader = new ExecutionHeader();
                rs.ExecutionHeaderValue = execHeader;
                execInfo = rs.LoadReport(reportPath, historyID);

                String SessionId = rs.ExecutionHeaderValue.ExecutionID;

                result = rs.Render(format, devInfo, out extension, out encoding, out mimeType, out warnings, out streamIDs);

                //Create email activity
                Entity email = new Entity();
                email.LogicalName = "email";
                email.Attributes.Add("regardingobjectid", new EntityReference("account", accountId);

                //Creating EntityReference for from, to and cc. Need to be changed according to your requirement
                EntityReference from = new EntityReference("systemuser", senderUserId);
                EntityReference to = new EntityReference("contact", recieverUserId);
                EntityReference cc = new EntityReference("contact", recieverCCUserId);

                //Creating party list
                Entity fromParty = new Entity("activityparty");
                fromParty.Attributes.Add("partyid", from);
                Entity toParty = new Entity("activityparty");
                toParty.Attributes.Add("partyid", to);
                Entity ccParty = new Entity("activityparty");
                ccParty.Attributes.Add("partyid", cc);

                EntityCollection collFromParty = new EntityCollection();
                collFromParty.EntityName = "systemuser";
                collFromParty.Entities.Add(fromParty);

                EntityCollection collToParty = new EntityCollection();
                collToParty.EntityName = "contact";
                collToParty.Entities.Add(toParty);

                EntityCollection collccParty = new EntityCollection();
                collccParty.EntityName = "contact";
                collccParty.Entities.Add(ccParty);

                // Adding from, to and cc to the email
                email.Attributes.Add("from", collFromParty);
                email.Attributes.Add("to", collToParty);
                email.Attributes.Add("cc", collccParty);

                email.Attributes.Add("subject", "Here goes subject message.. : ");
                email.Attributes.Add("description", "Here goes description text..");
                Guid emailID = service.Create(email); // Create the email

                // Attaching Pdf Report
                int NextActorID = new int();
                RetrieveEntityRequest request = new RetrieveEntityRequest();
                request.LogicalName = "email";
                RetrieveEntityResponse response = (RetrieveEntityResponse)service.Execute(request);
                int objecttypecode = response.EntityMetadata.ObjectTypeCode.Value;

                Entity attachment = new Entity("activitymimeattachment");
                attachment.Attributes.Add("subject", "Report");
                attachment.Attributes.Add("filename", "Report.pdf");
                attachment.Attributes.Add("body", Convert.ToBase64String(result));
                attachment.Attributes.Add("filesize", Convert.ToInt32(result.Length.ToString()));
                attachment.Attributes.Add("mimetype", "text/plain");
                attachment.Attributes.Add("attachmentnumber", NextActorID);
                attachment.Attributes.Add("objectid", new EntityReference("email", new Guid(email.Id.ToString())));
                attachment.Attributes.Add("objecttypecode", objecttypecode);
                service.Create(attachment); //Create the attachment

                // Sending email
                SendEmailRequest reqSendEmail = new SendEmailRequest();
                reqSendEmail.EmailId = emailID;
                reqSendEmail.TrackingToken = "";
                reqSendEmail.IssueSend = true;
                SendEmailResponse res = (SendEmailResponse)service.Execute(reqSendEmail);
            }
            catch (Exception err)
            {
                // Throw error message
            }
        }
    }
}

By Ranjan Parhi
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

 
9 Comments

Posted by on November 20, 2013 in CRM WorkFlow

 

Tags: , , , , , , , , , , , , , , , ,

Changing Filter Condition in Associated View

Activities Associated View

Activities Associated View

Introduction

At times, we have the requirement to change the Filter Condition in an Associated View.

Background

In my case, the requirement was to show all the Activities when “Activities” Associated View is selected. The default Filter Condition in Activity Associated View is “Next 30 days“. I had to change it to “All“.

Code

Here is the code snippet to work this out. This function must be called on Load of the Form.

function filterAllActivities()
{
    //Calling function when activity is clicked
    document.getElementById("navActivities").onclick = function () {
        Mscrm.Details.loadArea(this, "areaActivities"); //loadArea is the predefined function

        //On load of the activity iframe change the filter
        document.getElementById("areaActivitiesFrame").onload = function () {
            var entityName = Xrm.Page.data.entity.getEntityName();
            var entity = entityName.charAt(0).toUpperCase() + entityName.substr(1);

            var doc = this.contentWindow.document; //Getting the document of the window

            //Getting the control of the 'Filter on' dropdown
            var filterOn = doc.getElementById("crmGrid_" + entity + "_ActivityPointers_datefilter");
            filterOn.value = "All"; //Changing the filter condition

            var evt = document.createEvent("HTMLEvents");
            evt.initEvent("change", false, true);
            filterOn.dispatchEvent(evt); //Dispatch event
        };
    };
}

By Ranjan Parhi
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

 
3 Comments

Posted by on November 19, 2013 in WebResources

 

Tags: , , , , , , , , , , , , , , ,

CRM 2011 Exception “The HTTP request is unauthorized with client authentication scheme ‘Anonymous’. The authentication header received from the server was ‘NTLM'”

Introduction

This is in reference to my previous post Calling external Web Service from a CRM 2011 Plug-in. This blog post is just a modification of the last post.

Background

In one of the project while calling an external Web Service hosted in some other server(other than CRM server), I found an issue like the one below.

” The HTTP request is unauthorized with client authentication scheme ‘Anonymous’. The authentication header received from the server was ‘NTLM’ “

Problem

Clearly its an Authentication Issue. Then I found out that in Authentication Section of IIS, the Authentication Scheme for the service was Ntlm, whereas I was using Default Authentication Scheme in my HTTP Binding inside Configuration Information.

Solution

Instead of using the Default Authentication, I changed my Binding to use Ntlm Authentication.

So, instead of the following code,

BasicHttpBinding myBinding = new BasicHttpBinding();

myBinding.Name = "BasicHttpBinding_Service";
myBinding.Security.Mode = BasicHttpSecurityMode.None;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;

I changed my code like below…

BasicHttpBinding myBinding = new BasicHttpBinding();

myBinding.Name = "BasicHttpBinding_Service";
myBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
myBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
myBinding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;

And to my utter surprise, it started to work :). !!!

By Dibyasingh Tripathy
Senior Software Engineer @Team DynamicsCRM.
Mindfire Solutions

 

Tags: , , , , , , , , , , , , , , , ,

 
%d bloggers like this: