AI-generated Key Takeaways
-
Starting with version 19.0.0, the Google Ads API client library for .NET will no longer support .NET 5.0, requiring an upgrade before the end of 2024 for continued functionality.
-
The Google Ads API uses field masks to specify which fields to update during an operation, ignoring any unspecified fields.
-
The
FieldMaskUtil
provides methods likeAllSetFieldsOf
andFromChanges
to help generate field masks automatically from objects. -
When updating
MESSAGE
fields with subfields without setting the subfields explicitly, manually add the mutable subfields to theFieldMask
to avoid errors. -
To clear a field, explicitly add it to the field mask for consistent and reliable behavior, even if the field is defined as optional.
In the Google Ads API, a field mask is used to provide a list of fields that an API request should update. Any field that is not specified in the field mask will be ignored, even if sent to the server.
FieldMaskUtil class
The recommended way to generate field masks is to use the built-in
FieldMaskUtil
class, which lets you generate field masks from a modified
object instead of building them from scratch.
Here's an example for updating a campaign, that uses the
FieldMasks.AllSetFieldsOf
method to produce a field mask that enumerates all
the set fields. You can then pass the generated field mask directly to the
update call.
// Update campaign by setting its status to paused, and "Search network" to false.
Campaign campaignToUpdate = new Campaign()
{
ResourceName = ResourceNames.Campaign(customerId, campaignId),
Status = CampaignStatus.Paused,
NetworkSettings = new NetworkSettings()
{
TargetSearchNetwork = false
}
};
// Create the operation.
CampaignOperation operation = new CampaignOperation()
{
Update = campaignToUpdate,
UpdateMask = FieldMasks.AllSetFieldsOf(campaignToUpdate)
};
// Update the campaign.
MutateCampaignsResponse response = campaignService.MutateCampaigns(
customerId.ToString(), new CampaignOperation[] { operation });
Sometimes, you may need to work with an existing object, and update a few
fields. In such cases, you'd modify the code to use the FieldMasks.FromChanges
method instead. This method generates a field mask that represents the
difference between two objects.
Campaign existingCampaign;
// Obtain existingCampaign from elsewhere.
...
// Create a new campaign based off the existing campaign for update.
Campaign campaignToUpdate = new Campaign(existingCampaign);
// Update campaign by setting its status to paused, and "Search network" to
// false.
campaignToUpdate.Status = CampaignStatus.Paused;
campaignToUpdate.NetworkSettings = new NetworkSettings()
{
TargetSearchNetwork = false
}
// Create the operation.
CampaignOperation operation = new CampaignOperation()
{
Update = campaignToUpdate,
UpdateMask = FieldMasks.FromChanges(existingCampaign, campaignToUpdate)
};
How to handle FieldMaskError.FIELD_HAS_SUBFIELDS
errors
On rare occasions, you may need to set a field without updating any of the sub-fields of that type. Consider the following example:
// Creates a campaign with the proper resource name and an empty
// MaximizeConversions field.
Campaign campaign = new Campaign()
{
ResourceName = ResourceNames.Campaign(customerId, campaignId),
MaximizeConversions = new MaximizeConversions()
};
CampaignOperation operation = new CampaignOperation()
{
Update = campaign,
UpdateMask = FieldMasks.AllSetFieldsOf(campaign)
};
MutateCampaignsResponse response = campaignService.MutateCampaigns(
customerId.ToString(), new CampaignOperation[] { operation });
This API call will fail with an FieldMaskError.FIELD_HAS_SUBFIELDS
error.
Since MaximizeConversions
has three
sub-fields, the Google Ads API server expects field masks for those fields to be
present in the request. However, FieldMaskUtil
cannot generate field masks
correctly in this situation, since the request is not setting these fields.
In such cases, you can manually edit the field mask as follows:
// Creates a Campaign object with the proper resource name.
Campaign campaign = new Campaign()
{
ResourceName = ResourceNames.Campaign(customerId, campaignId),
};
FieldMask fieldMask = FieldMasks.AllSetFieldsOf(campaign);
// Only include 'maximize_conversions.target_cpa_micros' in the field mask
// as it is the only mutable subfield on MaximizeConversions when used as a
// standard bidding strategy.
//
// Learn more about standard and portfolio bidding strategies here:
// https://developers.google.com/google-ads/api/docs/campaigns/bidding/assign-strategies
fieldMask.Paths.AddRange(new string[] {
"maximize_conversions.target_cpa_micros",
});
// Creates an operation to update the campaign with the specified fields.
CampaignOperation operation = new CampaignOperation()
{
Update = campaign,
UpdateMask = fieldMask
};
How to clear fields
Google Ads API supports clearing some field values. To clear a field, you must manually set the field mask for that field. Setting a field to its default value (such as zero for an int64 field) won't clear the field.
The following code example shows how to clear the target_cpa_micros
field of
MaximizeConversions
bidding strategy.
Correct code
The following code clears the target_cpa_micros
field because we are
setting the maximize_conversions.target_cpa_micros
in the field mask and
not setting thecampaign.MaximizeConversions.TargetCpaMicros
field.
// Creates a Campaign object with the proper resource name.
Campaign campaign = new Campaign()
{
ResourceName = ResourceNames.Campaign(customerId, campaignId),
};
// Constructs a field mask from the existing campaign and adds the
// 'maximize_conversions.target_cpa_micros' field to the field mask, which will
// clear this field from the bidding strategy without impacting any other fields
// on the bidding strategy.
FieldMask fieldMask = FieldMasks.AllSetFieldsOf(campaign);
fieldMask.Paths.AddRange(new string[] {
"maximize_conversions.target_cpa_micros",
});
// Creates an operation to update the campaign with the specified field.
CampaignOperation operation = new CampaignOperation()
{
Update = campaign,
UpdateMask = fieldMask
};
Incorrect code
The following code doesn't clear the target_cpa_micros
field, since we
are setting this field to zero. Both the FieldMaskUtils
and the Google Ads API
server will ignore this value. In addition, you may also not receive an
error in this case, since the value was ignored by the server.
// Creates a campaign with the proper resource name and a MaximizeConversions
// object. Attempt to clear the target_cpa_micros field by setting it to 0.
Campaign campaign = new Campaign()
{
ResourceName = ResourceNames.Campaign(customerId, campaignId),
MaximizeConversions = new MaximizeConversions()
{
TargetCpaMicros = 0
}
};
// Constructs an operation, using the FieldMasks' AllSetFieldsOf utility to
// derive the update mask. However, the field mask will NOT include
// 'maximize_conversions.target_cpa_micros'.
CampaignOperation operation = new CampaignOperation()
{
Update = campaign,
UpdateMask = FieldMasks.AllSetFieldsOf(campaign)
};
// Sends the operation in a mutate request that will succeed but will NOT update
// the 'target_cpa_micros' field because 'maximize_conversions.target_cpa_micros'
// was not included in the field mask.
MutateCampaignsResponse response = campaignService.MutateCampaigns(
customerId.ToString(), new CampaignOperation[] { operation });