Setting custom fields via SOAP - The Better Way

After a fairly significant rant about the difficulties that go into setting a custom field or attribute on a base object
(Setting custom fields via SOAP) I figured it's past due to come up with a reusable solution.

I've created two extension methods for the base RNObject class: GetCustomField(string fieldName) and SetCustomField(string fieldName, object value, DataTypeEnum typeEnum).

Usage is dead simple:

  • Set a custom field: soapObject.SetCustomField("c$stringField", "string value", DataTypeEnum.STRING);
  • Get a custom field: string value = (string)soapObject.GetCustomField("c$stringField");
  • Set a custom attribute: soapObject.SetCustomField("CO$intAttr", 10, DataTypeEnum.INTEGER);
  • Get a custom attribute: int intAttrResult = (int)(soapObject.GetCustomField("CO$intAttr") ?? 0);

Getting it set up is also pretty straight forward:

  1. Get the source: https://gist.github.com/proteux/8501c8e259f9bfdadfff or https://bitbucket.org/45north/cx-developer-tutorials/src
  2. Add the class to your project and add a service reference for your CX site if one doesn't already exist
  3. Update the using line in the class to that of your SOAP namespace (using EasyCustomFields.RightNow.Soap;)
  4. Add using EasyCustomFields; to the top of whichever class needs to get or set a custom field
  5. Now there should be two additional methods for any RNObject instances you have in your class: SetCustomField() and GetCustomField()

Note: When setting a custom attribute that is a NamedID you can either pass in a NamedID object or an int, long or string and the library will create the NamedID object for you.

Full source is available on Bitbucket under / Libraries / EasyCustomFIelds /

Categories : 

Comments

Jack

Thanks for your reusable code, it's easy to use. But I'm a little confused about field type name. It seems as the API does not care about this field type name. The reason why I say that is there is no exception when we set fieldTypeName to "ContactCustomFieldsc" or "ContactCustomFieldsCO" for the "CO$age". Please see my comments about fieldTypeName in code blocks.


//assume fieldName is "CO$age", root is a Contact object
public static void SetCustomField(this RNObject root, string fieldName, object value, DataTypeEnum typeEnum)
{
ItemsChoiceType choiceEnum = GetChoiceByType(typeEnum);

Type type = root.GetType();
GenericObject customFields;
PropertyInfo cf_prop;

//break out the field name
string packageName = "c";
if (fieldName.Contains('$'))
{
string[] parts = fieldName.Split('$');
packageName = parts[0];
fieldName = parts[1];
}

//create the layer names
string objectTypeName = type.Name; //Contact
string fieldTypeName = objectTypeName + "CustomFieldsc"; //it's "ContactCustomFieldsc", but it should be "ContactCustomFieldsCO"
string fieldArrayTypeName = objectTypeName + "CustomFields"; //ContactCustomFields
}

Is it better to use "ContactCustomFieldsCO" in this case? Because I have debuged the 'get' method for a contact, it's "ContactCustomFieldsCO"

hi Jack,

Could you please share how to create a object with custom filed value in SOAP XML in Batching. I tried the SOAP XML given RN documentation but its not working for me. Here is the code which i used could pls say me wat mistake i have done or any other fields to be added to make it work
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v1="urn:messages.ws.rightnow.com/v1_3" xmlns:v11="urn:base.ws.rightnow.com/v1_3" xmlns:v12="urn:generic.ws.rightnow.com/v1_3">
<soapenv:Header>
<v1:ClientInfoHeader>
<v1:AppID>test</v1:AppID>
</v1:ClientInfoHeader>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-4" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>***</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">***</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ns7:Batch xmlns:ns7="urn:messages.ws.rightnow.com/v1_3">
<ns7:BatchRequestItem>
<ns7:CreateMsg>
<ns7:RNObjects xmlns:ns2="urn:generic.ws.rightnow.com/v1_3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:GenericObject">
<ID xmlns="urn:base.ws.rightnow.com/v1_3" xsi:type="ChainSourceID" id="0" variableName="NewOrganization" />
<ns2:ObjectType>
<ns2:TypeName>Organization</ns2:TypeName>
</ns2:ObjectType>
<ns2:GenericFields dataType="STRING" name="Login">
<ns2:DataValue xsi:nil="1" />
</ns2:GenericFields>
<ns2:GenericFields dataType="STRING" name="Name">
<ns2:DataValue>
<ns2:StringValue>Name</ns2:StringValue>
</ns2:DataValue>
</ns2:GenericFields>
<ns2:GenericFields dataType="INTEGER" name="NumberOfEmployees">
<ns2:DataValue>
<ns2:IntegerValue>100</ns2:IntegerValue>
</ns2:DataValue>
</ns2:GenericFields>
</ns7:RNObjects>
<ns7:ProcessingOptions>
<ns7:SuppressExternalEvents>false</ns7:SuppressExternalEvents>
<ns7:SuppressRules>false</ns7:SuppressRules>
</ns7:ProcessingOptions>
</ns7:CreateMsg>
</ns7:BatchRequestItem>
<ns7:BatchRequestItem>
<ns7:CreateMsg>
<ns7:RNObjects xmlns:ns2="urn:generic.ws.rightnow.com/v1_3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:GenericObject">
<ID xmlns="urn:base.ws.rightnow.com/v1_3" xsi:type="ChainSourceID" id="0" variableName="MyNewContact" />
<ns2:ObjectType>
<ns2:TypeName>Contact</ns2:TypeName>
</ns2:ObjectType>
<ns4:CustomFields xmlns:ns2="urn:generic.ws.rightnow.com/v1_3" xsi:type="ns2:GenericObject">
<ns2:ObjectType>
<ns2:TypeName>ContactCustomFields</ns2:TypeName>
</ns2:ObjectType>
<ns2:GenericFields dataType="OBJECT" name="c">
<ns2:DataValue>
<ns2:ObjectValue xsi:type="ns2:GenericObject">
<ns2:ObjectType>
<ns2:TypeName>ContactcCustomFields</ns2:TypeName>
</ns2:ObjectType>
<ns2:GenericFields dataType="STRING" name="credit_card">
<ns2:DataValue>
<ns2:StringValue>Setting Custom Field!</ns2:StringValue>
</ns2:DataValue>
</ns2:GenericFields>
</ns2:ObjectValue>
</ns2:DataValue>
</ns2:GenericFields>
</ns4:CustomFields>
<ns2:GenericFields dataType="OBJECT" name="Name">
<ns2:DataValue>
<ns2:ObjectValue xsi:type="ns2:GenericObject">
<ns2:ObjectType>
<ns2:TypeName>PersonName</ns2:TypeName>
</ns2:ObjectType>

