Friday, April 17, 2015

Browser Link in Visual Studio 2013

In this post, we will take a look at the new Browser Link feature in Visual Studio 2013.
We often need to build custom web portals which integrate with Microsoft Dynamics CRM 2011 that need to be tested in multiple browsers during development. It can be quite frustrating having to manually refresh each browser window when making small cosmetic changes to web pages. With Browser Link, you can easily refresh your web application in all browsers with one click!
To enable Browser Link, click on the arrow next to the browser link icon and selectEnable Browser Link.
 Browser Link in Visual Studio 2013
The screenshot below shows simple HTML code and what it looks like when it’s rendered in Internet Explorer.
 Browser Link in Visual Studio 2013
I have changed the text inside the <h1> tag to “Testing Browser Link – Browser Link”. Instead of refreshing the browser in Internet Explorer, I can click on the Browser Linkicon on the Visual Studio 2013 toolbar.
 Browser Link in Visual Studio 2013
The screenshot below shows Browser Link in action with our web application running in both IE and Chrome. Again, we can simply refresh both browsers with the click of one button.
 Browser Link in Visual Studio 2013
Browser Link can be extended to unleash additional functionality both from within Visual Studio and in the web browser itself. The Build Conference showcased a great feature where you can fill out a web form in one browser and automatically populate fields on the same form on another browser.
This feature will be extremely useful when testing your web applications. I will definitely be using it when building custom web portals for Microsoft Dynamics CRM.

Thanks
Rajeev

Import Organization Database Into Microsoft Dynamics CRM 2015

You may need multiple CRM databases for security purposes, or if you are moving your database from one environment/organization to the other. This article shows how to import an organization database into Microsoft Dynamics CRM 2015.
 
Step 1
 
Open Microsoft Dynamics CRM Deployment Manager. You will see the existing organizations as in the following:
 
 
Step 2
 
Right-click on Organizations and choose the Import Organization option.
 
 
Step 3
 
Choose the SQL Server and Organization database name. Please note that this database is the CRM database that is to be imported. You can use the backup and restore options of SQL Server to restore this database to your environment and then run this wizard.
 
 
Step 4
 
Choose the Display Name and the Unique Database Name and click Next.
 
 
Step 5
 
You can choose to Automatically Map Users or Select Custom Mapping Options.
 
 
Step 6
 
You will get a list of options to choose the method for mapping users.
 
 
Step 7
 
System Check is performed and if all checks are okay, you can import the data.
 
 
Step 8
 
If all goes well, you will get the following results. There may be some issues with the Reporting Services installation and user account. You can change the user account to be the Network account and re-run this wizard.
 
 
If Reporting Services Extensions is not installed you will get the following error. Install it and re-run the wizard.
 
 
Step 9
 
Once all the system checks are cleared, you will get the Ready to Import dialog with details. Once you are satisfied with this, click on Import.
 
 
Step 10
 
The data is imported.
 
 
If there are no issues in the user mapping, you should see a success message as in the following, else the log file has the detailed error message.
 

Wednesday, April 15, 2015

Retrieve AliasedValue form fetch xml


