Showing posts with label dynamics crm 2011. Show all posts
Showing posts with label dynamics crm 2011. Show all posts

Thursday, October 9, 2014

Dynamics CRM 2011 recommended books

After I wrote the Dynamics CRM 2013 recommended books I realized people are still using the 2011 version, So I've decided to write also short list for Dynamics CRM 2011 book.
Most of these books I've actually read and dealt with.

Again in my point of you there is nothing like the SDK
http://msdn.microsoft.com/en-us/library/hh547453(v=crm.5).aspx

And now for the books:
Working with Microsoft Dynamics CRM 2011 (Developer Reference) 

Configure, adapt, and extend Microsoft Dynamics CRM 2011—guided by two of the leading implementation specialists in the field. Whether you’re an IT professional, a developer, or a power user, you’ll get pragmatic, hands-on insights for customizing CRM in your organization—with or without programming.



Microsoft Dynamics CRM 2011 Unleashed
One thing I have learned about CRM since I began using it is it has a million different features with a million different uses. It is a great program but only if you know how to use it. Microsoft Dynamics CRM 2011 Unleashed explains every detail of Dyanmics CRM 2011 in a way that is easy to understand. I keep this book at my desk in case there is a feature I would like to know more about or if I want to know if Dynamics CRM is capable of something. Great book for reference.

Microsoft Dynamics CRM 2011 Administration Bible
Once you purchase this book and it arrives you'll know why the title of this review says that this is the CRM 2011 book to own. This is not your 'average' CRM book. First, the book contains more than 700 pages of CRM vital information. It takes the reader from "Laying a Solid Foundation" through "Extending and Integrating". What's in between those two, nothing but pure CRM goodness; architecting the application, installing, managing data, Sales, Marketing & Service, working with Entities, Processes and more

Microsoft Dynamics CRM 2011 Application Design 
I thoroughly enjoyed reading the book. This is the only book in the market that talks about and teaches how to design solution using Microsoft Dynamics CRM 2011's various customization and extension features. This makes the book helpful to both readers who are new to CRM as well as experienced. There are total 8 chapters in the book in which readers will learn the basics of CRM 2011 and will also learn how to implement and create applications like Project Training Enrolment System, Employee Recruitment Management System, Hotel Management System etc. using CRM 2011. The readers will also get to learn how to create Silverlight applications, ASP.NET pages which integrates with CRM 2011.
A must read book for any serious CRM developer.


Good luck!

Saturday, January 19, 2013

Dynamics CRM 2011 Open dialog from Javascript

There are many nice things you could do withe dialogs, but making the user to go and choose a dialog from the ribbon isn't really good UI and it doesn't make lot of sense.

Example of when I used the code.
Let say you want to help the user go throw the process of closing case, wouldn't be goo idea to replace the resolve case ribbon button with new ribbon that will open a dialog?

In this example I'm using CrmRestKit, It is required for the code to work, Please make sure you add it to the form.

Javascript:


var DIALOG_NAME = "Test Dialog";

CrmRestKit.ByQuery('Workflow', ['WorkflowId'], "Category/Value eq 1 and StateCode/Value eq 1 and Type/Value eq 1 and Name eq '" + DIALOG_NAME + "'", false)
            .fail(function (t) {
            alert(t)
        })
            .done(function (data, status, xhr) {
            // Assert
            //equals(data.d.results.length, 2, 'Expected two');          
            if (data.d.results.length < 1) {
                alert("Missing dialog named: '"+DIALOG_NAME+"'");
                return;
            }
            var dialogId = data.d.results[0].WorkflowId;
            var objectId = Xrm.Page.data.entity.getId().replace("{", "%7b").replace("}", "%7d");
            var url = Xrm.Page.context.prependOrgName("/cs/dialog/rundialog.aspx?DialogId=%7b" + dialogId + "%7d&EntityName="+ Xrm.Page.data.entity.getEntityName() +"&ObjectId=" + objectId);
            var returnValue = showModalDialog(url);
        });

Sunday, January 6, 2013

Dynamics CRM 2011 - Javascript - Getting selected records from subgrid

Getting the selected values from subgrid in form is not supported, which makes it little bit more tricky.
Lets say you need to get selected records from subgrid after the user got out of the subgrid, like after onchange event of some form attribute. In this case the focus moves out of the subgrid and all you'll get would be an empty list.

The trick to get the selected records is: Get the focus back on the subgrid before trying to get the values.
Anyway it is not supported as well.

My Sample code:

var subgridName = "testSubGrid"

function GetSelectedRecords() {
    var stringOfSelectedIds = "No records were selected";
    if (Xrm.Page.getControl(subgridName) != null) {
        document.getElementById(subgridName).getElementsByTagName('a')[0].focus();
    }
    //document.getElementById(subgridName).control.get_selectedIds()
    if (document.getElementById(subgridName) != null && document.getElementById(subgridName).control != null) {
        selectedRecods = document.getElementById(subgridName).control.get_selectedIds();
        if (selectedRecods != null && selectedRecods.length > 0) {
            stringOfSelectedIds = "Selceted records: " + selectedRecods.join();
        }
        alert(stringOfSelectedIds);
    }
}