<ns2:GenericFields dataType="STRING" name="First">
<ns2:DataValue>
<ns2:StringValue>Chris</ns2:StringValue>
</ns2:DataValue>
</ns2:GenericFields>
<ns2:GenericFields dataType="STRING" name="Last">
<ns2:DataValue>
<ns2:StringValue>Omland</ns2:StringValue>
</ns2:DataValue>
</ns2:GenericFields>
</ns2:ObjectValue>
</ns2:DataValue>
</ns2:GenericFields>
<ns2:GenericFields dataType="NAMED_ID" name="Organization">
<ns2:DataValue>
<ns2:NamedIDValue>
<ID xmlns="urn:base.ws.rightnow.com/v1_3" xsi:type="ChainDestinationID" id="0" variableName="NewOrganization" />
</ns2:NamedIDValue>
</ns2:DataValue>
</ns2:GenericFields>
</ns7:RNObjects>
<ns7:ProcessingOptions>
<ns7:SuppressExternalEvents>false</ns7:SuppressExternalEvents>
<ns7:SuppressRules>false</ns7:SuppressRules>
</ns7:ProcessingOptions>
</ns7:CreateMsg>
</ns7:BatchRequestItem>
<ns7:BatchRequestItem>
<ns7:CreateMsg>
<ns7:RNObjects xmlns:ns2="urn:generic.ws.rightnow.com/v1_3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:GenericObject">
<ID xmlns="urn:base.ws.rightnow.com/v1_3" xsi:type="ChainSourceID" id="0" variableName="MyNewIncident" />
<ns2:ObjectType>
<ns2:TypeName>Incident</ns2:TypeName>
</ns2:ObjectType>

<ns2:GenericFields dataType="NAMED_ID" name="Organization">
<ns2:DataValue>
<ns2:NamedIDValue>
<ID xmlns="urn:base.ws.rightnow.com/v1_3" xsi:type="ChainDestinationID" id="0" variableName="NewOrganization" />
</ns2:NamedIDValue>
</ns2:DataValue>
</ns2:GenericFields>
<ns2:GenericFields dataType="STRING" name="Subject">
<ns2:DataValue>
<ns2:StringValue>New Incident with Chaining Contact & Organization</ns2:StringValue>
</ns2:DataValue>
</ns2:GenericFields>
<ns2:GenericFields dataType="OBJECT" name="PrimaryContact">
<ns2:DataValue>
<ns2:ObjectValue xsi:type="ns2:GenericObject">
<ns2:ObjectType>
<ns2:TypeName>IncidentContact</ns2:TypeName>
</ns2:ObjectType>
<ns2:GenericFields dataType="NAMED_ID" name="Contact">
<ns2:DataValue>
<ns2:NamedIDValue>
<ID xmlns="urn:base.ws.rightnow.com/v1_3" xsi:type="ChainDestinationID" id="0" variableName="MyNewContact" />
</ns2:NamedIDValue>
</ns2:DataValue>
</ns2:GenericFields>
</ns2:ObjectValue>
</ns2:DataValue>
</ns2:GenericFields>

</ns7:RNObjects>
<ns7:ProcessingOptions>
<ns7:SuppressExternalEvents>false</ns7:SuppressExternalEvents>
<ns7:SuppressRules>false</ns7:SuppressRules>
</ns7:ProcessingOptions>
</ns7:CreateMsg>
</ns7:BatchRequestItem>

<ns7:BatchRequestItem>
<ns7:GetMsg>
<ns7:RNObjects xmlns:ns2="urn:generic.ws.rightnow.com/v1_3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:GenericObject">
<ID xmlns="urn:base.ws.rightnow.com/v1_3" xsi:type="ChainDestinationID" id="0" variableName="MyNewIncident" />
<ns2:ObjectType>
<ns2:TypeName>Incident</ns2:TypeName>
</ns2:ObjectType>
</ns7:RNObjects>
<ns7:ProcessingOptions>
<ns7:FetchAllNames>false</ns7:FetchAllNames>
</ns7:ProcessingOptions>
</ns7:GetMsg>
</ns7:BatchRequestItem>
</ns7:Batch>
</soapenv:Body>
</soapenv:Envelope>

Zircon - This is a contributing Drupal Theme
Design by WeebPal.