12/21/13

ASP.Net Show Assembly Build Date

When creating an about page for a web application, we often add the build date information. To get the build date, we can query the executing assembly file and get the last write time property.

/// <summary>
/// returns the file write date
/// </summary>
/// <returns></returns>
private static string GetAssemblyDate()
{
string date = string.Empty;
try
{
var assembly = Assembly.GetExecutingAssembly();
var fileInfo = new FileInfo(assembly.Location);
var writeTime = fileInfo.LastWriteTime;
date = String.Format("{0} {1}", writeTime.ToShortDateString(), writeTime.ToShortTimeString());
}catch(Exception ex)
{
//log exception info
}
return date;
}

This helper method reads the file properties of the assembly and returns the date and time information. This is the same date-time information that we would find when using Windows Explorer.  The date time information return by this method has this format:

                MM/DD/YYYY hh:mm am/pm


I hope this helps some of you.

12/14/13

MSCRM Adding Notes With JavaScript

In Dynamics CRM, users can add notes to make comments about certain changes that were made to a record. In some instances, there may be a requirement to automate the creation of notes based on certain field information changes.  

The challenge with notes is that it is not a field on the entity. It is actually a 1:N association which is displayed on the form with an embedded IFRAME. This means that we can’t just populate a field, but instead, we need to call the REST web services on dynamics to request the creation of the note.
To handle this, we can create a simple JavaScript object that handles the web service call (NoteManager) and another object to the handle the test of the creation of the notes (TestNotes):

NoteManager Script:

if (typeof (OGBIT) == "undefined") { OGBIT = {}; }
OGBIT.NoteManager = {
    AddNote: function (params, entitySet, onComplete, onError) {
        var self = OGBIT.NoteManager;
        var serverUrl = self.GetServerUrl();
        var ODataURL = serverUrl + entitySet;
        var json = JSON.stringify(params);      //MUST CONVERT TO JSON STRING

        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            datatype: "json",
            url: ODataURL,
            data: json,
            beforeSend: function (XMLHttpRequest) {
                XMLHttpRequest.setRequestHeader("Accept", "application/json");
            },
            success: function (data, textStatus, XmlHttpRequest) {
                if (onComplete != null)
                    onComplete(data.d.results);
            },
            error: function (XmlHttpRequest, textStatus, errorObject) {
                var msg = textStatus;
                try {
                    msg = JSON.parse(XMLHttpRequest.responseText).error.message.value;
                } catch (e) { }

                if (onError != null)
                    onError(msg);
            }
        });
    },
    GetServerUrl: function () {
        var serverUrl = '';
        if (typeof (Xrm) != 'undefined' && Xrm != null) {
            serverUrl = Xrm.Page.context.getServerUrl();
            //test that server name is not coming back instead of the domain name
            //otherwise we get a Cross-Origen (CORS) 400 error           
        }
        if (serverUrl.match(/\/$/)) {
            serverUrl = serverUrl.substring(0, serverUrl.length - 1);
        }

        return serverUrl + "/XRMServices/2011/OrganizationData.svc/";
    },

}
The above script implements two main methods:

Method Name
Description
AddNote
This method handles the interaction with the Dynamics CRM web service. It takes the following parameters:

Name
Description
Params
JSON structure that contains the note information
entitySet
This is the name of the entity where the record needs to be added. For notes, the name is AnotationSet
onComplete
This is a callback handler
onError
This is a callback handler for errors

Note the following attributes on the request:

The Dynamic CRM web services are RESTFul. For the creation of a new note, we to set the verb to POST.

Since we pass a JSON structure we set the content and data types to JSON

The data parameter contains the JSON data in string format which is generated after calling the stringify function

GetServerUrl
This method resolves the server URL and current organization name.

TestNotes Script:

OGBIT.TestNotes = {
   AddNotes: function () {
      var self = OGBIT.TestNotes;
      var note = {};
      var ref = {};
      note.NoteText = "This is the content of the notes";
      note.Subject = "Note Unit test";
      ref.LogicalName = Xrm.Page.data.entity.getEntityName();//returns the entity name
      ref.Id = Xrm.Page.data.entity.getId();             //returns the primary id/guid
      note.ObjectId = ref;                              //associate the note to an entity
     OGBIT.NoteManager.AddNote(note, 'AnnotationSet', self.onComplete, self.onError); //AnnotationSet is the notes entity set 
    },
    onError: function (msg) {
        alert(msg)
    },
    onComplete: function (data) {
        alert(data);
    }
}

The above script creates the following JSON structures:

Name
Description
Note
This is the note object notation. It is created with the following attributes:

Name
Description
NoteText
This is the content for the note
Subject
This is the subject
ObjectId
This is the object associated to the notes. I.E. A note can be associated to an account or other custom entity that support notes.


ref
This is the associated object. It needs the following attributes:

Name
Description
LogicalName
This is the name of the entity
Id
This is the primary id (GUID)

These values can be fetched by using the Xrm client object model. It uses the current context to retrieve the entity information.


After creating the JSON references, the script uses the NoteManager method to post the request to the web services. The callback handlers are called after the web service call has completed. 



I hope these scripts can help you get more understanding of the Dynamics CRM web services and how to interact with them via JavaScript.

11/30/13

WCF Web Service Get Assembly Version

This is a simple snippet to show a simple way to display the current assembly version of a WCF Web Service.  We first need a helper class with a method that looks as follows: (class is excluded for brevity)

public static string GetVersion()
        {
            string version = string.Empty;
            var assembly = System.Reflection.Assembly.GetExecutingAssembly();
            if (assembly != null)
            {
                  version = assembly.GetName().Version.ToString();
            }

            return version;
        }

We now need to add a Web method to our web service that we can call to return the version number. I often like to add a Ping or Version web method to the web services to test basic client connectivity. The method just needs to call the helper class and return the string with the version information as follows:

public String Ping()
        {
            string version = RequestHelper.GetVersion();
            return version;
        }

When testing this web service, you can call this method to verify what current version is deployed.

I hope you find this helpful.


10/26/13

Editable HTML Elements with ContentEditable Attribute

With HTML, we often implement the editable contents with a TextArea, Text and RichText editor controls.  With HTML5, we can use the ContentEditable attribute on any content element to allow users to edit and change the content.

For example, when we use the following HTML page:

<!DOCTYPE html>
<html><head></head>
<body>
<header id="headercontent" contenteditable="true">
    My header
</header>

<div id="MainContent" contenteditable="true">
    main content
</div>

<footer id="footercontent" contenteditable="true">
    my footer
</footer>

</body></html>

We can see that the main body elements like header, main content and footer are set with an additional attribute. When the contenteditable attribute is set to true, the browsers that support HTML5 allows the users to click on the content and type text changes. This feature allows us to quickly create HTML content editors without having to resort to JavaScript plugins or text area controls.

We should note that the main purpose of this attribute is to allow users to update the content, but it does not allow the user to format the contents with text effects.  For that type of functionality we would need to add a plugin that can support rich text capabilities.

9/19/13

Office 365 Change Password Expiration Days

Office 365 passwords expires by default every 90 days.  If this setting is too short, you can modify the number of days from the Office 365 Administration screen which can be accessed by following these steps:
  1. On the header/top menu, click on Admin
  2. On the Left navigation menu, click on service settings
  3. On the content top menu, click on passwords
  4. Enter the number of days next to the Days before password expire text box.
This is an image of how this should look on the new Office 365 with SharePoint 2013.

Office 365 - Password Expiration Days

























We can also note that the notification settings can be updated from this view. By default, it is set to 14 days.  This means that 14 days prior to a password expiring, the user gets a notification indicating that the password is about to expire. 

8/25/13

Dynamics CRM How to Access Page Controls with JavaScript

When working with Dynamic CRM custom solutions, I often have to implement some UI control behaviors with JavaScript.  The table below shows some of the common tasks that can be done when using the XRM JavaScript framework that comes with the Dynamics platform.

Task
XRM JavaScript Framework API
Show or Hide a control
setVisible(cmd)

cmd bool  value:  
true  to show
false to hide

Disable or enable a control
setDisabled(cmd)

cmd bool  value:
true = to disable
false to enable
Focus
setFocus()

This table shows the steps to access a control and set several properties:

Tasks
Script
Get a control reference
var control = Xrm.Page.getControl(name.toLowerCase());

Note:  Controls on the web form are set with lowercase letters.

Disable a control
control.setDisabled(true);

Enable a control
control.setDisabled(false);

Show a control
control.setVisible(true);

Hide a control
control.setVisible(false);

Set the focus
control.setFocus();



I hope you enjoy this quick reference.