Friday, June 7, 2013

Enable WCF compression to Improve CRM2011 Netowrk Performance

Enable compression using a command line.

1. Open the Command Prompt on the CRM Server.

2. Run the following command:    

%SYSTEMROOT%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/soap%u002bxml; charset=utf-8',enabled='true']" /commit:apphost

3. Reset IIS for the setting to take effect.

Enable compression by manually updating the ApplicationHost.Config

1. On the CRM Server Navigate to: C:\Windows\System32\Inetsrv\Config\applicationHost.config and open it with notepad.

2. Search for the Section: “” and in that section you should fine an entry that looks like this: 

3. Below that, add the following line: 

4. Save the file and reset IIS for the setting to take effect.

Note: You may notice an increase in CPU utilization with compression enabled so be sure to monitor CPU accordingly

Thursday, October 18, 2012

Dynamics CRM 2011 JavaScript “Access is Denied” Error with OData call

Dynamics CRM 2011 JavaScript “Access is Denied” Error with OData call
In CRM 2011 on load of JS users geting ""Access is Denied" error if they have OData call
when they use the Xrm.Page.context.getServerUrl();

Use the below JS
document.location.protocol + "//" + document.location.host + "/" + Xrm.Page.context.getOrgUniqueName();

Tuesday, June 12, 2012

CRM 2011 User does not have send-as privilege



CRM 2011 User does not have send-as privilege

When you have workflows in CRM 2011 that create e-mails for other users, like say, send an e-mail from the person who last modified an account to the owner of the account, you’re probably going to end up with e-mails staying in Draft.
When you want to send the e-mail afterwards you’re greeted with a nice: “User does not have send-as privilege.” (ErrorCode: -2147203059) exception.
When you look up the privilege, it’s nowhere to be found in the UI.
You can however set it (as suggested on the Microsoft Forum) in the Personal Settings.


The downside, you only get this option when you have the System Administrator role and no other.
When looking in the database, there is actually a prvSendAsUser privilege, so after assigning it to a general role that all users get like this:
AddPrivilegesRoleRequest addPrivilegesRequest = new AddPrivilegesRoleRequest
{
RoleId = new Guid(generalroleid),
Privileges = new[]
{
// Grant prvSendAsUser privilege.
new RolePrivilege
{
PrivilegeId = new Guid("6FD3EB4F-66E3-4587-B4AB-C064F03AD783"),
Depth = PrivilegeDepth.Global
}
}
};
service.Execute(addPrivilegesRequest);
If you afterwards have a look at the user’s privileges in the database with this query:
SELECT p.name
FROM SystemUser u
JOIN filteredSystemUserRoles sur ON sur.systemuserid = u.systemuserid
JOIN RolePrivileges rp ON rp.roleid = sur.roleid
JOIN FilteredPrivilege p ON p.privilegeid = rp.PrivilegeId
You’ll see that the user has in fact got the prvSendAsUser role.
But when you try to send an e-mail the problem stays the same.
The solution however is very simple, check for this privilege is not done in through privileges, despite what the exception makes you suggest, but is checked in the user settings.
Running an easy update query will fix this for you:
UPDATE UserSettings
SET IsSendAsAllowed = 1
WHERE IsSendAsAllowed = 0
Logical, no; but does it work, yes

Monday, May 7, 2012

CRM2011 oData: Retrieve Lookup and String field values using JS and REST Endpoints


CRM2011 oData: Retrieve Lookup, String field values using JS and REST Endpoints 

// JScript source code
function lookupvalidation() {
    var TechExpert = new Array();
    TechExpert = Xrm.Page.getAttribute("msft_technicalexpertiseid").getValue();

    if (TechExpert != null) {
        var name = TechExpert[0].name;
        var uniqueid = TechExpert[0].id;
        var entType = TechExpert[0].entityType;

        //Required ODataQuery
        var context = parent.Xrm.Page.context;
        var serverUrl = context.getServerUrl();
        var odataSelect = serverUrl + "/xrmservices/2011/OrganizationData.svc/msft_technologySet?$select=msft_CategoryId,msft_PandL&$filter=msft_technologyId eq guid'"
+ uniqueid + "'";
        //  alert(odataSelect);

        $.ajax({
            type: "GET",
            contentType: "application/json; charset=utf-8",
            datatype: "json",
            url: odataSelect,
            beforeSend: function (XMLHttpRequest) { XMLHttpRequest.setRequestHeader("Accept", "application/json"); },
            success: function (data, textStatus, XmlHttpRequest) {

                // Multiple Entities retrieval
                ProcessReturnedEntities(data.d.results);

            },
            error: function (XmlHttpRequest, textStatus, errorThrown) { alert('OData Select Failed: ' + odataSelect); }
        });

    }

}

