Praca z typami buforów protokołu

Interfejs Google Ads API używa proto3 jako domyślnego formatu ładunku, dlatego podczas pracy z nim warto znać kilka konwencji i typów protobuf.

Pola opcjonalne

Wiele pól w interfejsie Google Ads API jest oznaczonych jako optional. Dzięki temu możesz odróżnić przypadki, w których pole ma pustą wartość, od przypadków, w których serwer nie wysłał wartości dla tego pola. Pola te działają jak zwykłe pola, ale mają też dodatkowe metody czyszczenia pola i sprawdzania, czy jest ono ustawione.

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

// 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;

Pola powtarzane

Tablica pól jest reprezentowana w interfejsie Google Ads API jako pole tylko do odczytu RepeatedField.

Przykładem może być pole url_custom_parameters kampanii, które jest polem powtarzanym, dlatego w bibliotece klienta .NET jest reprezentowane jako pole RepeatedField<CustomParameter> tylko do odczytu. Klasa RepeatedField implementuje interfejs IList<T>.

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

Metoda AddRange

 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" }
 });
 ```

Składnia inicjatora 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 }
};

Pola typu oneof

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

Biblioteka .NET implementuje pola oneof, udostępniając 1 właściwość dla każdego typu wartości, które mogą być przechowywane w polu oneof, oraz wszystkie właściwości aktualizujące wspólne pole klasy.

Na przykład campaign_bidding_strategy kampanii jest oznaczony jako pole oneof. Ta klasa jest zaimplementowana w ten sposób (kod uproszczony dla zwięzłości):

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ż usługi oneof współdzielą miejsce na dane, jedno przypisanie może zastąpić poprzednie, co może prowadzić do subtelnych 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ą inicjację pola campaign.ManualCpc.

Konwersja na inne formaty

Konwertowanie na format JSON

Możesz przekonwertować 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 lub 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);

Konwertowanie na bajty

Możesz serializować obiekt do 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);