Showing posts with label create. Show all posts
Showing posts with label create. Show all posts

June 18, 2015

Hide fields dynamically based on Field Level Security privileges

When we set up Field Level Security for a field we can assign three different privileges (Read, Update, Write) to the users.
It is also possible to check the privilege using a supported JavaScript method: getUserPrivilege
This method returns an object with three boolean properties: canRead, canUpdate, canCreate.

We can use these properties in combination with the forEach method of attributes and controls collections in order to dynamically hide the fields.

The following code will hide dynamically all the fields protected by Field Level Security that the user can't read:
function HideSecuredFields() {
    // fetch all attributes on the form
    Xrm.Page.data.entity.attributes.forEach(
        function(attribute, aIndex) {
            // get the FLS privileges
            var privileges = attribute.getUserPrivilege();
            // check if the user can't read the field
            if (privileges.canRead == false) {
                // fetch all the controls related to the attribute
                attribute.controls.forEach(
                    function (control, cIndex) {
                       // hide the controls
                       control.setVisible(false);
                    }
                );
            }
        }
    );
}

January 20, 2015

Get the Id of records created using Early Bound OrganizationServiceContext

The other day my friend Raj (@RajYRaman) retweeted a post from Dynamics CRM PFE Team about the best practice to let CRM to choose the Guid of new records instead of using Guid.NewGuid():

http://blogs.msdn.com/b/crminthefield/archive/2015/01/19/the-dangers-of-guid-newguid.aspx

With IOrganizationService object is very easy to get the Id of the new record, because it's the value returned by the Create method independently if late bound or early bound is used:
IOrganizationService service = new OrganizationService(crmConnection);

// late bound
Entity lateAccount = new Entity("account");
lateAccount["name"] = "Late Bound Account";
Guid lateAccountId = service.Create(lateAccount);

// early bound
Account earlyAccount = new Account();
earlyAccount.Name = "Early Bound Account";
Guid earlyAccountId = service.Create(earlyAccount);
This works because Early Bound classes inherit from the Entity class.
public partial class Account : Microsoft.Xrm.Sdk.Entity ...
But how we can get the Id of the records when we use the OrganizationServiceContext in combination with the AddObject and SaveChanges methods?
Using Guid.NewGuid() in order to specify the Id before creating the record was one of my mistakes when I first used Early Bound classes. My badly written code was:
IOrganizationService service = new OrganizationService(crmConnection);
XrmContext context = new XrmContext(service);

// WORST CODE EVER, DON'T DO THIS!
Account earlyAccount = new Account();
Guid badGeneratedId = Guid.NewGuid();
earlyAccount.Id = badGeneratedId;
earlyAccount.Name = "Early Bound Account";
context.AddObject(earlyAccount);
context.SaveChanges();
The reason was to avoid parsing the results of the SaveChanges method in order to get the Id. SaveChanges doesn't return void but a SaveChangesResultCollection object with the details of the save operation.

But checking the results is not necessary, in fact the OrganizationServiceContext updates the tracked records adding the Guid value to the Id property. We just need to read the Id property after the SaveChanges:
Account earlyAccount = new Account();
earlyAccount.Name = "Early Bound Account";
context.AddObject(earlyAccount);
context.SaveChanges();

Guid crmGeneratedId = earlyAccount.Id; 
MSDN Documentation (at least at the time I discover this) isn't so clear explaining this behavior, hope it helps!