GetSelectedRecords()

Sunday, December 16, 2012

Dynamics CRM 2011 - Preventing close alert

Dynamics CRM 2011 - Preventing close alert


In Dynamics CRM 4.0 it was easy to disable close alert by using this one line of code before you close the window:
crmForm.detachCloseAlert();

In Dynamics CRM 2011, this method is depracated. The way i workaround it, is setting all dirty fields submit mode to never.
function IsAttributeDirty(attribute, index) {    return attribute.getIsDirty();}
function SetAllDirtyFieldsToNeverSubmit(){ var attributes = Xrm.Page.data.entity.attributes.get(IsAttributeDirty); for (var i in attributes) { attributes[i].setSubmitMode("never"); }}//ends function RemoveAllDirtyFields(){
Close window with out fields change message:
SetAllDirtyFieldsToNeverSubmit();
Xrm.Page.ui.close();

Sunday, December 9, 2012

Microsoft Dynamics CRM 2011 - Something about plugins SharedVariables

Microsoft Dynamics CRM 2011 - Something about plugins SharedVariables

My SharedVariables problem 
I had 2 plugins:
1) Pre Validation (code: 10)
2) Post Operation (code: 40)
After adding new value to SharedVariables in PreValidation, I've failed getting it in the PostOperation.

Solution:
I've found this article which explains the subject very well and helped me with my issue:
http://thomasthankachan.com/2011/08/12/pass-data-between-plug-ins-using-sharedvariables/

Summary:
PreValidation and PostOperation are running under different pipelines, and you should get SharedVariables from the parent context in PostOperation plugin and not it's own context.

MyCode:


bool isUpdate = true;
if(context.SharedVariables.Contains("SkipPlugin") && ((bool) context.SharedVariables["SkipPlugin"]))
{
  isUpdate = false;
} else if(context.ParentContext != null && context.ParentContext.SharedVariables.Contains("SkipPlugin") && ((bool) context.ParentContext.SharedVariables["SkipPlugin"])) {
  isUpdate = false;
}

Saturday, October 20, 2012

Dynamics CRM 2011 Form Script Analyzer

Dynamics CRM 2011 Form Script Analyzer

Few weeks ago i needed to get all the Javascript that is running in one of our customers Dynamics CRM 2011 Organization, I needed to get out all the Web Resource that are used, where are they used, what are the function that are running and on what are they running on (Onload, OnChange, OnSave, Ribbon buttons).
It was sisyphean work but after going over each Web Resource and their dependencies, I got the list out. This is what made me think, maybe I should build such a tool that takes it all out to an CSV file.

Yesterday, while surfing the web I've found the tool that does excetly that.

In TechEd New Zealand 2012 Gayan Perera presented a talk named:
Advanced Bag of Tips & Tricks for Microsoft Dynamics CRM 2011 Developers

I've enjoyed the presentation very much.
It was about:
T4 Code generation
MSCRM JS
Script#
How to convert managed solution to unmanaged solution
ILMerge
and Form Script Analyzer.

Back to the tool:
The Form Script Analyzer is Console Application tool that exports the Web resources and where their functions are called.

You can download it here : Download
For detailed description go to the TechEd Video and skip to 39 minutes (My recommention is to see the whole thing)

I haven't tried the tool yet, but it seems promising.

Friday, October 12, 2012

Dynamics CRM Interactive network visualization

A Jquery library to create interactive network visualization
http://flowingdata.com/2012/08/02/how-to-make-an-interactive-network-visualization/

If you have ideas of what to do with it in Dynamics CRM 2011, Please comment,  I'll see what i can do about it and I promise to post it in this blog.

Tuesday, October 2, 2012

How to change the customer / partner portal V2 to authenticate against the MSCRM only.


How to change the customer / partner portal V2 to authenticate against the MSCRM only.

There is a new portal and the changes are Little bit different than it was in the previous version
Customer portal V1 changes can be found here

Walkthrough:

In order to do it you'll need to download the portal and follow the installation steps, avoid all the stuff regarding the LiveID.
After you've imported the solution and the website data we are ready to go.
1)      Open the website in visual studio.
2)      Edit he web.config.
a.                 Remove
                a.1)
 <add name="Live" connectionString="Application Id=0000000000000000; Secret=00000000000000000000000000000000"/>

 a.2)
 <add key="FederationMetadataLocation" value="https://contoso.accesscontrol.windows.net/FederationMetadata/2007-06/FederationMetadata.xml"/>

                        a.3)
 <membership defaultProvider="CrmMembershipProvider">
                                        <providers>
                                                        <add name="CrmMembershipProvider" type="Microsoft.Xrm.Portal.Web.Security.LiveIdMembershipProvider, Microsoft.Xrm.Portal" liveIdConnectionStringName="Live"/>
                                        </providers>
                                        </membership>

                        a.4) 
