Search

Friday, May 21, 2010

Collapsable CRM section

attachCollapsableToSections();

function getElementsByCondition(condition, container) {
    container = container || document;
    var all = container.all || container.getElementsByTagName('*');
    var arr = [];
    for (var k = 0; k < all.length; k++) {
        var elm = all[k];
        if (condition(elm, k)) arr[arr.length] = elm;
    } return arr;
}

function attachCollapsableToSections() { 
    var sections = getElementsByCondition(function(elm) {
        if (elm.className.indexOf("ms-crm-Form-Section") != -1)
            return true;
    }, null); 
    for (var i = 0; i < sections.length; i++) {
        sections[i].innerHTML = '<img  id="' + i + '_imgid" src="/_imgs/navup.gif" alt="Expanded, click to collapse"  style="cursor:hand;"/> <label id="' + i + '_lblid" />' + sections[i].innerHTML;
        sections[i].childNodes[0].attachEvent('onclick', toggleVisibility);
        sections[i].childNodes[2].attachEvent('onclick', toggleVisibility);       
    }
} 
function toggleVisibility(e) { 
    var sectionContainer = e.srcElement.parentNode.parentNode.parentNode;
    var elements = getElementsByCondition(function(elm) {
        if (elm.vAlign == "top") return true;
    }, sectionContainer);
    for (var i = 0; i < elements.length; i++) {
        if (elements[i].style.display == "none") {
            elements[i].style.display = "";
            if (e.srcElement.id.indexOf("_lblid") != -1) {
                var _imgid;
                _imgid = e.srcElement.id.replace(/(^\d+)(.+$)/i, '$1') + "_imgid";
                document.getElementById(_imgid).src = document.getElementById(_imgid).src.replace("navdown", "navup");
            }
            else {
                e.srcElement.src = e.srcElement.src.replace("navdown", "navup");
            }
        } else {
            elements[i].style.display = "none";
            if (e.srcElement.id.indexOf("_lblid") != -1) {
                var _imgid;
                _imgid = e.srcElement.id.replace(/(^\d+)(.+$)/i, '$1') + "_imgid";
                document.getElementById(_imgid).src = document.getElementById(_imgid).src.replace("navup", "navdown");
            }
            else {
                e.srcElement.src = e.srcElement.src.replace("navup", "navdown");
            }
        }
    }
}

Tuesday, May 11, 2010

LINQ on CRM SDK 4.0.12

  1. Download here.
  2. Generate linq code for CRM, from a command line – go to the SDK folder/Microsoft.xrm/Tools and run the following command line – replacing MyCrmServer with your actual server name, replace MyCrmOrg with your actual CRM Org and MyEntitiesFolder with the name. Note : This assumes using integrated authentication for on-premise – support is available for many different scenarios – check the docs.
crmsvcutil /connectionString:"Authentication Type=AD; Server=http://servername/crm_orgname; User ID=domain\username; Password=password;" /out:"C:\Entities"


I’m very excited to talk about the new LINQ to CRM libraries available recently. Say you need to retrieve an Account Number, given the Account Name…

Using the traditional webservice methods:

ColumnSet cols = new ColumnSet();
cols.AddColumns(new string[] {"accountnumber"});

QueryByAttribute query = new QueryByAttribute();
query.ColumnSet = cols;
query.EntityName = "account";
query.Attributes = new string[] {"name"};
query.Values = new string[] {"Microsoft Dynamics CRM"};

RetrieveMultipleRequest req = new RetrieveMultipleRequest();

req.Query = query;
req.ReturnDynamicEntities = true;
RetrieveMultipleResponse resp = oService.Execute(req) as RetrieveMultipleResponse;
BusinessEntityCollection becMultipleRecords = resp.BusinessEntityCollection;
if (deSalesOrder.Properties.Contains("accountnumber"))
{
//And So On
//And So Forth
}

Using LINQ to SQL:

var accounts = (from a in context.Accounts
where a.Name.Equals("Microsoft Dynamics CRM")
select a).ToList();
LINQ2CRM.Account acc = (Account)accounts.First();
Response.Write("Account name = " + acc.Name.ToString());

Friday, May 7, 2010

CRM 4.0 & .NET 4.0

For those that have had a chance to play with Visual Studio 2010 RC and .NET 4.0, you may have considered the possibility of writing CRM 4.0 extensions with this new framework. Unfortunately, this is not to be.

So what’s the problem exactly? The big jump is that Microsoft .NET 4.0 actually ships with a new version of the Common Language Runtime (CLR). It’s a bit confusing, but .NET 3.0 and .NET 3.5 actually used the .NET 2.0 CLR. This is because .NET 3.0 and 3.5 were really just a set of extensions to the framework and did not require an actual new runtime. This means that ASP.NET 2.x to 3.5 all used the same .NET 2.0 runtime! As such, Microsoft CRM 4.0 has no problem working with extensions that use the .NET 2.0 CLR, and takes advantage of framework extensions found in .NET 3.0 and 3.5.


So whether you run an in process plug-in or an asynchronous one, if you try to write a plug-in that uses the .NET 4.0 CLR you will get an error that looks something like this:

Microsoft.Crm.CrmException: Assembly cannot be loaded from C:\Program Files\Microsoft Dynamics CRM Server\server\bin\assembly\testing.dll. ---> System.BadImageFormatException: Could not load file or assembly 'file:///C:\Program Files\Microsoft Dynamics CRM Server\server\bin\assembly\testing.dll' or one of its dependencies.



This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.
 
For web pages/custom pages,
In theory, if you could get the CRM web site to run under ASP.NET 4.0, this would get around this error. However I am sure plenty of other things would break and this doesn’t help with plug-ins hosted by the Outlook client or the Asynchronous Service.
 
If you want to use .NET 4.0 with CRM 4.0, you are not entirely out of luck. As long as it runs in its own process space, either on the client (like a Silverlight 4.0 control) or on another web site (like an IFRAME or a pop-up dialog from a CRM form), things should work.
 
The good news of course is that Microsoft CRM 5.0 will be written take full advantage of .NET 4.0, WF 4.0 and more.