Praca z typami buforów protokołu

Ponieważ interfejs Google Ads API używa protokołu Protobuf jako domyślnego formatu danych, podczas pracy z interfejsem API warto poznać kilka konwencji i typów protokołu Protobuf.

Pola opcjonalne

Wiele pól w interfejsie Google Ads API jest oznaczonych jako optional. Dzięki temu możesz odróżnić przypadki, gdy pole ma pustą wartość, od sytuacji, gdy serwer nie zwrócił wartości pola. Te pola działają jak zwykłe pola, ale dodatkowo udostępniają dodatkowe metody czyszczenia i sprawdzania, czy pole jest ustawione.

Na przykład pole Name obiektu Campaign jest oznaczone jako opcjonalne. Aby pracować z tym polem, możesz użyć tych metod.

// Get the name.
string name = campaign.Name;

// Set the name.
campaign.Name = name;

// Check if the campaign object has the name field set.
bool hasName = campaign.HasName();

// Clear the name field. Use this method to exclude Name field from
// being sent to the server in a subsequent API call.
campaign.ClearName();

// Set the campaign to empty string value. This value will be
// sent to the server if you use this object in a subsequent API call.
campaign.Name = "";

// This will throw a runtime error. Use ClearName() instead.
campaign.Name = null;

Powtarzające się typy

Tablica pól jest reprezentowana w interfejsie Google Ads API jako tylko do odczytuRepeatedField.

Przykładem jest pole url_custom_parameters kampanii, które jest polem powtarzalnym, więc w bibliotece klienta .NET jest ono reprezentowane jako tylko do odczytu RepeatedField<CustomParameter>.

RepeatedField implementuje interfejs IList<T>.

Pole RepeatedField możesz wypełnić na 2 sposoby.

Starsza wersja C#: dodawanie wartości za pomocą metody AddRange

Poniżej znajdziesz przykład.

Campaign campaign = new Campaign()
{
    ResourceName = ResourceNames.Campaign(customerId, campaignId),
    Status = CampaignStatus.Paused,
};

// Add values to UrlCustomParameters using AddRange method.
campaign.UrlCustomParameters.AddRange(new CustomParameter[]
{
    new CustomParameter { Key = "season", Value = "christmas" },
    new CustomParameter { Key = "promocode", Value = "NY123" }
});

Nowsze wersje C#: używaj składni inicjalizatora kolekcji

// Option 1: Initialize the field directly.
Campaign campaign = new Campaign()
{
    ResourceName = ResourceNames.Campaign(customerId, campaignId),
    Status = CampaignStatus.Paused,
    // Directly initialize the field.
    UrlCustomParameters =
    {
        new CustomParameter { Key = "season", Value = "christmas" },
        new CustomParameter { Key = "promocode", Value = "NY123" }
    }
};

// Option 2: Initialize using an intermediate variable.
CustomParameter[] parameters = new CustomParameter[]
{
    new CustomParameter { Key = "season", Value = "christmas" },
    new CustomParameter { Key = "promocode", Value = "NY123" }
}

Campaign campaign1 = new Campaign()
{
    ResourceName = ResourceNames.Campaign(customerId, campaignId),
    Status = CampaignStatus.Paused,
    // Initialize from an existing array.
    UrlCustomParameters = { parameters }
};

Typy OneOf

Niektóre pola w interfejsie Google Ads API są oznaczone jako pola OneOf, co oznacza, że mogą one zawierać różne typy, ale tylko jedną wartość w danym momencie. Pola typu OneOf są podobne do typu union w C.

Biblioteka .NET implementuje pola OneOf, udostępniając jedną właściwość dla każdego typu wartości, która może być przechowywana w polu OneOf, oraz wszystkie właściwości aktualizujące pole klasy współdzielonej.

Na przykład campaign_bidding_strategy w kampanii jest oznaczone jako pole typu OneOf. Ta klasa jest implementowana w ten sposób (kod uproszczony ze względu na zwiękłą objętość):

public sealed partial class Campaign : pb::IMessage<Campaign>
{
    object campaignBiddingStrategy_ = null;
    CampaignBiddingStrategyOneofCase campaignBiddingStrategyCase_;

    public ManualCpc ManualCpc
    {
        get
        {
            return campaignBiddingStrategyCase_ == CampaignBiddingStrategyOneofCase.ManualCpc ?
                (ManualCpc) campaignBiddingStrategy_ : null;
        }
        set
        {
            campaignBiddingStrategy_ = value;
            campaignBiddingStrategyCase_ = CampaignBiddingStrategyOneofCase.ManualCpc;
        }
    }

    public ManualCpm ManualCpm
    {
        get
        {
            return campaignBiddingStrategyCase_ == CampaignBiddingStrategyOneofCase.ManualCpm ?
                (ManualCpm) campaignBiddingStrategy_ : null;
        }
        set
        {
            campaignBiddingStrategy_ = value;
            campaignBiddingStrategyCase_ = CampaignBiddingStrategyOneofCase.ManualCpm;
        }
    }

    public CampaignBiddingStrategyOneofCase CampaignBiddingStrategyCase
    {
        get { return campaignBiddingStrategyCase_; }
    }
}

Ponieważ właściwości OneOf korzystają z tego samego miejsca na dane, jedno przypisanie może nadpisać poprzednie, co może prowadzić do drobnych błędów. Na przykład

Campaign campaign = new Campaign()
{
    ManualCpc = new ManualCpc()
    {
        EnhancedCpcEnabled = true
    },
    ManualCpm = new ManualCpm()
    {

    }
};

W tym przypadku wartość campaign.ManualCpc to teraz null, ponieważ zainicjowanie pola campaign.ManualCpm zastępuje poprzednią inicjalizację pola campaign.ManualCpc.

Konwertowanie na inne formaty

Możesz łatwo konwertować obiekty protobuf na format JSON i odwrotnie. Jest to przydatne podczas tworzenia systemów, które muszą współpracować z innymi systemami wymagającymi danych w formatach tekstowych, takich jak JSON czy XML.

GoogleAdsRow row = new GoogleAdsRow()
{
    Campaign = new Campaign()
    {
        Id = 123,
        Name = "Campaign 1",
        ResourceName = ResourceNames.Campaign(1234567890, 123)
    }
};
// Serialize to JSON and back.
string json = JsonFormatter.Default.Format(row);
row = GoogleAdsRow.Parser.ParseJson(json);

Możesz też serializować obiekty w postaci bajtów i z powrotem. Serializacja binarna jest bardziej wydajna pod względem pamięci i miejsca na dane niż format JSON.

GoogleAdsRow row = new GoogleAdsRow()
{
    Campaign = new Campaign()
    {
        Id = 123,
        Name = "Campaign 1",
        ResourceName = ResourceNames.Campaign(1234567890, 123)
    }
};
// Serialize to bytes and back.
byte[] bytes = row.ToByteArray();
row = GoogleAdsRow.Parser.ParseFrom(bytes);