function ProcessReturnedEntities(ManyEntities) {
    // var AwardCategory = new Array();
    //AwardCategory = ManyEntities[0].msft_CategoryId;  

    var id = ManyEntities[0].msft_CategoryId.Id;
    var name = ManyEntities[0].msft_CategoryId.Name;
    var entityType = ManyEntities[0].msft_CategoryId.LogicalName;

    var AwardCategory = new Array();
    AwardCategory[0] = new Object();
    AwardCategory[0].id = id;
    AwardCategory[0].name = name;
    AwardCategory[0].entityType = entityType;

    var PL = ManyEntities[0].msft_PandL;

    //Assign AwardCategory based on Technical Experitise
     if (AwardCategory != null)
     Xrm.Page.getAttribute("msft_awardcategoryid").setValue(AwardCategory);


    //Assign Product&Language based on Technical Expertise
    if (PL != null)
        Xrm.Page.getAttribute("msft_pl").setValue(PL);

}

Wednesday, May 2, 2012


CRM2011-MultiForm: Display default form based on the Optionset/Lookup field values on the form.



  var programlookup = new Array();
    programlookup = Xrm.Page.getAttribute("msft_programid").getValue();

    if (programlookup != null)
    {

        var name = programlookup[0].name;
        var guid = programlookup[0].id;
        var entType = programlookup[0].entityType;
        // alert(Xrm.Page.ui.formSelector.getCurrentItem().getLabel());

        if (Xrm.Page.ui.formSelector.getCurrentItem() != null)
        {
            var formlabel = Xrm.Page.ui.formSelector.getCurrentItem().getLabel();
            if (formlabel != name)
            {
                var items = Xrm.Page.ui.formSelector.items.get();
                for (var i in items)
                {
                    var item = items[i];
                    var itemId = item.getId();
                    var itemLabel = item.getLabel()

                    if (itemLabel == name)
                    {
                        var attributes = Xrm.Page.data.entity.attributes.get();
                        for (var j in attributes)
                            attributes[j].setSubmitMode("never");
                        item.navigate();
                    }

                }
            }
        }
    }

Disadvantages: 
1. Performance(Form will load twice if last opened form is not same as field value)
2. On load page will blink
3. Make optionset/lookup field readonly so that user can't change the values

Plugin: Revoke sharing permissions to all USERS/TEAMS associated to a record

