Reputation: 4906
I have a *.proto
file that defines two messages: MyRequest
and MyResponse
. This is defined in a common .NET Standard 2.0 library and uses the following NuGet packages:
<PackageReference Include="Google.Protobuf" Version="3.18.0" />
<PackageReference Include="Grpc" Version="2.40.0" />
<PackageReference Include="Grpc.Tools" Version="2.40.0">
I have a .NET Framework (4.8) WebAPI and the following Action Method:
[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);
}
}
So this successfully receives a MyRequest
object sent via HttpPost, and based on the data in that object, generates a MyResponse
object and returns that.
I have a .Net 5 client that consumes this service with an HttpClient:
// 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);
The HttpClient "Blah" is only configured with a base URL and security token.
However....when I call the ParseFrom
on the last line I get the following exception:
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 ....
Not sure how to solve this one...
Upvotes: 1
Views: 500
Reputation: 4906
I solved the problem I was facing by changing the .NET Framework (4.8) Server's method:
[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;
}
}
However, also considering the gRPC
approach mentioned by @MarcGravell (see comments/conversation).
Upvotes: 0