Http gRPC with .NET Core and Docker – Error starting gRPC call. System.Net.Http.HttpRequestException: An error occurred while sending the request. —> System.IO.IOException: The response ended prematurely.

Hi everyone,

I’ve been mucking around with gRPC today while using .NET Core and Docker. I have two Microservices in the setup, one server and one client. Because these services will only be communicating internally I intended to use HTTP instead of HTTPS. Unfortunately, I hit the following error while attempting to set this up:

Error starting gRPC call. System.Net.Http.HttpRequestException: An error occurred while sending the request. —> System.IO.IOException: The response ended prematurely.

According Microsoft’s eshoponcontainers documentation there are a few extra steps for getting this to work:

Using gRPC without TLS
gRPC works with HTTP/2 only. Usually when a client connects to a server, the connection is done using HTTP1.1 and promoted to HTTP/2 only if both, server and client, support HTTP/2. This promotion is performed using a protocol negotiation, usually implemented using ALPN protocol which requires TLS.

In order to get it to work you need to add the following to your server :

.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup()

.ConfigureKestrel(options =>
{
options.Listen(IPAddress.Any, 5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
});
});

You then need to explicitly allow HTTP/2 without TLS when creating the client:

AppContext.SetSwitch(“System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport”, true);
AppContext.SetSwitch(“System.Net.Http.SocketsHttpHandler.Http2Support”, true);

// The port number(5001) must match the port of the gRPC server.
var channel = GrpcChannel.ForAddress(endpoint, new GrpcChannelOptions { LoggerFactory = loggerFactory });
var client = new CatalogService.Catalog.CatalogClient(channel);

Note that the AppContext.SetSwitch statements need to appear before the client is created to work. There’s also a bit of an overview on the following page: https://github.com/dotnet-architecture/eShopOnContainers/wiki/gRPC

The following stackoverflow post also helped with the ordering issue: https://stackoverflow.com/a/58053460/522859

eShopOnContainers – No parameterless constructor defined for type dbcontext

Hi everyone,

Another eShopOnContainers post. Today I was setting up migrations and ran into the following error:

Found DbContext ‘CatalogContext’.
Microsoft.EntityFrameworkCore.Design.OperationException: Unable to create an object of type ‘CatalogContext’. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
—> System.MissingMethodException: No parameterless constructor defined for type ‘Catalog.Api.Infrastructure.CatalogContext’.
at System.RuntimeType.CreateInstanceDefaultCtorSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean fillCache)

This turned out to be because I was missing the following from my CatalogContext:

public class CatalogContextDesignFactory : IDesignTimeDbContextFactory
{
public CatalogContext CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder()
.UseSqlServer(“Server=.;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;Integrated Security=true”);

return new CatalogContext(optionsBuilder.Options);
}
}

‘DatabaseFacade’ does not contain a definition for ‘Migrate’ and no accessible extension method ‘Migrate’… – eShopOnContainers

Hi everyone,

I’ve been going through Microsoft’s eShopOnContainers repo and replicating it as a small test project to learn microservices. While adding the WebHost Customization project I ran into the following error: 

Severity Code Description Project File Line Suppression State
Error CS1061 ‘DatabaseFacade’ does not contain a definition for ‘Migrate’ and no accessible extension method ‘Migrate’ accepting a first argument of type ‘DatabaseFacade’ could be found (are you missing a using directive or an assembly reference?) WebHost.Customization … N/A

This turned out to be a fairly simple fix. All that’s required is the following package (I installed via Nuget):

Microsoft.EntityFrameworkCore.SqlServer

Thanks to the following stackoverflow post for the info: https://stackoverflow.com/a/57606203/522859

Return URL is missing path – Azure AD B2C

Hi everyone,

Just a small issue I’ve hit while implementing Azure AD B2C. After logging in Azure has been routing me to the base path instead of including the controller.

The solution to this turned out to be pretty straight-forward. All URLS apparently need to be including in the reply URLs of your Azure AD B2C application.

Just add a new row with the entire url to yours and it should start working immediately.

Thanks,
Chris

Azure AD B2C – Unauthorized

Hi everyone,

I’ve been mucking around with Azure AD B2C. It seems like a pretty good substitute for AWS Cognito that I’ve used previously.

While following the Microsoft sample tutorials I ran into an “unauthorized” error. A value was being returned but no access token was provided.

This seems to be indicative of an issue with scopes. In my case, I’d excluded a trailing slash on the ApiIdentifier url in the TaskWebApp web.config.

This seems to be a fairly common configuration issue. The following stackoverflow post pointed me in the right direction:

https://stackoverflow.com/a/49304044/522859

Relevant tutorial article can be found here: https://docs.microsoft.com/en-au/azure/active-directory-b2c/active-directory-b2c-tutorials-web-api?tabs=applications

Prevent Hot-Chocolate Schema Polling from Spamming Logs – GraphQL

Hi everyone,

I’m currently toying around with GraphQL on with HotChocolate on .NET Core Microservices. After implementing logging I ran into a bit of a problem every time I opened the GraphQL playground.

While observing my logs I noticed that an almost continuous stream of Schema logs were appearing which made it fairly difficult to track down any legitimate errors. The solution to this turned out to be fairly simple – playground offers both a polling enabled and polling frequency setting that can be configured locally:

polling

I simply disabled this for testing, and then increased it to 30s once I’d migrated my logs to seq.

The logging implementation itself was based off the following example: https://chillicream.com/blog/2019/03/19/logging-with-hotchocolate

Thanks,
Chris

error : “Timestamp” is not defined. – .net core and gRPC

Hi everyone,

I’m currently testing out gRPC with .NET Core and hit the following error when attempting to add a timestamp field to my proto file:

error : “Timestamp” is not defined.

My proto file was as follows:

syntax = “proto3”;
import “google/protobuf/timestamp.proto”;

option csharp_namespace = “publisher_api”;

package Weather;

// The weather forecast service definition
service Weather {

// Gets weather forecast
rpc Forecast(WeatherForecastRequest) returns (WeatherForecastResponse);
}

// The request message
message WeatherForecastRequest {

}

// The response message
message WeatherForecastResponse {
timestamp date = 1;
int32 temperatureC = 2;
int32 temperatureF = 3;
string summary = 4;
}

The solution was to fully qualify the timestamp namespace:


message WeatherForecastResponse {
google.protobuf.Timestamp date = 1;
int32 temperatureC = 2;
int32 temperatureF = 3;
string summary = 4;
}

Also ensure that you’ve added the protobuff package:

dotnet add package Google.Protobuf

See the following repo for a full example: https://github.com/Buzzology/microservicesDockerRabbitMQ