Search This Blog

Tuesday, September 6, 2011

CRM 2011: Jscript to Read Optionset selected text using Metadata service

Hi,
Recently I was working on an assignment where I had to retrieve data of a lookup record using Jscript, I accomplished to retrieve the lookup record's data using RestFul services. But I found that for the optionset field on the lookup record, i got back only the value (integer) of the selected option, whereas i was expecting to get both, value as well as its text. only later i found that to retrieve its text, I had to do a soap request to the organization metadata service.
Here;s the code which will get the optionset's text. You need to supply the entity logical name, attribute logical name & its selected value, to get back the text of selection option.

function RetrieveAttributeSync(EntityLogicalName, LogicalName, MetadataId, RetrieveAsIfPublished, attributeValue) {

    var ODataPath;
    var serverUrl = Xrm.Page.context.getServerUrl();
    ODataPath = serverUrl + "/XRMServices/2011/Organization.svc/web";

    var request = "<Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
    request += "<request i:type=\"a:RetrieveAttributeRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
    request += "<a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
    request += "<a:KeyValuePairOfstringanyType>";
    request += "<b:key>EntityLogicalName</b:key>";
    request += "<b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + EntityLogicalName + "</b:value>";
    request += "</a:KeyValuePairOfstringanyType>";
    if (MetadataId == null)
    { MetadataId = "00000000-0000-0000-0000-000000000000"; }
    request += "<a:KeyValuePairOfstringanyType>";
    request += "<b:key>MetadataId</b:key>";
    request += "<b:value i:type=\"ser:guid\"  xmlns:ser=\"http://schemas.microsoft.com/2003/10/Serialization/\">" + MetadataId + "</b:value>";
    request += "</a:KeyValuePairOfstringanyType>";
    request += "<a:KeyValuePairOfstringanyType>";
    request += "<b:key>RetrieveAsIfPublished</b:key>";
    request += "<b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + RetrieveAsIfPublished + "</b:value>";
    request += "</a:KeyValuePairOfstringanyType>";
    request += "<a:KeyValuePairOfstringanyType>";
    request += "<b:key>LogicalName</b:key>";
    request += "<b:value i:type=\"c:string\"   xmlns:c=\"http://www.w3.org/2001/XMLSchema\">" + LogicalName + "</b:value>";
    request += "</a:KeyValuePairOfstringanyType>";
    request += "</a:Parameters>";
    request += "<a:RequestId i:nil=\"true\" /><a:RequestName>RetrieveAttribute</a:RequestName></request>";
    request += "</Execute>";
    request = _getSOAPWrapper(request);

    var req = new XMLHttpRequest();
    req.open("POST", ODataPath, false);
    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");
    req.send(request);

    if (req.responseXML != null) {
        var attributeData = req.responseXML.selectSingleNode("//b:value");
        if (attributeData != null) {
            var attributeType = attributeData.selectSingleNode("c:AttributeType").text;

            switch (attributeType) {
                case "Picklist":
                    return getPickListTextValue(attributeData, attributeValue);
                    break;
                default:
                    break;

            }


function getPickListTextValue(attributeData, attributeValue) {
    var options = attributeData.selectSingleNode("c:OptionSet//c:Options");
    for (var i = 0; i < options.childNodes.length; i++) {
        var value = options.childNodes[i].selectSingleNode("c:Value").text;
        if (value == attributeValue['Value']) {
            var text = options.childNodes[i].selectSingleNode("c:Label").selectSingleNode("a:UserLocalizedLabel").selectSingleNode("a:Label").text;
            return text;
        }
    }
}


Thus by using the above code, you will be able to retrieve all the items (text & value) of the option set  in JScript.

Hope this post will be helpful to someone, as I struggled with this functionality !!

Good Luck :)



Tuesday, July 19, 2011

CRM 2011: Plugin Registration Tool Error - Unable to load assembly !!


Recently I wrote a custom workflow to create a direct URL for a record within CRM & output the formatted URL, so that it can be used in email alerts to the users.
I faced this peculiar problem while I was registering the custom workflow assembly using the new Plugin Registration tool on my client server. I was unable to load my custom workflow assembly onto the plugin registration tool, whenever I choose to load the assembly on the tool, it gave me an error message:
Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'file:///C:\Plugin Registration Tool\PluginRegistration.exe' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)
   at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection, Boolean suppressSecurityChecks)
   at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
   at System.Reflection.Assembly.LoadFrom(String assemblyFile, Evidence securityEvidence)
   at System.Activator.CreateInstanceFromInternal(String assemblyFile, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo)
   at System.AppDomain.CreateInstanceFrom(String assemblyFile, String typeName)
   at System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName)
   at System.AppDomain.CreateInstanceFromAndUnwrap(String assemblyName, String typeName)
   at PluginRegistrationTool.AppDomainContext`1..ctor() in C:\pluginregistration\AssemblyReader.cs:line 41
   at PluginRegistrationTool.RegistrationHelper.RetrievePluginsFromAssembly(String pathToAssembly) in C:\pluginregistration\RegistrationHelper.cs:line 40
   at PluginRegistrationTool.PluginRegistrationForm.btnLoadAssembly_Click(Object sender, EventArgs e) in C:\pluginregistration\PluginRegistrationForm.cs:line 166
Inner Exception: System.NotSupportedException: An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enable CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please enable the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information.
The reason I got this error was on the client server was that, the file was blocked on the server !!
Yes, now on some new server OS’s, this feature is enabled by default i.e. any external file that you deploy on the server will be blocked. You have to exclusively unblock the file & then use it to deploy!!
On suggestions from one of my peers, I unblocked the files (workflow assembly & all the files within the plugin registration tool) & then it worked like a charm!!  Everything went smooth later on!!
Unblocking the files: Right click on the file & if you see a unblock button on the properties dialog, then unblock it, else the file is already unblocked!!

I had a day wasted due to this small thing!! hope this helps someone !!

Thanks !!

Friday, July 15, 2011

CRM 2011 Custom workflow


Today I was working on custom workflow activities for CRM 2011. There are lot of changes,  the way you write custom workflow code w.r.t CRM 2011. First thing, you need VS2010 on your system to start working with your project.
Choose a workflow activity library project on your VS 2010.
Add Microsoft.Xrm.sdk & Microsoft.Xrm.sdk.Workflow in your references to your project, when you add this, your project needs to be in .Net framework v 4.0.
Now comes the actual change !
Your workflow activity class needs to derive from a class named: CodeActivity ( a class present in System.Activities, remember to add this assembly in your project references and remove system.workflow.Activities from your directives else this will cause ambiguous error).
We have a new service which can be used for tracing your workflow code or plugin code, called ITracing service.  You can use this service to trace through your code at runtime, you can write messages to it.
You can see how to use this service at the below link:
 
Now coming back to our custom workflow code, there are changes in the way you declare your input & output properties. In CRM 4.0 we used to declare a dependency property for an input or output properties, but in CRM 2011 it’s as shown below:
[Input("Input Value")]
        [Default("Hello")] // this default value will be used if nothing you have specified in your input
        public InArgument<string> ServerName { get; set; }

        [Output("Output value")]
        public OutArgument<string> OutputValue { get; set; }

For more on how to declare your inputs & outputs, refer below link:
After this the usual, strong name your assembly & go on to register your workflow assembly using the new Plugin registration Tool for CRM 2011.
List of changes between CRM 4.0 custom workflow & CRM 2011 Custom workflow code is well explained in the below link:

Hope with this information you can go ahead and build custom workflow activities for CRM 2011.
Good Luck!!

Friday, July 1, 2011

Microsoft Dynamics CRM 2011 – Filtered Lookups

In CRM 4.0, creating a “Filtered Lookup” was… well… kind of a pain. It required quite a bit of JavaScript on the Form in order for the filter to work correctly and if you needed to make additional modifications later on… !
In CRM 2011, the filtered lookups are simple, and you don’t have to know JavaScript to create them.
Example 1: I would like the “Out of the box” Primary Contact lookup on the Account, to ONLY show the contacts that are related to that particular Account. (Very Common request)
Step 1: Access the Account form (From your Solution or Main Customization Area)


Step 2: Open the Form and “Double Click” the Primary Contact field to access the Attribute Properties, then scroll to the bottom of the Field Properties window to adjust the properties of the Lookup!


In addition to being able to filter on Related Records, you can create Filtered views and have the Lookup use it as the default!
Example 2: In CRM, I have multiple “Account Types“. The Account Type field is a Picklist (Option Set) with the following choices: Hospital and Surgery Center. I would like to add an additional Lookup field on the Account form that looks up all Accounts with the “Account Type” of “Surgery Center“.
Step 1: Create the View that filters all Accounts where the Account Type = Surgery Center


Step 2: Create a new Lookup field on the Account Form. (Account to Account)
  1. Access the Account form (Customization Area)
  2. New to CRM 2011 – Create the Lookup directly from the Form!– At the bottom of the Account form, click “New” to create a new Field.

  3. Add your display name and choose the Field “Type” of Lookup.

  4. After the field has been created, add the field to the form using the new “Drag and Drop” functionality.

  5. Double click the field to open its properties

  6. Change the “Default View” to your new View!
As always, make sure to publish your changes to make them available to the users!

Orginal Post:
http://www.powerobjects.com/blog/2011/02/17/microsoft-dynamics-crm-2011-%E2%80%93-filtered-lookups/

Other posts:
http://crmconsultancy.wordpress.com/2011/05/17/filtered-lookups-in-crm-2011/

Thursday, June 9, 2011

Microsoft Dynamics CRM 2011 Virtual Machine is now available !!

The Microsoft Dynamics CRM 2011 Virtual Machine (VM) is now available for Microsoft Dynamics CRM partners to download from the PartnerSource website.
This VM is intended to address these main objectives:
  • Accelerate customer-facing demonstrations by providing baseline infrastructure, enhanced data, and rich scenarios.
  • Enable development and testing of Microsoft Dynamics CRM 2011 demos and solutions in an offline environments where an Internet connection is not readily available.
The Microsoft Dynamics CRM 2011 VM bill of materials consists of two separate VMs:
  • Microsoft Dynamics CRM 2011 VM-01: DC, SQL, CRM
  • Microsoft Dynamics CRM 2011 VM-02: Exchange (optional)
Included in Microsoft Dynamics CRM 2011 VM-01 are the following deployments:
Microsoft Dynamics Core CRM 2011 Environment
A basic CRM environment that contains sample data and preconfigured SharePoint integration.
Microsoft Dynamics CRM Demo Scenarios Environment
More comprehensive demonstrations illustrating core CRM capabilities in expanded scenarios.
  • Marketing, Sales, and Service scenarios
  • Enhanced data, dashboards, customisations, processes (workflows, and dialogs), SharePoint integration, and customer and partner portals
  • End-to-end script that ties each scenario together
xRM Environments
Configured examples of how Microsoft Dynamics CRM can be extended to vertical solutions.
  • Facility Management
  • Employee Management
  • Vendor Management
The VM can be downloaded from here: http://bit.ly/jcqY5i

Wednesday, February 2, 2011

SQL Server Login failed for user 'domain\Administrator'


SQL Login failed for user 'domain\Administrator' or 'sa' or any other user.
This happens for a lot of reason, one of the reasons may be, you have changed the domain controller of your server, where SQL was already installed.
When this happens, you cannot login to the SQL server with any account.
Then the resolution would be running the SQL instance in single-user mode.
How to do this , follow the below steps :
  1. In SQL Server Configuration Manager, click SQL Server Services.
  2. In the right pane, right-click SQL Server (<instance_name>), and then click Properties.
  3. On the Advanced tab, in the Startup Parameters box, type the parameters separated by semicolons (;).
    For example, to start in single-user mode, insert -m; in front of the existing startup options, and then restart the database. (When you start SQL Server in single-user mode, first stop SQL Server Agent. Otherwise, SQL Server Agent might connect first and prevent you from connecting as a second user.)
    Important noteImportant note: "After you are finished using single-user mode, you must remove the -m; from the Startup Parameters box before you can restart the server instance in the normal multi-user mode. "
  4. Click OK.
  5. Restart the Database Engine.
 Now when you have logged in to the SQL management studio, follow the below steps:
1. Expand the security node.
2. Right click on logins, create a new login for the new domain account.
3. Also, you can reset the SA password.

There you go, now your SQL server works fine.

Hope this hepls.

Tuesday, February 1, 2011

Verify Domain User account SPN for the Microsoft Dynamics CRM ASP.NET Application Pool account

"Caller does not have enough privilege to set the CallerOriginToken to the specified value". If you are seeing this error when you try to open your CRM for the first time, then you have tried installing your CRM using your domain account and you have ignored the below given warning message by the EDU during installation .
"Verify Domain User account SPN for the Microsoft Dynamics CRM ASP.NET Application Pool account."

Follow these below steps to resolve it.
  1. Using Windows Support Tools, setup the SPNs for the machine and service account (Important: needs to be done first)
    setspn –A HTTP/servername:5555 domain/serviceusername
    setspn –A HTTP/servername.company.com:5555 domain/serviceusername


    Note: Don’t forget the PORT
    Note: Don’t forget to do both the FQDN and the NetBios name
  2. Trust for Delegation enabled in AD for the Service Account AND CRM Machine

    Note: This option is only available after you add the SPN for the both the NetBios name and FQDN) in step #1
  3. Verify / add the service account to the CRM installation’s PrivUserGroup

    Note: This step must be done after installation. There is a known issue were setup will remove the user used for installation (the "setup user") and if this user is the same as the service account user, it will be missing.
  4. The service account needs to be added to the local machines IIS_WPG group
  5. Reset your IIS on the server.  OR Restart the CRM server. 
Hope this helps.

Original blog.
http://billoncrmtech.blogspot.com/2008/08/now-i-am-master-tips-for-running-crm-40.html

MS CRM 4.0 installation with SQL server 2008 R2 on WIN server 2008

I was trying to install MS CRM 4.0 on a windows server 2008, where I had SQL server 2008 R2 installed on it. Now I followed all the steps mentioned in the Microsoft KB article
http://support.microsoft.com/kb/950100

Everything seems to be fine, until I got a error saying "Service msftesql was not found on computer 'name'.
The specified service does not exist as an installed service".
Then after long hours of research found out that SQL server 2008 uses a different name for the Service msftesql".

Solution:
- Run > Regedit
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
- Rename MSSQLFDLauncher Folder to msftesql
- Reboot System
- Administrative Tools > Services > SQL Full-text Filter Daemon Launcher (MSSQLSERVER) and START the service
- Now try installing CRM, it goes fine.
- Rename back msftesql Folder to MSSQLFDLauncher.
- Restart the server.

Hurray !!! CRM got installed.