<httpRuntime maxRequestLength="102400" requestValidationMode="2.0" requestValidationType="Microsoft.Xrm.Portal.IdentityModel.Web.FederationRequestValidator, Microsoft.Xrm.Portal"/>

                        a.5)
 <add name="LiveId" verb="*" path="LiveID.axd" preCondition="integratedMode" type="Microsoft.Xrm.Portal.IdentityModel.Web.Handlers.LiveIdAccountTransferHandler, Microsoft.Xrm.Portal"/>
                                        <add name="Federation" verb="*" path="Federation.axd" preCondition="integratedMode" type="Microsoft.Xrm.Portal.IdentityModel.Web.Handlers.FederationAuthenticationHandler, Microsoft.Xrm.Portal"/>


a.6) 
<microsoft.identityModel>
<service>
                                        <audienceUris>
                                                        <add value="http://contoso.cloudapp.net/"/>
                                        </audienceUris>
                                        <federatedAuthentication>
                                                        <wsFederation passiveRedirectEnabled="false" issuer="https://contoso.accesscontrol.windows.net/v2/wsfederation" realm="http://contoso.cloudapp.net/" requireHttps="false"/>
                                                        <cookieHandler requireSsl="false"/>
                                        </federatedAuthentication>
                                        <issuerNameRegistry type="Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
                                                        <trustedIssuers>
                                                                        <add thumbprint="0000000000000000000000000000000000000000" name="https://contoso.accesscontrol.windows.net/"/>
                                                        </trustedIssuers>
                                        </issuerNameRegistry>
                        </service>
        </microsoft.identityModel>
        <microsoft.xrm.portal.identityModel>
                        <registration enabled="true" registrationPath="~/confirm-invite" profilePath="~/profile" accountTransferPath="~/login" requiresInvitation="true"
                                        requiresChallengeAnswer="false" requiresConfirmation="false" invitationCodeDuration="01:00:00"/>
        </microsoft.xrm.portal.identityModel>

b.         Replace the Authentication tag to as follow
<authentication mode="Forms">
<forms loginUrl="/login" timeout="525600"     defaultUrl="/"  />
 </authentication>

3)      Edit \Pages\Login.aspx
a.         Remove                
a.1)
<%@ Register TagPrefix="adx" TagName="AzureAcs" Src="~/Controls/AzureAcs.ascx" %>

a.2)
<adx:AzureAcs runat="server" />

a.3)
<crm:Snippet runat="server" SnippetName="Login/ACS/AccountTransfer/Heading" DefaultText="Live ID Account Transfer" />

a.4)
<p>Already registered with a Windows Live ID account? Sign in to transfer the account to an AppFabric ACS account:</p>

b.         Replace
<crm:LiveIdLoginStatus ID="TransferLiveIdLink" runat="server" LoginImageUrl="https://www.passportimages.com/1033/signin.gif"
LogoutImageUrl="https://www.passportimages.com/1033/signout.gif" />
With
  <asp:Login ID="Login1" runat="server" OnAuthenticate="Login1_Authenticate"></asp:Login>

5)   Edit \Pages\Login.aspx.cs
a.                Add to using
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Crm.Sdk;
using Microsoft.Xrm.Client.Services;
using Microsoft.Xrm.Client;
using Xrm;
using System.Web.Security;

b.                Replace Page_Load
protected void Page_Load(object sender, EventArgs e)
        {
            if ((User != null) && User.Identity.IsAuthenticated)
            {
                var redirectUrl = !string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]) ? Request["ReturnUrl"]: !string.IsNullOrEmpty(Request.QueryString["URL"])? Request["URL"]: "/";
                Response.Redirect(redirectUrl);
            }
        }
c.                 Add
        private Contact _loginContact;

        protected Contact LoginContact
        {
            get
            {
                return _loginContact ?? (_loginContact = XrmContext.ContactSet.FirstOrDefault(c => c.Adx_username == Login1.UserName && c.Adx_LogonEnabled != null && c.Adx_LogonEnabled.Value));
            }
        }

        protected void Login1_Authenticate(object sender, System.Web.UI.WebControls.AuthenticateEventArgs e)
        {
            if (LoginContact == null)
            {
                e.Authenticated = false;
            }
            else
            {
                if (LoginContact.Adx_password == Login1.Password)
                {
                if (LoginContact.Adx_changepasswordatnextlogon != null && LoginContact.Adx_changepasswordatnextlogon.Value)
                    {
                        //var page = ServiceContext.GetPageBySiteMarkerName(Website, "ChangePassword");
                        //string redirectURL = ServiceContext.GetUrl(page) + "?UserName=" + Server.UrlEncode(Login1.UserName) + "&Password=" + Server.UrlEncode(Login1.Password);
                        //Response.Redirect(redirectURL);
                    }
                    else
                    {
                        LoginContact.Adx_LastSuccessfulLogon = DateTime.Now.Date;
                        XrmContext.UpdateObject(LoginContact);
                        XrmContext.SaveChanges();
                        e.Authenticated = true;
                        // Response.Redirect("/");
                        FormsAuthentication.RedirectFromLoginPage(Login1.UserName, true);
                    }
                }
                else
                {
                    e.Authenticated = false;
                }
            }
        }

Compile, Debug and Publish to the IIS.

Download changed portal: