Monday, May 2, 2011

How to: Create a Custom Entity Using Jscript or .NET Using the Microsoft Dynamics CRM 2011 SDK

Here is a quick demo on how to utilize the CreateEntity message of the CRM 2011 Organization service in both C# and Jscript.   This illustration shows you how to create a custom entity using SOAP (JScript) or C# (.NET) with the CreateEntity message.
First in C#:

 IOrganizationService service = (IOrganizationService)_serviceProxy;

         CreateEntityRequest createrequest = new CreateEntityRequest
         {

             //Define the entity
             Entity = new EntityMetadata
             {
                 SchemaName = "new_customrobot2",
                 DisplayName = new Label("Custom Robot2 ", 1033),
                 DisplayCollectionName = new Label("Custom Robots2", 1033),
                 Description = new Label("An entity to store information about custom robots", 1033),
                 OwnershipType = OwnershipTypes.UserOwned,
                 IsActivity = false,

             },

             // Define the primary attribute for the entity
             PrimaryAttribute = new StringAttributeMetadata
             {
                 SchemaName = "new_robotname",
                 RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None),
                 MaxLength = 100,
                 Format = StringFormat.Text,
                 DisplayName = new Label("Robot Name", 1033),
                 Description = new Label("The primary attribute for the custom robot entity.", 1033)
             },



         };
         service.Execute(createrequest);


Now here is the Jscript nicely formatted by the CRM 2011 SOAP formatter. Available at: http://crm2011soap.codeplex.com/

Now in Jscript:

if (typeof (SDK) == "undefined")
   { SDK = { __namespace: true }; }
       //This will establish a more unique namespace for functions in this library. This will reduce the 
       // potential for functions to be overwritten due to a duplicate name when the library is loaded.
       SDK.SAMPLES = {
           _getServerUrl: function () {
               ///<summary>
               /// Returns the URL for the SOAP endpoint using the context information available in the form
               /// or HTML Web resource.
               ///</summary>
               var OrgServicePath = "/XRMServices/2011/Organization.svc/web";
               var serverUrl = "";
               if (typeof GetGlobalContext == "function") {
                   var context = GetGlobalContext();
                   serverUrl = context.getServerUrl();
               }
               else {
                   if (typeof Xrm.Page.context == "object") {
                         serverUrl = Xrm.Page.context.getServerUrl();
                   }
                   else
                   { throw new Error("Unable to access the server URL"); }
                   }
                  if (serverUrl.match(/\/$/)) {
                       serverUrl = serverUrl.substring(0, serverUrl.length - 1);
                   } 
                   return serverUrl + OrgServicePath;
               }, 
           CreateEntityRequest: function () {
               var requestMain = ""
               requestMain += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
               requestMain += "  <s:Body>";
               requestMain += "    <Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
               requestMain += "      <request i:type=\"a:CreateEntityRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
               requestMain += "        <a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <b:key>Entity</b:key>";
               requestMain += "            <b:value i:type=\"c:EntityMetadata\" xmlns:c=\"http://schemas.microsoft.com/xrm/2011/Metadata\">";
               requestMain += "              <c:MetadataId i:nil=\"true\" />";
               requestMain += "              <c:ActivityTypeMask i:nil=\"true\" />";
               requestMain += "              <c:Attributes i:nil=\"true\" />";
               requestMain += "              <c:AutoRouteToOwnerQueue i:nil=\"true\" />";
               requestMain += "              <c:CanBeInManyToMany i:nil=\"true\" />";
               requestMain += "              <c:CanBePrimaryEntityInRelationship i:nil=\"true\" />";
               requestMain += "              <c:CanBeRelatedEntityInRelationship i:nil=\"true\" />";
               requestMain += "              <c:CanCreateAttributes i:nil=\"true\" />";
               requestMain += "              <c:CanCreateCharts i:nil=\"true\" />";
               requestMain += "              <c:CanCreateForms i:nil=\"true\" />";
               requestMain += "              <c:CanCreateViews i:nil=\"true\" />";
               requestMain += "              <c:CanModifyAdditionalSettings i:nil=\"true\" />";
               requestMain += "              <c:CanTriggerWorkflow i:nil=\"true\" />";
               requestMain += "              <c:Description>";
               requestMain += "                <a:LocalizedLabels>";
               requestMain += "                  <a:LocalizedLabel>";
               requestMain += "                    <a:IsManaged i:nil=\"true\" />";
               requestMain += "                    <a:Label>An entity to store information about custom robots</a:Label>";
               requestMain += "                    <a:LanguageCode>1033</a:LanguageCode>";
               requestMain += "                  </a:LocalizedLabel>";
               requestMain += "                </a:LocalizedLabels>";
               requestMain += "                <a:UserLocalizedLabel i:nil=\"true\" />";
               requestMain += "              </c:Description>";
               requestMain += "              <c:DisplayCollectionName>";
               requestMain += "                <a:LocalizedLabels>";
               requestMain += "                  <a:LocalizedLabel>";
               requestMain += "                    <a:IsManaged i:nil=\"true\" />";
               requestMain += "                    <a:Label>Custom Robots3</a:Label>";
               requestMain += "                    <a:LanguageCode>1033</a:LanguageCode>";
               requestMain += "                  </a:LocalizedLabel>";
               requestMain += "                </a:LocalizedLabels>";
               requestMain += "                <a:UserLocalizedLabel i:nil=\"true\" />";
               requestMain += "              </c:DisplayCollectionName>";
               requestMain += "              <c:DisplayName>";
               requestMain += "                <a:LocalizedLabels>";
               requestMain += "                  <a:LocalizedLabel>";
               requestMain += "                    <a:IsManaged i:nil=\"true\" />";
               requestMain += "                    <a:Label>Custom Robot3 </a:Label>";
               requestMain += "                    <a:LanguageCode>1033</a:LanguageCode>";
               requestMain += "                  </a:LocalizedLabel>";
               requestMain += "                </a:LocalizedLabels>";
               requestMain += "                <a:UserLocalizedLabel i:nil=\"true\" />";
               requestMain += "              </c:DisplayName>";
               requestMain += "              <c:IconLargeName i:nil=\"true\" />";
               requestMain += "              <c:IconMediumName i:nil=\"true\" />";
               requestMain += "              <c:IconSmallName i:nil=\"true\" />";
               requestMain += "              <c:IsActivity>false</c:IsActivity>";
               requestMain += "              <c:IsActivityParty i:nil=\"true\" />";
               requestMain += "              <c:IsAuditEnabled i:nil=\"true\" />";
               requestMain += "              <c:IsAvailableOffline i:nil=\"true\" />";
               requestMain += "              <c:IsChildEntity i:nil=\"true\" />";
               requestMain += "              <c:IsConnectionsEnabled i:nil=\"true\" />";
               requestMain += "              <c:IsCustomEntity i:nil=\"true\" />";
               requestMain += "              <c:IsCustomizable i:nil=\"true\" />";
               requestMain += "              <c:IsDocumentManagementEnabled i:nil=\"true\" />";
               requestMain += "              <c:IsDuplicateDetectionEnabled i:nil=\"true\" />";
               requestMain += "              <c:IsEnabledForCharts i:nil=\"true\" />";
               requestMain += "              <c:IsImportable i:nil=\"true\" />";
               requestMain += "              <c:IsIntersect i:nil=\"true\" />";
               requestMain += "              <c:IsMailMergeEnabled i:nil=\"true\" />";
               requestMain += "              <c:IsManaged i:nil=\"true\" />";
               requestMain += "              <c:IsMappable i:nil=\"true\" />";
               requestMain += "              <c:IsReadingPaneEnabled i:nil=\"true\" />";
               requestMain += "              <c:IsRenameable i:nil=\"true\" />";
               requestMain += "              <c:IsValidForAdvancedFind i:nil=\"true\" />";
               requestMain += "              <c:IsValidForQueue i:nil=\"true\" />";
               requestMain += "              <c:IsVisibleInMobile i:nil=\"true\" />";
               requestMain += "              <c:LogicalName i:nil=\"true\" />";
               requestMain += "              <c:ManyToManyRelationships i:nil=\"true\" />";
               requestMain += "              <c:ManyToOneRelationships i:nil=\"true\" />";
               requestMain += "              <c:ObjectTypeCode i:nil=\"true\" />";
               requestMain += "              <c:OneToManyRelationships i:nil=\"true\" />";
               requestMain += "              <c:OwnershipType>UserOwned</c:OwnershipType>";
               requestMain += "              <c:PrimaryIdAttribute i:nil=\"true\" />";
               requestMain += "              <c:PrimaryNameAttribute i:nil=\"true\" />";
               requestMain += "              <c:Privileges i:nil=\"true\" />";
               requestMain += "              <c:RecurrenceBaseEntityLogicalName i:nil=\"true\" />";
               requestMain += "              <c:ReportViewName i:nil=\"true\" />";
               requestMain += "              <c:SchemaName>new_customrobot3</c:SchemaName>";
               requestMain += "            </b:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <b:key>HasActivities</b:key>";
               requestMain += "            <b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">false</b:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <b:key>HasNotes</b:key>";
               requestMain += "            <b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">false</b:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "          <a:KeyValuePairOfstringanyType>";
               requestMain += "            <b:key>PrimaryAttribute</b:key>";
               requestMain += "            <b:value i:type=\"c:StringAttributeMetadata\" xmlns:c=\"http://schemas.microsoft.com/xrm/2011/Metadata\">";
               requestMain += "              <c:MetadataId i:nil=\"true\" />";
               requestMain += "              <c:AttributeOf i:nil=\"true\" />";
               requestMain += "              <c:AttributeType>String</c:AttributeType>";
               requestMain += "              <c:CanBeSecuredForCreate i:nil=\"true\" />";
               requestMain += "              <c:CanBeSecuredForRead i:nil=\"true\" />";
               requestMain += "              <c:CanBeSecuredForUpdate i:nil=\"true\" />";
               requestMain += "              <c:CanModifyAdditionalSettings i:nil=\"true\" />";
               requestMain += "              <c:ColumnNumber i:nil=\"true\" />";
               requestMain += "              <c:DeprecatedVersion i:nil=\"true\" />";
               requestMain += "              <c:Description>";
               requestMain += "                <a:LocalizedLabels>";
               requestMain += "                  <a:LocalizedLabel>";
               requestMain += "                    <a:IsManaged i:nil=\"true\" />";
               requestMain += "                    <a:Label>The primary attribute for the custom robot entity.</a:Label>";
               requestMain += "                    <a:LanguageCode>1033</a:LanguageCode>";
               requestMain += "                  </a:LocalizedLabel>";
               requestMain += "                </a:LocalizedLabels>";
               requestMain += "                <a:UserLocalizedLabel i:nil=\"true\" />";
               requestMain += "              </c:Description>";
               requestMain += "              <c:DisplayName>";
               requestMain += "                <a:LocalizedLabels>";
               requestMain += "                  <a:LocalizedLabel>";
               requestMain += "                    <a:IsManaged i:nil=\"true\" />";
               requestMain += "                    <a:Label>Robot Name</a:Label>";
               requestMain += "                    <a:LanguageCode>1033</a:LanguageCode>";
               requestMain += "                  </a:LocalizedLabel>";
               requestMain += "                </a:LocalizedLabels>";
               requestMain += "                <a:UserLocalizedLabel i:nil=\"true\" />";
               requestMain += "              </c:DisplayName>";
               requestMain += "              <c:EntityLogicalName i:nil=\"true\" />";
               requestMain += "              <c:IsAuditEnabled i:nil=\"true\" />";
               requestMain += "              <c:IsCustomAttribute i:nil=\"true\" />";
               requestMain += "              <c:IsCustomizable i:nil=\"true\" />";
               requestMain += "              <c:IsManaged i:nil=\"true\" />";
               requestMain += "              <c:IsPrimaryId i:nil=\"true\" />";
               requestMain += "              <c:IsPrimaryName i:nil=\"true\" />";
               requestMain += "              <c:IsRenameable i:nil=\"true\" />";
               requestMain += "              <c:IsSecured i:nil=\"true\" />";
               requestMain += "              <c:IsValidForAdvancedFind i:nil=\"true\" />";
               requestMain += "              <c:IsValidForCreate i:nil=\"true\" />";
               requestMain += "              <c:IsValidForRead i:nil=\"true\" />";
               requestMain += "              <c:IsValidForUpdate i:nil=\"true\" />";
               requestMain += "              <c:LinkedAttributeId i:nil=\"true\" />";
               requestMain += "              <c:LogicalName i:nil=\"true\" />";
               requestMain += "              <c:RequiredLevel>";
               requestMain += "                <a:CanBeChanged>true</a:CanBeChanged>";
               requestMain += "                <a:ManagedPropertyLogicalName i:nil=\"true\" />";
               requestMain += "                <a:Value>None</a:Value>";
               requestMain += "              </c:RequiredLevel>";
               requestMain += "              <c:SchemaName>new_robotname</c:SchemaName>";
               requestMain += "              <c:Format>Text</c:Format>";
               requestMain += "              <c:ImeMode i:nil=\"true\" />";
               requestMain += "              <c:MaxLength>100</c:MaxLength>";
               requestMain += "              <c:YomiOf i:nil=\"true\" />";
               requestMain += "            </b:value>";
               requestMain += "          </a:KeyValuePairOfstringanyType>";
               requestMain += "        </a:Parameters>";
               requestMain += "        <a:RequestId i:nil=\"true\" />";
               requestMain += "        <a:RequestName>CreateEntity</a:RequestName>";
               requestMain += "      </request>";
               requestMain += "    </Execute>";
               requestMain += "  </s:Body>";
               requestMain += "</s:Envelope>";
               var req = new XMLHttpRequest();
               req.open("POST", SDK.SAMPLES._getServerUrl(), true)
               // Responses will return XML. It isn't possible to return JSON.
               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");
               var successCallback = null;
               var errorCallback = null;
               req.onreadystatechange = function () { SDK.SAMPLES.CreateEntityResponse(req, successCallback, errorCallback); };
               req.send(requestMain);
           },
       CreateEntityResponse: function (req, successCallback, errorCallback) {
               ///<summary>
               /// Recieves the assign response
               ///</summary>
               ///<param name="req" Type="XMLHttpRequest">
               /// The XMLHttpRequest response
               ///</param>
               ///<param name="successCallback" Type="Function">
               /// The function to perform when an successfult response is returned.
               /// For this message no data is returned so a success callback is not really necessary.
               ///</param>
               ///<param name="errorCallback" Type="Function">
               /// The function to perform when an error is returned.
               /// This function accepts a JScript error returned by the _getError function
               ///</param>
               if (req.readyState == 4) {
               if (req.status == 200) {
               if (successCallback != null)
               { successCallback(); }
               }
               else {
                   errorCallback(SDK.SAMPLES._getError(req.responseXML));
               }
           }
       },
       _getError: function (faultXml) {
           ///<summary>
           /// Parses the WCF fault returned in the event of an error.
           ///</summary>
           ///<param name="faultXml" Type="XML">
           /// The responseXML property of the XMLHttpRequest response.
           ///</param>
           var errorMessage = "Unknown Error (Unable to parse the fault)";
           if (typeof faultXml == "object") {
               try {
                   var bodyNode = faultXml.firstChild.firstChild;
                   //Retrieve the fault node
                   for (var i = 0; i < bodyNode.childNodes.length; i++) {
                       var node = bodyNode.childNodes[i];
                       //NOTE: This comparison does not handle the case where the XML namespace changes
                       if ("s:Fault" == node.nodeName) {
                       for (var j = 0; j < node.childNodes.length; j++) {
                           var faultStringNode = node.childNodes[j];
                           if ("faultstring" == faultStringNode.nodeName) {
                               errorMessage = faultStringNode.text;
                               break;
                           }
                       }
                       break;
                   }
               }
           }
           catch (e) { };
        }
        return new Error(errorMessage);
     },
 __namespace: true
};




To understand how to parse the response please review my post on using the DOM parser.
Now you can call the SDK.SAMPLES.CreateEntityRequest function from your form jscript handler.
Thats all there is to it!

You may also want to publish your custom entity after creation so you may want to read my article on publishing an entity from jscript.
http://mileyja.blogspot.com/2011/03/publish-entity-in-jscript-in-crm-2011.html


I hope this helps!

1 comment:

  1. hi
    can you send me the solution in visual studio for this example please i'm new in crm and i tried to develop an aplication

    ReplyDelete