Do you like WCF-like approach and need to cover communication in between ASP.NET Core service and Blazor WebAssembly client? Use code-first with gRPC-Web! You can try the it right now by following a few simple steps (commit):
Add NuGet packages:
- Grpc.AspNetCore.Web (prerelease)
- protobuf-net.Grpc.AspNetCore
Register CodeFirstGrpc()
and GrpcWeb()
services in Startup.cs
ConfigureServices() method:
services.AddCodeFirstGrpc(config => { config.ResponseCompressionLevel = System.IO.Compression.CompressionLevel.Optimal; });
services.AddGrpcWeb(options => { options.GrpcWebEnabled = true; }
Add GrpcWeb
middleware in between UseRouting()
and UseEndpoints()
:
app.UseGrpcWeb();
Add System.ServiceModel.Primitives NuGet package.
Define the interface of your service:
[ServiceContract]
public interface IMyService
{
Task DoSomething(MyServiceRequest request);
}
[DataContract]
public class MyServiceResult
{
[DataMember(Order = 1)]
public string NewText { get; set; }
[DataMember(Order = 2)]
public int NewValue { get; set; }
}
[DataContract]
public class MyServiceRequest
{
[DataMember(Order = 1)]
public string Text { get; set; }
[DataMember(Order = 2)]
public int Value { get; set; }
}
Implement your service:
public class MyService : IMyService
{
public Task DoSomething(MyServiceRequest request)
{
return Task.FromResult(new MyServiceResult()
{
NewText = request.Text + " from server",
NewValue = request.Value + 1
});
}
}
Publish the service in Startup.cs
:
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<MyService>();
// ...
}
Add NuGet packages:
- Grpc.Net.Client
- Grpc.Net.Client.Web (prerelease)
- protobuf-net.Grpc
Consume the service in your razor file:
var handler = new Grpc.Net.Client.Web.GrpcWebHandler(Grpc.Net.Client.Web.GrpcWebMode.GrpcWeb, new HttpClientHandler());
using (var channel = Grpc.Net.Client.GrpcChannel.ForAddress("https://localhost:44383/", new Grpc.Net.Client.GrpcChannelOptions() { HttpClient = new HttpClient(handler) }))
{
var testFacade = channel.CreateGrpcService<IMyService>();
this.result = await testFacade.DoSomething(request);
}
(You can move the plumbing to ConfigureServices()
as a factory and use pure dependency injection in your razor files.)