Skip to content

Commit 03b7e08

Browse files
committed
Protobuf scalar default values and ByteString detail
1 parent a3dcf32 commit 03b7e08

File tree

1 file changed

+37
-10
lines changed

1 file changed

+37
-10
lines changed

aspnetcore/grpc/protobuf.md

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ Protobuf supports a range of native scalar value types. The following table list
6969
| `string` | `string` |
7070
| `bytes` | `ByteString` |
7171

72+
Scalar values always have a default value and can't be set to `null`. This constraint includes `string` and `ByteString` which are C# classes. `string` defaults to an empty string value and `ByteString` defaults to an empty bytes value. Attempting to set them to `null` throws an error.
73+
74+
[Nullable wrapper types](#nullable-types) can be used to support null values.
75+
7276
### Dates and times
7377

7478
The native scalar types don't provide for date and time values, equivalent to .NET's <xref:System.DateTimeOffset>, <xref:System.DateTime>, and <xref:System.TimeSpan>. These types can be specified by using some of Protobuf's *Well-Known Types* extensions. These extensions provide code generation and runtime support for complex field types across the supported platforms.
@@ -129,19 +133,42 @@ message Person {
129133
}
130134
```
131135

132-
Protobuf uses .NET nullable types, for example, `int?`, for the generated message property.
136+
`wrappers.proto` types aren't exposed in generated properties. Protobuf automatically maps them to appropriate .NET nullable types in C# messages. For example, a `google.protobuf.Int32Value` field generates an `int?` property. Reference type properties like `string` and `ByteString` are unchanged except `null` can be assigned to them without error.
133137

134138
The following table shows the complete list of wrapper types with their equivalent C# type:
135139

136-
| C# type | Well-Known Type wrapper |
137-
| --------- | ----------------------------- |
138-
| `bool?` | `google.protobuf.BoolValue` |
139-
| `double?` | `google.protobuf.DoubleValue` |
140-
| `float?` | `google.protobuf.FloatValue` |
141-
| `int?` | `google.protobuf.Int32Value` |
142-
| `long?` | `google.protobuf.Int64Value` |
143-
| `uint?` | `google.protobuf.UInt32Value` |
144-
| `ulong?` | `google.protobuf.UInt64Value` |
140+
| C# type | Well-Known Type wrapper |
141+
| ------------ | ----------------------------- |
142+
| `bool?` | `google.protobuf.BoolValue` |
143+
| `double?` | `google.protobuf.DoubleValue` |
144+
| `float?` | `google.protobuf.FloatValue` |
145+
| `int?` | `google.protobuf.Int32Value` |
146+
| `long?` | `google.protobuf.Int64Value` |
147+
| `uint?` | `google.protobuf.UInt32Value` |
148+
| `ulong?` | `google.protobuf.UInt64Value` |
149+
| `string` | `google.protobuf.StringValue` |
150+
| `ByteString` | `google.protobuf.BytesValue` |
151+
152+
### Bytes
153+
154+
Binary payloads are supported in Protobuf with the `bytes` scalar value type. A generated property in C# uses `ByteString` as the property type.
155+
156+
Use `ByteString.CopyFrom(byte[] data)` to create a new instance from a byte array:
157+
158+
```csharp
159+
var data = await File.ReadAllBytesAsync(path);
160+
161+
var payload = new PayloadResponse();
162+
payload.Data = ByteString.CopyFrom(data);
163+
```
164+
165+
`ByteString` data is accessed directly using `ByteString.Span` or `ByteString.Memory`. Or call `ByteString.ToByteArray()` to convert an instance back into a byte array:
166+
167+
```csharp
168+
var payload = await client.GetPayload(new PayloadRequest());
169+
170+
await File.WriteAllBytesAsync(path, payload.Data.ToByteArray());
171+
```
145172

146173
### Decimals
147174

0 commit comments

Comments
 (0)