Thursday, May 28, 2015

Interface between systems - call to WS\ WCF service from CRM FAILED because Https request (validation errors)

Interface between systems - call to WS\ WCF service from CRM FAILED because Https request (validation errors)
The solution is to add the next code in plugin

  bool CertificateValidationCallBack(
    object sender,
    System.Security.Cryptography.X509Certificates.X509Certificate certificate,
    System.Security.Cryptography.X509Certificates.X509Chain chain,
    System.Net.Security.SslPolicyErrors sslPolicyErrors)
        {
            // If the certificate is a valid, signed certificate, return true.
            if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
            {
                return true;
            }
            // If there are errors in the certificate chain, look at each error to determine the cause.
            if ((sslPolicyErrors & System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors) != 0)
            {
                if (chain != null && chain.ChainStatus != null)
                {
                    foreach (System.Security.Cryptography.X509Certificates.X509ChainStatus status in chain.ChainStatus)
                    {
                        if (//(certificate.Subject == certificate.Issuer) &&
                           (status.Status == System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.UntrustedRoot))
                        {
                            // Self-signed certificates with an untrusted root are valid.
                            continue;
                        }
                        else
                        {
                            if (status.Status != System.Security.Cryptography.X509Certificates.X509ChainStatusFlags.NoError)
                            {
                                // If there are any other errors in the certificate chain, the certificate is invalid,
                                // so the method returns false.
                                return false;
                            }
                        }
                    }
                }
                // When processing reaches this line, the only errors in the certificate chain are
                // untrusted root errors for self-signed certificates. These certificates are valid
                // for default Exchange Server installations, so return true.
                return true;
            }
            else
            {
                // In all other cases, return false.
                return false;
            }

        }

View Class 


Enjoy,
Rami Heleg

Interface between systems - call to WS\ WCF service from CRM

Interface between systems - call to WS\ WCF service from CRM
The easy way to call WCF service using Plugin..
Invoke plugin from JS for instance by createing temp entity record
Write the next code in plugin:

public void Execute(IServiceProvider serviceProvider){
 IOrganizationService _srv = null;
 try
 {
  IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
 IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
 _srv = factory.CreateOrganizationService(context.InitiatingUserId);
  if (context.MessageName.ToLower() == "create"){
    HttpWebRequest httpWReq= HttpWebRequest)WebRequest.Create("https://service/lalala.asmx");
    ASCIIEncoding encoding = new ASCIIEncoding();
    string postData = "request";
    byte[] data = encoding.GetBytes(postData);
    httpWReq.Method = "POST";
    httpWReq.ContentType = "text/xml; charset=utf-8";
    httpWReq.Host = "iservices.service.example";
    httpWReq.ContentLength = data.Length;
    using (Stream stream = httpWReq.GetRequestStream()){
      Write(data, 0, data.Length);
      HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();
      string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
                    }
                }
       }
 catch (FaultException<OrganizationServiceFault> ex){}
 Catch (Exception ez){}
        }



Enjoy,
Rami Heleg

Friday, May 22, 2015

Performance – system settings

Performance – system settings.

1.       By default most application defined in debug mode.
Change from
<compilation debug=”true”/>
To
<compilation debug=”false”/>

2.        Update management Thread settings
3.       
parameter
default
recommended
maxIoThreads
20
100
maxWorkerThreads
20
100
minFreeThreads
8
88 * # CPUs
minLocalRequestFreeThreads
4
76 * # CPUs

Define parameters in machine config:
<processModel
enable="true"
timeout="Infinite"
idleTimeout="Infinite"
shutdownTimeout="0:00:05"
requestLimit="Infinite"
requestQueueLimit="5000"
restartQueueLimit="10"
memoryLimit="60"
webGarden="false"
cpuMask="0xffffffff"
userName="machine"
password="AutoGenerate"
logLevel="Errors"
clientConnectedCheck="0:00:05"
comAuthenticationLevel="Connect"
comImpersonationLevel="Impersonate"
responseDeadlockInterval="00:03:00"
maxWorkerThreads="100"
maxIoThreads="100"/>

