In the Google Ads API, a [field mask](https://protobuf.dev/reference/protobuf/google.protobuf/#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 is ignored, even if sent to the server.

## FieldMasks class

The recommended way to generate field masks in the .NET client library is to use
the built-in `FieldMasks` utility 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 enumerating all 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, use the `FieldMasks.FromChanges` method instead. This
method generates a field mask that represents the difference between two
objects:

    Campaign existingCampaign;

    // Obtain existingCampaign from an earlier API call.

    // Create a new campaign based on 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)
    };

## Handle `FieldMaskError.FIELD_HAS_SUBFIELDS` errors

On rare occasions, you may need to set a message field without updating any of
its subfields. 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 fails with a `FieldMaskError.FIELD_HAS_SUBFIELDS` error. Since
[`MaximizeConversions`](https://developers.google.com/google-ads/api/reference/rpc/v26/MaximizeConversions) has subfields, the
Google Ads API server expects field masks for the mutable subfields to be present in
the request. However, `FieldMasks` cannot generate subfield masks automatically
in this situation because the request does not set any subfields.

In such cases, you can manually add paths to `fieldMask.Paths` (which is a
`RepeatedField<string>`):

    // 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 at:
    // https://developers.google.com/google-ads/api/docs/campaigns/bidding/assign-strategies
    fieldMask.Paths.Add("maximize_conversions.target_cpa_micros");

    // Creates an operation to update the campaign with the specified fields.
    CampaignOperation operation = new CampaignOperation()
    {
        Update = campaign,
        UpdateMask = fieldMask
    };

## Clear fields

The Google Ads API supports clearing some field values. To clear a field, you must
manually include that field in the field mask while leaving the field unset on
the resource object. Setting a field to its default value (such as `0` for an
`int64` field) doesn't clear the field.

The following code example shows how to clear the `target_cpa_micros` field of a
`MaximizeConversions` bidding strategy:

### Correct code

The following code clears the `target_cpa_micros` field because it adds
`maximize_conversions.target_cpa_micros` to the field mask without setting
the `campaign.MaximizeConversions.TargetCpaMicros` property:

    // 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
    // clears this field from the bidding strategy without impacting any other
    // fields on the bidding strategy.
    FieldMask fieldMask = FieldMasks.AllSetFieldsOf(campaign);
    fieldMask.Paths.Add("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, because
it sets the field to `0`. Both the `FieldMasks` utility and the Google Ads API
server ignore this value when `TargetCpaMicros` is `0` or when the path is
omitted from the mask, and the server does not return an error:

    // Creates a campaign with the proper resource name and a
    // MaximizeConversions object. Attempts 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 FieldMasks.AllSetFieldsOf to derive the
    // update mask.
    CampaignOperation operation = new CampaignOperation()
    {
        Update = campaign,
        UpdateMask = FieldMasks.AllSetFieldsOf(campaign)
    };

    // Sends the operation in a mutate request that succeeds without clearing
    // the previous 'target_cpa_micros' value cleanly.
    MutateCampaignsResponse response = campaignService.MutateCampaigns(
        customerId.ToString(), new CampaignOperation[] { operation });