将 WCF 服务迁移到 gRPC 服务时出错
Error when migrating WCF service to gRPC service
我有一个 WCF 服务,我想将其重写为 gRPC 服务。有一个特定的端点给我带来了一些麻烦。现在该方法如下所示:
public List<Dictionary<string, string> GetData(GetDataRequest request)
{
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
/// ...
/// Code that populates the results list
/// ...
return results;
}
我是这样编写原型文件的:
message GetDataRequest {
string code = 1;
}
message GetDataResponse {
message KeyValuePair {
map<string, string> pairs = 1;
}
repeated KeyValuePair results= 1;
}
service Demo {
rpc GetData(GetDataRequest) returns (GetDataResponse);
}
以及服务实现:
public class DemoService : Demo.DemoBase
{
public override async Task<GetDataResponse> GetData(GetDataRequest request, ServerCallContext context)
{
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
/// ...
/// Code that populates the results list
/// ...
return await Task.FromResult(new GetDataResponse
{
Results = results
});
}
}
我的问题是,当我尝试 return 字典列表时,我得到了这个错误:
我需要进行哪些更改才能return 正确响应?
我使用 Visual Studio 2019 gRPC 服务模板。
这是从 protobuf 编译器生成的 GetDataResponse 代码:
public sealed partial class GetDataResponse : pb::IMessage<GetDataResponse>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
, pb::IBufferMessage
#endif
{
private static readonly pb::MessageParser<GetDataResponse> _parser = new pb::MessageParser<GetDataResponse>(() => new GetDataResponse());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<GetDataResponse> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::GrpcService.Protos.DemoReflection.Descriptor.MessageTypes[1]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public GetDataResponse() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public GetDataResponse(GetDataResponse other) : this() {
results_ = other.results_.Clone();
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public GetDataResponse Clone() {
return new GetDataResponse(this);
}
/// <summary>Field number for the "results" field.</summary>
public const int ResultsFieldNumber = 1;
private static readonly pb::FieldCodec<global::GrpcService.Protos.GetDataResponse.Types.KeyValuePair> _repeated_results_codec
= pb::FieldCodec.ForMessage(10, global::GrpcService.Protos.GetDataResponse.Types.KeyValuePair.Parser);
private readonly pbc::RepeatedField<global::GrpcService.Protos.GetDataResponse.Types.KeyValuePair> results_ = new pbc::RepeatedField<global::GrpcService.Protos.GetDataResponse.Types.KeyValuePair>();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::GrpcService.Protos.GetDataResponse.Types.KeyValuePair> Results {
get { return results_; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as GetDataResponse);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(GetDataResponse other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if(!results_.Equals(other.results_)) return false;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= results_.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
results_.WriteTo(output, _repeated_results_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
results_.WriteTo(ref output, _repeated_results_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += results_.CalculateSize(_repeated_results_codec);
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(GetDataResponse other) {
if (other == null) {
return;
}
results_.Add(other.results_);
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
input.ReadRawMessage(this);
#else
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
results_.AddEntriesFrom(input, _repeated_results_codec);
break;
}
}
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
case 10: {
results_.AddEntriesFrom(ref input, _repeated_results_codec);
break;
}
}
}
}
#endif
#region Nested types
/// <summary>Container for nested types declared in the GetDataResponse message type.</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
public sealed partial class KeyValuePair : pb::IMessage<KeyValuePair>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
, pb::IBufferMessage
#endif
{
private static readonly pb::MessageParser<KeyValuePair> _parser = new pb::MessageParser<KeyValuePair>(() => new KeyValuePair());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<KeyValuePair> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::GrpcService.Protos.GetDataResponse.Descriptor.NestedTypes[0]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public KeyValuePair() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public KeyValuePair(KeyValuePair other) : this() {
pairs_ = other.pairs_.Clone();
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public KeyValuePair Clone() {
return new KeyValuePair(this);
}
/// <summary>Field number for the "pairs" field.</summary>
public const int PairsFieldNumber = 1;
private static readonly pbc::MapField<string, string>.Codec _map_pairs_codec
= new pbc::MapField<string, string>.Codec(pb::FieldCodec.ForString(10, ""), pb::FieldCodec.ForString(18, ""), 10);
private readonly pbc::MapField<string, string> pairs_ = new pbc::MapField<string, string>();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<string, string> Pairs {
get { return pairs_; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as KeyValuePair);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(KeyValuePair other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (!Pairs.Equals(other.Pairs)) return false;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= Pairs.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
pairs_.WriteTo(output, _map_pairs_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
pairs_.WriteTo(ref output, _map_pairs_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += pairs_.CalculateSize(_map_pairs_codec);
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(KeyValuePair other) {
if (other == null) {
return;
}
pairs_.Add(other.pairs_);
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
input.ReadRawMessage(this);
#else
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
pairs_.AddEntriesFrom(input, _map_pairs_codec);
break;
}
}
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
case 10: {
pairs_.AddEntriesFrom(ref input, _map_pairs_codec);
break;
}
}
}
}
#endif
}
}
#endregion
}
在 ASP.NET Core gRPC for WCF developers the Repeated fields for lists and arrays 部分解释说
repeated fields are represented by read-only properties of the Google.Protobuf.Collections.RepeatedField type rather than any of the built-in .NET collection types. This type implements all the standard .NET collection interfaces, such as IList and IEnumerable. So you can use LINQ queries or convert it to an array or a list easily.
您必须使用 Add
/AddRange
向 属性 添加项目,例如:
var response=new GetDataResponse();
response.AddRange(results);
return response;
您不需要将 response
包装在 Task
到 return 中,因为您的方法具有 async
签名,所以它已经包装了 return 值。无论如何,await Task.FromResult(x)
只是 returns x
我有一个 WCF 服务,我想将其重写为 gRPC 服务。有一个特定的端点给我带来了一些麻烦。现在该方法如下所示:
public List<Dictionary<string, string> GetData(GetDataRequest request)
{
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
/// ...
/// Code that populates the results list
/// ...
return results;
}
我是这样编写原型文件的:
message GetDataRequest {
string code = 1;
}
message GetDataResponse {
message KeyValuePair {
map<string, string> pairs = 1;
}
repeated KeyValuePair results= 1;
}
service Demo {
rpc GetData(GetDataRequest) returns (GetDataResponse);
}
以及服务实现:
public class DemoService : Demo.DemoBase
{
public override async Task<GetDataResponse> GetData(GetDataRequest request, ServerCallContext context)
{
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
/// ...
/// Code that populates the results list
/// ...
return await Task.FromResult(new GetDataResponse
{
Results = results
});
}
}
我的问题是,当我尝试 return 字典列表时,我得到了这个错误:
我需要进行哪些更改才能return 正确响应? 我使用 Visual Studio 2019 gRPC 服务模板。
这是从 protobuf 编译器生成的 GetDataResponse 代码:
public sealed partial class GetDataResponse : pb::IMessage<GetDataResponse>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
, pb::IBufferMessage
#endif
{
private static readonly pb::MessageParser<GetDataResponse> _parser = new pb::MessageParser<GetDataResponse>(() => new GetDataResponse());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<GetDataResponse> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::GrpcService.Protos.DemoReflection.Descriptor.MessageTypes[1]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public GetDataResponse() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public GetDataResponse(GetDataResponse other) : this() {
results_ = other.results_.Clone();
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public GetDataResponse Clone() {
return new GetDataResponse(this);
}
/// <summary>Field number for the "results" field.</summary>
public const int ResultsFieldNumber = 1;
private static readonly pb::FieldCodec<global::GrpcService.Protos.GetDataResponse.Types.KeyValuePair> _repeated_results_codec
= pb::FieldCodec.ForMessage(10, global::GrpcService.Protos.GetDataResponse.Types.KeyValuePair.Parser);
private readonly pbc::RepeatedField<global::GrpcService.Protos.GetDataResponse.Types.KeyValuePair> results_ = new pbc::RepeatedField<global::GrpcService.Protos.GetDataResponse.Types.KeyValuePair>();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::RepeatedField<global::GrpcService.Protos.GetDataResponse.Types.KeyValuePair> Results {
get { return results_; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as GetDataResponse);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(GetDataResponse other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if(!results_.Equals(other.results_)) return false;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= results_.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
results_.WriteTo(output, _repeated_results_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
results_.WriteTo(ref output, _repeated_results_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += results_.CalculateSize(_repeated_results_codec);
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(GetDataResponse other) {
if (other == null) {
return;
}
results_.Add(other.results_);
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
input.ReadRawMessage(this);
#else
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
results_.AddEntriesFrom(input, _repeated_results_codec);
break;
}
}
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
case 10: {
results_.AddEntriesFrom(ref input, _repeated_results_codec);
break;
}
}
}
}
#endif
#region Nested types
/// <summary>Container for nested types declared in the GetDataResponse message type.</summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static partial class Types {
public sealed partial class KeyValuePair : pb::IMessage<KeyValuePair>
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
, pb::IBufferMessage
#endif
{
private static readonly pb::MessageParser<KeyValuePair> _parser = new pb::MessageParser<KeyValuePair>(() => new KeyValuePair());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<KeyValuePair> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::GrpcService.Protos.GetDataResponse.Descriptor.NestedTypes[0]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public KeyValuePair() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public KeyValuePair(KeyValuePair other) : this() {
pairs_ = other.pairs_.Clone();
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public KeyValuePair Clone() {
return new KeyValuePair(this);
}
/// <summary>Field number for the "pairs" field.</summary>
public const int PairsFieldNumber = 1;
private static readonly pbc::MapField<string, string>.Codec _map_pairs_codec
= new pbc::MapField<string, string>.Codec(pb::FieldCodec.ForString(10, ""), pb::FieldCodec.ForString(18, ""), 10);
private readonly pbc::MapField<string, string> pairs_ = new pbc::MapField<string, string>();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public pbc::MapField<string, string> Pairs {
get { return pairs_; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as KeyValuePair);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool Equals(KeyValuePair other) {
if (ReferenceEquals(other, null)) {
return false;
}
if (ReferenceEquals(other, this)) {
return true;
}
if (!Pairs.Equals(other.Pairs)) return false;
return Equals(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override int GetHashCode() {
int hash = 1;
hash ^= Pairs.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
return hash;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override string ToString() {
return pb::JsonFormatter.ToDiagnosticString(this);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void WriteTo(pb::CodedOutputStream output) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
output.WriteRawMessage(this);
#else
pairs_.WriteTo(output, _map_pairs_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
pairs_.WriteTo(ref output, _map_pairs_codec);
if (_unknownFields != null) {
_unknownFields.WriteTo(ref output);
}
}
#endif
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int CalculateSize() {
int size = 0;
size += pairs_.CalculateSize(_map_pairs_codec);
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
return size;
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(KeyValuePair other) {
if (other == null) {
return;
}
pairs_.Add(other.pairs_);
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public void MergeFrom(pb::CodedInputStream input) {
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
input.ReadRawMessage(this);
#else
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
break;
case 10: {
pairs_.AddEntriesFrom(input, _map_pairs_codec);
break;
}
}
}
#endif
}
#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
uint tag;
while ((tag = input.ReadTag()) != 0) {
switch(tag) {
default:
_unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
break;
case 10: {
pairs_.AddEntriesFrom(ref input, _map_pairs_codec);
break;
}
}
}
}
#endif
}
}
#endregion
}
在 ASP.NET Core gRPC for WCF developers the Repeated fields for lists and arrays 部分解释说
repeated fields are represented by read-only properties of the Google.Protobuf.Collections.RepeatedField type rather than any of the built-in .NET collection types. This type implements all the standard .NET collection interfaces, such as IList and IEnumerable. So you can use LINQ queries or convert it to an array or a list easily.
您必须使用 Add
/AddRange
向 属性 添加项目,例如:
var response=new GetDataResponse();
response.AddRange(results);
return response;
您不需要将 response
包装在 Task
到 return 中,因为您的方法具有 async
签名,所以它已经包装了 return 值。无论如何,await Task.FromResult(x)
只是 returns x