<httpRuntime
executionTimeout="90"
maxRequestLength="4096"
useFullyQualifiedRedirectUrl="false"
minFreeThreads="352"
minLocalRequestFreeThreads="304"
appRequestQueueLimit="100"
enableVersionHeader="true"/>


3.       Reducing weight 401 pages

In CRM we have around 1000 request per minute to these pages. 
Good option is to clean the pages under folder: C:\Windows\Help\iisHelp\common

Enjoy,
Rami Heleg

Thursday, May 21, 2015

Steps to upgrade CRM 2013 – CRM 2016

1.       Back Database.
2.       Remove SQL Reporting extension from server

3.       Install CRM 2016: Downloaded from http://www.microsoft.com/en-us/download/details.aspx?id=42637


4. Insert CRM key.

5. Accept License agreement

6. Select organization to upgrade..
   if you have more organization after finish to upgrade to 2016 open deployment manager and update organization
 7. Define service account.. for instance define sand box in specific user







8.   Install SetupSrsDataConnector.exe from  CRM 2016 Files\SrsDataConnector










1.       Upgrade organizations to 2016
3.       Install framework 4.5.2 
4.       Update plugin to new version (4.5.2)
5.        Test CRM.

Converting HTML to description field in Email Activity show html tags..

To remove all HTML tags when insert the html to description fields replace the content with the next command:


Xrm.Page.getAttribute("description").setValue(Xrm.Page.getAttribute("description").getValue().replace(/<[^>]*>?/g, ""));


Enjoy,
Rami Heleg

Implement nolock in Fetch

By default SQL server defined to lock records when execute query and rows selected until finish to execute.. problem when we have many records.

to prevent lock records in CRM, DBA allow to define all database to work with no-lock and we have another option to request fetch with no lock.

Example:









Enjoy,
Rami Heleg

Database: Command to get Entities list related to Solution

//LangNumber  = 1031, 1036, 1037 etc... language code
//SolutionName = solution name

select DISTINCT  e.LogicalName ,l.label, s.UniqueName from entity e right join   LocalizedLabel l
on e.entityid = l.objectid inner join SolutionBase s
on e.SolutionId = s.SolutionId inner join SolutionComponentBase sb
on sb.SolutionId = s.SolutionId where l.LanguageId=LangNumber
and l.ObjectColumnName ='LocalizedName' and  s.UniqueName = 'SolutionName'


Enjoy,
Rami Heleg

Import solution failed.. get message "solution With Id = e25cd1e4-54ff-4bdc-890b-31b1d8c3c720 Does Not Exist"

When try to import solution get the next message:

Unhandled Exception: System.ServiceModel.FaultException`1[[Microsoft.Xrm.Sdk.OrganizationServiceFault, Microsoft.Xrm.Sdk, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]: solution With Id = e25cd1e4-54ff-4bdc-890b-31b1d8c3c720 Does Not ExistDetail:
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
  <ErrorCode>-2147220969</ErrorCode>
  <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
  <Message>solution With Id = e25cd1e4-54ff-4bdc-890b-31b1d8c3c720 Does Not Exist</Message>
  <Timestamp>2012-08-09T10:45:33.7307214Z</Timestamp>
  <InnerFault i:nil="true" />
  <TraceText i:nil="true" />
</OrganizationServiceFault>

To  solve this issue please open SQL Management and run the command 

DECLARE @SolID NVARCHAR(MAX)
SET @SolID = 'e25cd1e4-54ff-4bdc-890b-31b1d8c3c720'
SELECT
      t.name AS table_name,
      SCHEMA_NAME(schema_id) AS schema_name,
      c.name AS column_name,
      'SELECT * FROM ' + t.name + ' WHERE ' + c.name + ' = ''' + @SolID + '''' as Query
FROM sys.tables AS t
      INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE '%SolutionId%'
ORDER BY schema_name, table_name;

after find the record remove the record from database and try to import the solution again.

enjoy,
Rami Heleg

Wednesday, May 20, 2015

Restore CRM organization - Database

Restore CRM organization - Database 


1.       Open SQL and select Restore Database…

2.       Select Device and select database backup file

3.       Run the Restore – press OK


4.       Open deployment manager and press Import organization




5.  CRM is ready


Enjoy,
Rami Heleg

Close Opportunity as Lose

LoseOpportunityRequest loseReq = new LoseOpportunityRequest();
Entity OpportunityClose = new Entity("opportunityclose");
OpportunityClose.Attributes.Add("opportunityid", eOpportunity);
OpportunityClose.Attributes.Add("actualend", DateTime.Now);
OpportunityClose.Attributes.Add("actualrevenue", 0);
loseReq.Status = new OptionSetValue(((OptionSetValue)context.InputParameters["Status"]).Value);
loseReq.OpportunityClose = OpportunityClose;
service.Execute(loseReq);

Close Opportunity as Win


 WinOpportunityRequest winReq = new WinOpportunityRequest();
Entity OpportunityClose = new Entity("opportunityclose");
OpportunityClose.Attributes.Add("opportunityid", eOpportunity);
OpportunityClose.Attributes.Add("actualend", DateTime.Now);
OpportunityClose.Attributes.Add("actualrevenue", 0);

winReq.Status = new OptionSetValue(3);
winReq.OpportunityClose = OpportunityClose;
service.Execute(winReq);

Enjoy,
Rami Heleg

Set field Mandatory, Recommended


//Mandatory
 Xrm.Page.getAttribute("new_field").setRequiredLevel('required');
//Usual,
Xrm.Page.getAttribute("new_field").setRequiredLevel('none');
//Recommended
Xrm.Page.getAttribute("new_field").setRequiredLevel('recommended');

Enjoy,
Rami Heleg

Submit Fields even if fields disabled


If Fields in disabled mode CRM doesn't send the value to server.. because of that we have the property Submit


example:
Xrm.Page.getAttribute("new_field").setSubmitMode("always");

Full example - Assign Request – Client side

//Assign to user
    AssignRequest(Xrm.Page.data.entity.getId(), 'incident', result.fl_userid.Value, 'systemuser');
//Assign to Team
    AssignRequest(Xrm.Page.data.entity.getId(), 'incident', result.fl_teamid.Value, 'team');

function AssignRequest(targetID, targetLogicalName, assigneeID, assigneeLogicalName) {
    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:AssignRequest\" 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>Target</c:key>";
    requestMain += "            <c:value i:type=\"a:EntityReference\">";
    requestMain += "              <a:Id>" + targetID + "</a:Id>";
    requestMain += "              <a:LogicalName>" + targetLogicalName + "</a:LogicalName>";
    requestMain += "              <a:Name i:nil=\"true\" />";
    requestMain += "            </c:value>";
    requestMain += "          </a:KeyValuePairOfstringanyType>";
    requestMain += "          <a:KeyValuePairOfstringanyType>";
    requestMain += "            <c:key>Assignee</c:key>";
    requestMain += "            <c:value i:type=\"a:EntityReference\">";
    requestMain += "              <a:Id>" + assigneeID + "</a:Id>";
    requestMain += "              <a:LogicalName>" + assigneeLogicalName + "</a:LogicalName>";
    requestMain += "              <a:Name i:nil=\"true\" />";
    requestMain += "            </c:value>";
    requestMain += "          </a:KeyValuePairOfstringanyType>";
    requestMain += "        </a:Parameters>";
    requestMain += "        <a:RequestId i:nil=\"true\" />";
    requestMain += "        <a:RequestName>Assign</a:RequestName>";
    requestMain += "      </request>";
    requestMain += "    </Execute>";
    requestMain += "  </s:Body>";
    requestMain += "</s:Envelope>";
    try {
        var req = new XMLHttpRequest();
    }
    catch (e) {
        var req = new ActiveXObject("Msxml2.XMLHTTP");
    }
    req.open("POST", getServerUrlWithOrgServicePath(), isAsync)

    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");
    try { req.responseType = 'msxml-document'; } catch (e) { }
    req.send(requestMain);

    if (req.readyState == 4) {
        if (req.status == 200) {
            return true;
        }
        else {
            return req.responseXML;
        }
    }
}

function getServerUrlWithOrgServicePath() {
    var OrgServicePath = "/XRMServices/2011/Organization.svc/web";
    var serverUrl = Xrm.Page.context.getClientUrl();
    if (serverUrl.match(/\/$/)) {
        serverUrl = serverUrl.substring(0, serverUrl.length - 1);

    }
    return serverUrl + OrgServicePath;
}

Enjoy,
Rami Heleg

Remove new record in lookup

var lookup = FLHTM.GetElement('new_lookupid');
lookup.AddParam("ShowNewButton", "1");

Set lookup Values

//get values base fetch or ODATA

http://mscrm201x.blogspot.co.il/2015/05/full-example-get-contact-details-base_20.html

var lookupData = new Array();
var lookupItem = new Object();
lookupItem.id = result[0].accountid.Value; // SET ID
lookupItem.name = result[0].name.Value; //SET NAME
lookupItem.typename = "account"; //ENTITY NAME
lookupData[0] = lookupItem;
Xrm.Page.getAttribute('customerid').setValue(lookupData);

Attach Event on field - Client side


// select the field and define the event on change
 Xrm.Page.getAttribute('new_fieldName').addOnChange(FieldChanged);


function FieldChanged(){
alert('function FieldChanged');
}

Full example - get Contact Details base ODATA – Client side

function FormOnLoad() {
    try {
        if (Xrm.Page.data.entity.getId() == null) { return true; }
        var contactId = Xrm.Page.data.entity.getId();
        var queryUrl = "ContactSet(guid'" + contactId + "')"
        var result = RequestODATA(queryUrl);
        alert(result[0].FullName);
    }
    catch (ex) {
        alert(ex.message);
    }
}

function RequestODATA(query) {
    try {
        var xmlhttp = new XMLHttpRequest();
    }
    catch (e) {
        var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    }
    xmlhttp.open("GET", prependOrgName("/xrmservices/2011/organizationdata.svc/") + query, false);
    xmlhttp.send();
    return GetReturnObject(xmlhttp.responseText, null, "");
}

function GetReturnObject   (xmlText, linksArr, fatherNode) {
    var returnObjectNSResolver = { m: "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata", d: "http://schemas.microsoft.com/ado/2007/08/dataservices" };
    var Entities = new Array();
    Entities.flError = {};
    try {
        var xml = XUI.Xml.LoadXml(xmlText.replace('xmlns="http://www.w3.org/2005/Atom"', ""));
        var entrys = XUI.Xml.SelectNodes(xml, fatherNode + '/entry', null);

        var entityName = GetEntityName(xml);
        Entities.EntityName = entityName;
        for (var i = 0; !IsNull(entrys), i < entrys.length; i++) {
            var linksXML = entrys[i].getElementsByTagName('link');


            var obj = new Object();

            if (!IsNull(linksArr)) {
                obj.LinksExpanded = GetLinks2Expand(entrys[i], linksArr);
            }
            var props = XUI.Xml.SelectSingleNode(entrys[i], "content/m:properties", returnObjectNSResolver);
            for (var j = 0; j < props.childNodes.length; j++) {
                if (props.childNodes[j].nodeType != 1)
                    continue;
                var type = props.childNodes[j].getAttribute("m:type");
                var propName = props.childNodes[j].tagName.replace("d:", "");
                switch (IsNull(type) ? "" : type) {
                    case FieldTypes.int:
                    case FieldTypes.double:
                    case FieldTypes.long:
                    case FieldTypes.string:
                    case FieldTypes.datetime:
                    case FieldTypes.guid:
                    case FieldTypes.decimal:
                        var propValue = IsNull(XUI.Xml.GetText(props.childNodes[j])) ? "" : XUI.Xml.GetText(props.childNodes[j]);
                        eval("obj." + propName + " = null; var tempEval = null;");
                        tempEval = propValue;
                        var evalExpression = ("obj." + propName + " = tempEval");
                        break;
                    case FieldTypes.bool:
                        var propValue = IsNull(XUI.Xml.GetText(props.childNodes[j])) ? "false" : XUI.Xml.GetText(props.childNodes[j]);
                        if (propValue == "")
                            propValue = "false";
                        var evalExpression = "obj." + propName + " = " + FixedString(propValue) + ";";
                        break;
                    case FieldTypes.money:
                    case FieldTypes.optionSetValue:
                        var value = XUI.Xml.SelectSingleNode(props.childNodes[j], 'd:Value', returnObjectNSResolver);
                        var propValue = IsNull(value) ? "" : XUI.Xml.GetText(value);
                        break;
                    case FieldTypes.entityReference:
                        var id = IsNull(XUI.Xml.SelectSingleNode(props.childNodes[j], 'd:Id', returnObjectNSResolver)) ? "" : "'" + XUI.Xml.GetText(XUI.Xml.SelectSingleNode(props.childNodes[j], 'd:Id', returnObjectNSResolver)) + "'";
                        var logic = IsNull(XUI.Xml.SelectSingleNode(props.childNodes[j], 'd:LogicalName', returnObjectNSResolver)) ? "" : "'" + XUI.Xml.GetText(XUI.Xml.SelectSingleNode(props.childNodes[j], 'd:LogicalName', returnObjectNSResolver)) + "'";
                        var display = IsNull(XUI.Xml.SelectSingleNode(props.childNodes[j], 'd:Name', returnObjectNSResolver)) ? "" : "'" + FixedString(XUI.Xml.GetText(XUI.Xml.SelectSingleNode(props.childNodes[j], 'd:Name', returnObjectNSResolver))) + "'";
                        break;
                }
                eval(evalExpression);
            }
            Entities.push(obj);
        }

        if (Entities.length == 0) {
            var error = xml.getElementsByTagName('error');

            if (!IsNull(error[0])) {
                Entities.flError.Message = XUI.Xml.GetText(XUI.Xml.SelectSingleNode(error[0], 'message', null));
                Entities.flError.Code = 1;
            }
            else {
                Entities.flError.Message = "Query with returned no results";
                Entities.flError.Code = 2;
            }
        }
        else {
            Entities.flError.Message = "";
            Entities.flError.Code = 0;
        }
    } catch (e) {
        Entities.flError.Message = e.message;
        Entities.flError.Code = 3;
    }

    return Entities;
}

function GetEntityName (xml) {
    var retVal = "";
    var node = XUI.Xml.SelectSingleNode(xml, "//link[@rel='edit']", null);
    if (!IsNull(node)) {
        retVal = node.getAttribute("title");
    }
    return retVal;
}


function GetLinks2Expand   (xmlTemp, linksArr) {
    var xml = new ActiveXObject("Microsoft.XMLDOM");
    xml.loadXML(xmlTemp.xml);
    var xpathOne = "m:inline";
    var xpathMany = "m:inline/feed";
    var xmlDeclaration = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>";
    var retArray = new Array();
    for (var i = 0; i < linksArr.length; i++) {
        var node = XUI.Xml.SelectSingleNode(xml, "//link[@title = '" + linksArr[i] + "']", null);
        if (!IsNull(node)) {
            var title = node.getAttribute('title');
            var tmpArr;
            if (!IsNull(XUI.Xml.SelectSingleNode(node, xpathMany, null))) {
                tmpArr = this.GetReturnObject(xmlDeclaration + XUI.Xml.SelectSingleNode(node, xpathMany, null).xml, null, "feed");
            }
            else if (!IsNull(XUI.Xml.SelectSingleNode(node, xpathOne, null))) {
                tmpArr = this.GetReturnObject(xmlDeclaration + XUI.Xml.SelectSingleNode(node, xpathOne, null).xml, null, xpathOne);
            }
            if (!IsNull(title) && !IsNull(linksArr)) {
                var LinkObject = new Link(title, tmpArr);
                retArray.push(LinkObject);
            }
        }
    }
    return retArray;
}

FieldTypes = {
    int: "Edm.Int32",
    long: "Edm.Int64",
    bool: "Edm.Boolean",
    guid: "Edm.Guid",
    datetime: "Edm.DateTime",
    decimal: "Edm.Decimal",
    optionSetValue: "Microsoft.Crm.Sdk.Data.Services.OptionSetValue",
    money: "Microsoft.Crm.Sdk.Data.Services.Money",
    entityReference: "Microsoft.Crm.Sdk.Data.Services.EntityReference",
    double: "Edm.Double",
    string: ""
}

function  FixedString(str) {
    str = str.replace("\\", "\\\\");
    str = str.replace(/\'/g, "\\'");
    var newStr = str;
    return newStr;
}

Enjoy,
Rami Heleg