function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
David_RDavid_R 

Dynamically update custom object (c#)

I am working in c#, am relatively new to the Salesforce API's and am trying to update a custom object dynamically.  I assume there is some way to retrieve (or create) the object, get its fields collection and update via the collection, something like myOjbect.Fields("status__c) = "accepted".  It's necessary to write it in this way because I won't know the fields to update in advance and therefore can't refer to them explicitly, like myObject.status.  Any direction much appreciated.

SuperfellSuperfell

Yes, you can either use the partner API, which is loosely/runtime typed (in .NET you typically end up working with XmlElements), or alternatively you can use the REST API and json payloads which are naturally loosely typed/dynamic in nature. in either case the desribeSObject call will return metadata about the sobject, including field names, types etc.

David_RDavid_R

Thanks Simon.  I'm working with the developer edition and generated the partner api wsdl, but when I tried to include it in my .net project my login didn't authenticate even though I used the security token with the password.  Does the partner api require a separate security token and if so, how do I go about getting it.

SuperfellSuperfell

login works exactly the same way in both the partner & enterprise APIs

JWykelJWykel

In C#, Reflection would be what you are likely looking for.

var result = sfdc.query("SELECT Id, " + fieldName + " FROM " + objectName + " WHERE Id = '" + recordId + "'"); //single quotes around the Id there, in case you missed it :)
var myObject = result.records[0];
myObject.GetType().GetProperties().First(p => p.Name == fieldName).SetValue(myObject, "Accepted", null);

sfdc.update(myObject);

 (that mixes LINQ in with Reflection, sorry if that was too much!)
GetType gets the type of the myObject (which is whatever the query returns)

GetProperties gets a list of PropertyInfo; if LINQ isn't in your skillset, you could also do something along the lines of:

foreach(PropertyInfo p : myObject.GetType().GetProperties())
{
    if(p.Name == fieldName)
    {
        p.SetValue(myObject, "Accepted", null); //"Accepted" is the value you want to set the field to
        break;
    }
}

 SetValue on PropertyInfo takes the instance you're setting it on (myObject), the value you're setting it to ("Accepted") and null.  I'll leave it to you to research other options for that 'null'; I have not ever had to use anything but null, though.

JWykelJWykel

Quick note regarding setting the field to null as it is a special situation when it comes to the Enterprise API.

 

You cannot simply set the value to null, you actually need to add the fieldName to the fieldsToNull array:

if(valueToSetTo == null) myObject.fieldsToNull = new string[]{ fieldName };

 

 

Another quick note:

Unless you're performing processing such as a concept of 'onchange', you do not actually need to select the object if you already have the Id:

var myObject = Activator.CreateInstance(Type.GetType(objectName));
myObject.Id = recordId;
myObject.GetType().GetProperties().First(p => p.Name == fieldName).SetValue(myObject, "Accepted", null);
sfdc.update(myObject);