1

我有一个*.proto文件定义了两条消息:MyRequestMyResponse. 这是在通用 .NET Standard 2.0 库中定义的,并使用以下 NuGet 包:

    <PackageReference Include="Google.Protobuf" Version="3.18.0" />
    <PackageReference Include="Grpc" Version="2.40.0" />
    <PackageReference Include="Grpc.Tools" Version="2.40.0">

服务器

我有一个 .NET Framework (4.8) WebAPI 和以下操作方法:

[HttpPost]
public async Task<IHttpActionResult> FetchSomeData()
{
    using (var ms = new MemoryStream(2048))
    {
        await content.CopyToAsync(ms).ConfigureAwait(false);
        byte[] bytes = ms.ToArray();
        MyRequest request = MyRequest.Parser.ParseFrom(bytes);

        MyResponse response = await SomeMethodAsync(request).ConfigureAwait(false);
        byte[] responseByteArray = response.ToByteArray();
        return this.Ok(responseByteArray);
    }
}

所以这成功地接收到一个通过MyRequestHttpPost发送的对象,并根据该对象中的数据,生成一个对象并返回它。MyResponse

客户端

我有一个使用 HttpClient 使用此服务的 .Net 5 客户端:

// Prepare Request
MyRequest webRequest = new() { ... };
byte[] byteArray = webRequest.ToByteArray();
ByteArrayContent byteContent = new(byteArray);

// Send data
HttpClient client = this.HttpClientFactory.CreateClient("Blah");
HttpResponseMessage webResponse = await client.PostAsync(new Uri("...", UriKind.Relative), byteContent).ConfigureAwait(false);

// Read response
HttpContent content = webResponse.Content;
byte[] webMethodResponseAsByteArray = await content.ReadAsByteArrayAsync().ConfigureAwait(false);
MyResponse webMethodResponse = MyResponse.Parser.ParseFrom(webMethodResponseAsByteArray);

HttpClient "Blah" 仅配置有基本 URL 和安全令牌。

但是....当我ParseFrom在最后一行调用时,我得到以下异常:

Google.Protobuf.InvalidProtocolBufferException
  HResult=0x80131620
  Message=Protocol message contained a tag with an invalid wire type.
  Source=Google.Protobuf
  StackTrace:
   at Google.Protobuf.UnknownFieldSet.MergeFieldFrom(ParseContext& ctx)
   at Google.Protobuf.UnknownFieldSet.MergeFieldFrom(UnknownFieldSet unknownFields, ParseContext& ctx)
   at namespace.MyResponse.pb::Google.Protobuf.IBufferMessage.InternalMergeFrom(ParseContext& input) in ....

这个不知道怎么解决。。。

4

1 回答 1

0

我通过更改 .NET Framework (4.8) Server 的方法解决了我面临的问题:

[HttpPost]
public async Task<IHttpActionResult> FetchSomeData()
{
    using (var ms = new MemoryStream(2048))
    {
        await content.CopyToAsync(ms).ConfigureAwait(false);
        byte[] bytes = ms.ToArray();
        MyRequest request = MyRequest.Parser.ParseFrom(bytes);

        MyResponse response = await SomeMethodAsync(request).ConfigureAwait(false);
        byte[] responseByteArray = response.ToByteArray();
        return this.Ok(responseByteArray);
    }
}

[HttpPost]
public async Task<HttpResponseMessage FetchSomeData()
{
    using (var ms = new MemoryStream(2048))
    {
        await content.CopyToAsync(ms).ConfigureAwait(false);
        byte[] bytes = ms.ToArray();
        MyRequest request = MyRequest.Parser.ParseFrom(bytes);

        MyResponse response = await SomeMethodAsync(request).ConfigureAwait(false);
        byte[] responseByteArray = response.ToByteArray();
        var result = new HttpResponseMessage(HttpStatusCode.OK)
        {
           Content = new ByteArrayContent(responseByteArray),
        };
        return result;
    }
}

但是,还要考虑gRPC@MarcGravell 提到的方法(请参阅评论/对话)。

于 2021-09-24T11:14:48.980 回答