string fetchXML = string.Format(@"<fetch version='1.0' output-format='xml-platform' no-lock='true' mapping='logical'> <entity name='account'> <attribute name='name' /> <filter type='and'> <condition attribute='statuscode' operator='eq' value='1' /> <condition attribute='accountid' operator='eq' value='{0}' /> </filter> <link-entity name='contact' from='contactid' to='primarycontactid' alias='ab'> <attribute name='fullname' alias='as_fullname' /> <attribute name='firstname' alias='as_firstname' /> <attribute name='lastname' alias='as_lastname' /> </link-entity> </entity> </fetch>", accountId.ToString()); var fetchExp = new FetchExpression(fetchXML); EntityCollection accountEntity = orgService.RetrieveMultiple(fetchExp); if (accountEntity.Entities.Count > 0) { //Primary Contact Fullname AliasedValue avContactFullname = accountEntity.Entities[0].GetAttributeValue<AliasedValue>("as_fullname"); if (avContactFullname != null) contactFullName = avContactFullname.Value; //Primary Contact Firstname AliasedValue avContactFirstname = accountEntity.Entities[0].GetAttributeValue<AliasedValue>("as_firstname"); if (avContactFirstname != null) contactFirstName = avContactFirstname.Value; //Primary Contact Lastname AliasedValue avContactLastname = accountEntity.Entities[0].GetAttributeValue<AliasedValue>("as_lastname"); if (avContactLastname != null) contactLastName = avContactLastname.Value; }

Thursday, March 26, 2015

Send Email Report Workflow Activity

using System;
using System.Activities;
using System.Text;
using SendEmailPDFReport.ReportService; // Add Reporting Service as Web Reference
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Workflow;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Crm.Sdk.Messages;
using Microsoft.Crm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Client;
using System.Collections.Generic;


namespace SendEmailPDFReport
{
    public class SendEmailPDF : CodeActivity
    {
        #region Input Parameters

        [Input("Report ID")]
        [ReferenceTarget("report")]
        public InArgument<EntityReference> ReportID { get; set; }

        [RequiredArgument]
        [Input("From")]
        [ReferenceTarget("queue")]
        public InArgument<EntityReference> From { get; set; }

        [RequiredArgument]
        [Input("To")]
        [ReferenceTarget("contact")]
        public InArgument<EntityReference> Recipient { get; set; }

        [RequiredArgument]
        [Input("Subject")]
        public InArgument<string> Subject { get; set; }

        [RequiredArgument]
        [Input("Report Parameter")]
        public InArgument<string> ReportParameter { get; set; }

        [RequiredArgument]
        [Input("Report URL")]
        public InArgument<string> ReportURL { get; set; }

        [RequiredArgument]
        [Input("E-mail")]
        [ReferenceTarget("email")]
        public InArgument<EntityReference> Email { get; set; }

        [RequiredArgument]
        [Input("Report Name")]
        public InArgument<string> ReportName { get; set; }


        #endregion

        protected override void Execute(CodeActivityContext context)
        {
            StringBuilder sb = new StringBuilder("Starting; ");

            try
            {
                //Create the tracing service
                ITracingService tracingService = context.GetExtension<ITracingService>();

                //-----------------------------------
                // Workflow Context & Service Objects
                //-----------------------------------

                IWorkflowContext workFlowContext = context.GetExtension<IWorkflowContext>();
                IOrganizationServiceFactory serviceFactory = context.GetExtension<IOrganizationServiceFactory>();
                IOrganizationService service = serviceFactory.CreateOrganizationService(workFlowContext.InitiatingUserId);


                OrganizationServiceContext orgContext = new OrganizationServiceContext(service);

                //--------------------------
                // Obtain the Input Argument
                // Report EntityReference
                //--------------------------

                Guid RptID = this.ReportID.Get(context).Id;
                Guid fromUserID = this.From.Get(context).Id;
                Guid sendto = this.Recipient.Get(context).Id;
                string SubjectTitle = this.Subject.Get(context);
                string rptParams = this.ReportParameter.Get(context);
                string rptURL = this.ReportURL.Get(context);
                Guid Emailent = this.Email.Get(context).Id;
                string rptName = this.ReportName.Get(context);

                tracingService.Trace("Retrieving Input Argument" + "ReportID: " + RptID + "fromUserID : " + fromUserID + "sendto: " + sendto + "Emailent " + Emailent);

                sb.AppendFormat("Retrieving Input Argument" + "ReportID: " + RptID + "Queue : " + fromUserID + "contact: " + sendto + "Emailent " + Emailent);

                // Credential to connect with CRM
                ReportExecutionService rs = new ReportExecutionService();
                rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
                rs.Url = this.ReportURL.Get(context);

                byte[] result = null;

                //--------------------------
                // 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 reportPath = string.Format("/{0}_MSCRM/CustomReports/{1}", workFlowContext.OrganizationName, ((EntityReference)context.GetValue(this.ReportID)).Id.ToString("B"));
                sb.AppendFormat("report path: {0}; ", reportPath);
                string format = "PDF";
                string historyID = null;
                string devInfo = @"<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>";

                ParameterValue[] parameters = new ParameterValue[1];
                parameters[0] = new ParameterValue();
                parameters[0].Name = "ClaimID";
                parameters[0].Value = rptParams.ToString();

                sb.AppendFormat("Parameter length: {0}; ", parameters.Length.ToString());

                //string showHideToggle = null;
                string encoding;
                string mimeType;
                string extension;
                Warning[] warnings = null;
                // ParameterValue[] reportHistoryParameters = null;
                string[] streamIDs = null;

                ExecutionInfo execInfo = new ExecutionInfo();

                ExecutionHeader execHeader = new ExecutionHeader();

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

                if (execInfo.CredentialsRequired)
                {
                    List<DataSourceCredentials> dsCredentials = new List<DataSourceCredentials>();
                    foreach (DataSourcePrompt dsp in execInfo.DataSourcePrompts)
                    {
                        DataSourceCredentials credentials1 = new DataSourceCredentials();
                        credentials1.DataSourceName = dsp.Name;
                        sb.Append("; DataSourceName: " + credentials1.DataSourceName);

                        credentials1.UserName = workFlowContext.InitiatingUserId.ToString();
                        sb.Append("; username: " + workFlowContext.InitiatingUserId.ToString());
                        credentials1.Password = workFlowContext.OrganizationId.ToString();
                        sb.Append("; pword: " + workFlowContext.OrganizationId.ToString());

                        dsCredentials.Add(credentials1);
                    }
                    execInfo = rs.SetExecutionCredentials(dsCredentials.ToArray());
                }

                rs.SetExecutionParameters(parameters, "en-us");
                String SessionId = rs.ExecutionHeaderValue.ExecutionID;
                sb.Append("Attempting the render; ");

                try
                {
                    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";
                    EntityReference regardingObject = new EntityReference("contact", sendto);
                    email.Attributes.Add("regardingobjectid", regardingObject);

                    //Creating EntityReference for from, to and cc. Need to be changed according to your requirement
                    EntityReference from = new EntityReference("queue", fromUserID);
                    EntityReference to = new EntityReference("contact", sendto);

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

                    Entity toParty = new Entity("activityparty");
                    toParty.Attributes.Add("partyid", to);

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

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

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

                    email.Attributes.Add("subject", "Test Report");
                    email.Attributes.Add("description", "Test description text..");
                    // Create the email
                    Guid emailID = service.Create(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["subject"] = "Report";
                    attachment["filename"] = "Report.pdf";
                    attachment["body"] = Convert.ToBase64String(result);
                    attachment["filesize"] = result.Length;
                    attachment["mimetype"] = "text/plain";
                    attachment["attachmentnumber"] = 1;
                    attachment["objectid"] = new EntityReference("email", new Guid(email.Id.ToString()));
                    attachment["objecttypecode"] = objecttypecode;

                    service.Create(attachment);

                    // Sending email
                    SendEmailRequest SendEmail = new SendEmailRequest();
                    SendEmail.EmailId = emailID;
                    SendEmail.IssueSend = true;
                    SendEmail.TrackingToken = "";
                    SendEmailResponse res = (SendEmailResponse)service.Execute(SendEmail);
                }

                catch (Exception err)
                {
                    throw new Exception(err.Message.ToString());
                }

            }
            catch (Exception ex)
            {
                throw new InvalidPluginExecutionException("An error occurred attaching the pdf: " + ex.Message + ": " + sb.ToString());
            }




        }
    }
}

Monday, March 9, 2015

Retrieve Metadata of a Boolean (Two Options) Attribute in Microsoft Dynamics CRM 2011/2013


Code to retrieve the boolean (Two Options) attribute metadata in CRM 2011. You need to pass the boolean value to get the Text.


public static string GetBoolText(IOrganizationService service, string entitySchemaName, string attributeSchemaName, bool value)
        {
            RetrieveAttributeRequest retrieveAttributeRequest = new RetrieveAttributeRequest
            {
                EntityLogicalName = entitySchemaName,
                LogicalName = attributeSchemaName,
                RetrieveAsIfPublished = true
            };
            RetrieveAttributeResponse retrieveAttributeResponse = (RetrieveAttributeResponse)service.Execute(retrieveAttributeRequest);
            BooleanAttributeMetadata retrievedBooleanAttributeMetadata = (BooleanAttributeMetadata)retrieveAttributeResponse.AttributeMetadata;
            string boolText = string.Empty;
            if (value)
            {
                boolText = retrievedBooleanAttributeMetadata.OptionSet.TrueOption.Label.UserLocalizedLabel.Label;
            }
            else
            {
                boolText = retrievedBooleanAttributeMetadata.OptionSet.FalseOption.Label.UserLocalizedLabel.Label;
            }
            return boolText;
        }

Friday, March 6, 2015

Set Option Set by OptionSet Text

function SetValue(optionsetAttribute, optionText)
{
 var options = Xrm.Page.getAttribute(optionsetAttribute).getOptions();
 for(i = 0; i < options.length; i++)
 {
  if (options[i].text == optionText)
   Xrm.Page.getAttribute(optionsetAttribute).setValue(options[i].value);
 }
}

Calling of the function

SetValue("new_country", "India")

Multi Pick List in CRM 2011/2013

I have a one req. in one of the CRM Projects where user want multiple selection option in Option Set

we can create a Multiple Pick List for Dynamic CRM 2011/2013 form too.


User can enter multiple data from Pick List by Checkbox. This will also work on in major browsers (IE, Firefox, Chrome). See the below screen shot.



Below is the js code:

// var_sc_optionset >>  Provide schema-name for Option Set field
// var_sc_optionsetvalue >> Provide schema-name for field which will
//                          store the multi selected values for Option Set
// OS >> Provide Option Set field object
//       (Ex:- document.getElementById("Option Set field schema-name"))
// OSV >> Provide text field object which will store the
//        multi selected values for Option Set
//       (Ex:- document.getElementById("text field schema-name"))

//Method to convert an optionset to multi select Option Set
function ConvertToMultiSelect(var_sc_optionset, var_sc_optionsetvalue, OS, OSV) {

    if (OS != null && OSV != null) {
        OS.style.display = "none";

        // Create a DIV container
        var addDiv = document.createElement("div");
        addDiv.id = var_sc_optionsetvalue + "_m";
        addDiv.style.width = "100%";
        addDiv.style.height = "80px";
        addDiv.style.background = "#ffffff";
        addDiv.style.color = "white";
        addDiv.style.overflow = "auto";
        addDiv.style.border = "1px #6699cc solid";
        OS.parentNode.appendChild(addDiv);

        // Initialise checkbox controls
        for (var i = 1; i < OS.options.length; i++) {
            var pOption = OS.options[i];
            if (!IsChecked(pOption.innerHTML, OS, OSV)) {
                var addInput = document.createElement("input");
                addInput.type = "checkbox";
                addInput.style.border = "none";
                addInput.style.width = "25px";
                addInput.style.align = "left";
                addInput.style.color = "#000000";
                addInput.onclick = function () {
                    OnSave(OS, var_sc_optionsetvalue);
                    createTable(var_sc_optionsetvalue);
                }

            }
            else {
                var addInput = document.createElement("input");
                addInput.type = "checkbox";
                addInput.checked = "checked";
                addInput.style.border = "none";
                addInput.style.width = "25px";
                addInput.style.align = "left";
                addInput.style.color = "#000000";
                addInput.onclick = function () {
                    OnSave(OS, var_sc_optionsetvalue);
                    createTable(var_sc_optionsetvalue);
                }

            }
            //Create Label
            var addLabel = document.createElement("label");
            addLabel.style.color = "#000000";
            addLabel.innerHTML = pOption.innerHTML;

            var addBr = document.createElement("br"); //it's a 'br' flag

            OS.nextSibling.appendChild(addInput);
            OS.nextSibling.appendChild(addLabel);
            OS.nextSibling.appendChild(addBr);
        }
    }
}

//Supported functions

// Check if it is selected
function IsChecked(pText, OS, OSV) {
    if (OSV.value != "") {
        var OSVT = OSV.value.split(",");

        for (var i = 0; i < OSVT.length; i++) {
           if (OSVT[i] == pText)
              return true;
        }
    }

    return false;
}

// var_sc_optionsetvalue >> Provide schema-name for field which will
//                          store the multi selected values for Option Set
// OS >> Provide Option Set field object
// Save the selected text, this field can also be used in Advanced Find
function OnSave(OS, var_sc_optionsetvalue) {
    var getInput = OS.nextSibling.getElementsByTagName("input");
    var result = "";

    for (var i = 0; i < getInput.length; i++) {
        if (getInput[i].checked) {
            result += getInput[i].nextSibling.innerHTML + ",";
        }
    }

    //save value
    control = Xrm.Page.getControl(var_sc_optionsetvalue);
    attribute = control.getAttribute();
    attribute.setValue(result);
}

function createTable(var_sc_optionsetvalue) {
    //get option set value
    var OptionValue = Xrm.Page.getAttribute(var_sc_optionsetvalue);
    var c_OptionValue = Xrm.Page.getControl(var_sc_optionsetvalue);
    var d_OptionValue = var_sc_optionsetvalue + "_d";

    if (OptionValue.getValue() != null) {

        c_OptionValue.setVisible(true);
        var OptionValueHtml = "<div style=\"overflow-y:auto;width:100%; min-height: 5em; max-height: 1000px;\">";

        OptionValueHtml += "<table style='width:100%;height: 100%;'>";
        var OptionValueV = OptionValue.getValue();

        var OptionValueT = OptionValueV.split(",");
        var cols = 0;
        for (var row = 0; row < OptionValueT.length - 1; row++) {
            OptionValueHtml += "<tr  style='height:20px;'>";
            for (var i = cols; i < cols + 3; i++) {
                OptionValueHtml += "<td style='width:33%;'>";
                if (OptionValueT[i] != null || OptionValueT[i] != undefined) {

                    OptionValueHtml += OptionValueT[i];
                }
                OptionValueHtml += "</td>";
            }
            cols = cols + 3;
            OptionValueHtml += "</tr>";
            if (cols >= OptionValueT.length) {
                break;
            }
        }

        OptionValueHtml += "</table>";
        OptionValueHtml += "</div>";
        document.getElementById(d_OptionValue).innerHTML = OptionValueHtml;
    }
    else {
        c_OptionValue.setVisible(false);
    }
}

Get files of last hour in Azure Data Factory

  Case I have a Data Factory pipeline that should run each hour and collect all new files added to the data lake since the last run. What is...