Plugin: Revoke sharing permissions to all USERS/TEAMS associated to a record


              public void Execute(IServiceProvider serviceProvider)

        {
            try
            {
                IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
                IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                service = factory.CreateOrganizationService(context.UserId);

                if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
                {
                    Entity entity = (Entity)context.InputParameters["Target"];

                    string _contact = entity.LogicalName;
                    Guid _contactid = entity.Id;

                    if (entity.LogicalName == "contact")
                    {
                        RetrieveSharedPrincipalsAndAccessRequest retrieveSharedRequest = new RetrieveSharedPrincipalsAndAccessRequest()
                    {
                        Target = new EntityReference(context.PrimaryEntityName, context.PrimaryEntityId)

                    };
                        RetrieveSharedPrincipalsAndAccessResponse retrieveSharedResponse = (RetrieveSharedPrincipalsAndAccessResponse)service.Execute(retrieveSharedRequest);
                        RevokeAccessRequest revokeRequest = new RevokeAccessRequest();
                        revokeRequest.Target = new EntityReference(_contact, _contactid);

                        foreach (PrincipalAccess principal in retrieveSharedResponse.PrincipalAccesses)
                        {
                            revokeRequest.Revokee = principal.Principal;
                            service.Execute(revokeRequest);
                        }


                    }
                }
            }


Note: Please test before using this code

Thursday, June 9, 2011

Microsoft Dynamics CRM Architecture

Microsoft Dynamics CRM Architecture

In order to effectively customize Microsoft Dynamics CRM, you must first have good understanding of the application's architecture. The system's architecture influences how and where you can customize the system components.

The key to understanding the Microsoft Dynamics CRM architecture as it relates to customization is the Microsoft Dynamics CRM platform. One way to understand the value of the Microsoft Dynamics CRM platform is to contrast it with the client/server (two-tier) architecture that has been around for more than two decades.

Client/Server Architecture

In client/server architecture, most of the application logic is found in the client. The client processes the information and the server is typically just the database that processes transactions and stores the data. The services that the database provides may be unappreciated now that users have become accustomed to them. However, consider the difficulty that developers may face if they had to devise their own methods to store, retrieve, and manage data without the database.

The database simplifies much of the complexity that a developer has to deal with and provides him or her with the means to interact with the data through available APIs using languages such as Transact-SQL. But the client/server architecture has many shortcomings and there is only so much that a database designed for general use can provide.

Microsoft Dynamics CRM's Multi-Tier Architecture

Microsoft Dynamics CRM is a web-based application that uses a multi-tier architecture. This structure provides many benefits that support scalability, flexibility, and extensibility that cannot be matched using client/server architecture.

MICROSOFT DYNAMICS CRM CUSTOMIZATION ARCHITECTURE

In this multi-tier design, the Microsoft Dynamics CRM platform serves as an intermediary between the software developer and the database. Just as the database provides important services in the client/server architecture, the Microsoft Dynamics CRM platform provides a set of CRM specific APIs that not only handles interaction with the database, but also provides all the building blocks for the Microsoft Dynamics CRM application.

The parts of the picture marked with a cogindicate places where the Microsoft Dynamics CRM customizer can interact with the platform through code, the UI, custom reports etc. This course concentrates on the part labeled Extendable Application. The other parts will be described briefly, but detailed treatment is beyond the scope of this course.

The Microsoft Dynamics CRM platform removes the complexity that developers may otherwise have to deal with and provides a rich environment for customizing the application. Because it is designed specifically for use as a Relationship Management platform, it can provide more specific features that programmers can use when they build applications that use it.

The Business Entity Components part of the platform is responsible for creating domain-specific objects. Examples of domain-specific objects in Microsoft Dynamics CRM include Contact, Lead, Opportunity, Account, and Business Unit. These objects are created in response to instructions from the Application platform, ultimately from the Microsoft Dynamics standard UI or from customization code.

The goal of the Microsoft Dynamics CRM platform is to implement the service rules by manipulating and combining the underlying domain-specific objects. The platform accomplishes this by:

· Controlling access to objects through security

· Controlling access to the database through the data access layer

· Raising events for workflow processes and custom business logic implementations

Except for reports, every application that interacts with Microsoft Dynamics CRM does so through Web services in the Microsoft Dynamics CRM platform. This includes the Workflow tools and solutions created by ISVs. In summary, think of the platform layer as providing the entire infrastructure that is required to implement a complete Microsoft Dynamics CRM (or Extended CRM) application.

Domain and Business Logic

The platform by itself does not impose business-specific logic. This layer imposes only generic domain constraints. It contains the components for an application, but by itself is nothing more than a collection of related objects. However, the interaction between these domain specific objects implements more extensible business logic for the organization. You can apply business logic at the platform through workflow processes and plug-ins; or through the UI using Dialogs or event scripts on Forms.

· Microsoft Dynamics CRM Workflow enables you to create automated business processes at the platform layer. Workflow processes perform actions based on rules set up by the business. Workflow processes are triggered by events within Microsoft Dynamics CRM when specific actions are performed and specified conditions are met. The Workflows apply the business logic using built in steps or by allowing developers to add their own custom code to carry out a step.

· Plug-ins refer to the ability to create business logic extensions using pre- and post-plug-ins available in the platform. Plug-ins are extension points made available by the Microsoft Dynamics CRM platform. There is a published set of events that a Plug-In can subscribe to. As part of the subscription, a developer must specify an event handler, which is a segment of customized code that runs in response to the system event. There are certain parts of the Microsoft Dynamics CRM application that include business logic that is not found in the platform and cannot be customized.

An example of this is the logic that converts a Lead into a Contact, Account, and Opportunity. This behavior occurs because the application interacts with the platform to create these new objects based on programmatic information stored in the Lead object. The platform creates the Lead, but the built-in business logic performed by the application converts the Lead to a Contact, Account, and Opportunity.

Database Access

The Microsoft Dynamics CRM platform has a Data Access layer to handle all interactions between the application and Microsoft SQL Server, which contains the Microsoft Dynamics CRM database.

Developers must not directly access or update the CRM database for the following reasons:

· It introduces the opportunity for invalid or corrupt data to be added to the database, which in turn can cause the Microsoft Dynamics CRM platform to function incorrectly.

The Microsoft Dynamics CRM database structure might change without notice in a future release.