diff --git a/aspnetcore/grpc/browser.md b/aspnetcore/grpc/browser.md index e8ef17f0e3..2adc707fdd 100644 --- a/aspnetcore/grpc/browser.md +++ b/aspnetcore/grpc/browser.md @@ -4,7 +4,7 @@ author: jamesnk description: Learn how to configure gRPC services on ASP.NET Core to be callable from browser apps using gRPC-Web. monikerRange: '>= aspnetcore-3.0' ms.author: jamesnk -ms.date: 02/16/2020 +ms.date: 04/15/2020 uid: grpc/browser --- # Use gRPC in browser apps @@ -23,6 +23,15 @@ By [James Newton-King](https://twitter.com/jamesnk) It is not possible to call a HTTP/2 gRPC service from a browser-based app. [gRPC-Web](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md) is a protocol that allows browser JavaScript and Blazor apps to call gRPC services. This article explains how to use gRPC-Web in .NET Core. +## gRPC-Web in ASP.NET Core vs. Envoy + +There are two choices for how to add gRPC-Web to an ASP.NET Core app: + +* Support gRPC-Web alongside gRPC HTTP/2 in ASP.NET Core. This option uses middleware provided by the `Grpc.AspNetCore.Web` package. +* Use the [Envoy proxy's](https://www.envoyproxy.io/) gRPC-Web support to translate gRPC-Web to gRPC HTTP/2. The translated call is then forwarded onto the ASP.NET Core app. + +There are pros and cons to each approach. If you're already using Envoy as a proxy in your app's environment, it might make sense to also use it to provide gRPC-Web support. If you want a simple solution for gRPC-Web that only requires ASP.NET Core, `Grpc.AspNetCore.Web` is a good choice. + ## Configure gRPC-Web in ASP.NET Core gRPC services hosted in ASP.NET Core can be configured to support gRPC-Web alongside HTTP/2 gRPC. gRPC-Web does not require any changes to services. The only modification is startup configuration. @@ -94,7 +103,7 @@ The preceding code: The `GrpcWebHandler` has the following configuration options when created: * **InnerHandler**: The underlying that makes the gRPC HTTP request, for example, `HttpClientHandler`. -* **Mode**: An enumeration type that specifies whether the gRPC HTTP request request `Content-Type` is `application/grpc-web` or `application/grpc-web-text`. +* **Mode**: An enumeration type that specifies whether the gRPC HTTP request `Content-Type` is `application/grpc-web` or `application/grpc-web-text`. * `GrpcWebMode.GrpcWeb` configures content to be sent without encoding. Default value. * `GrpcWebMode.GrpcWebText` configures content to be base64 encoded. Required for server streaming calls in browsers. * **HttpVersion**: HTTP protocol `Version` used to set [HttpRequestMessage.Version](xref:System.Net.Http.HttpRequestMessage.Version) on the underlying gRPC HTTP request. gRPC-Web doesn't require a specific version and doesn't override the default unless specified. diff --git a/aspnetcore/grpc/configuration.md b/aspnetcore/grpc/configuration.md index df064c3965..c38d646134 100644 --- a/aspnetcore/grpc/configuration.md +++ b/aspnetcore/grpc/configuration.md @@ -16,8 +16,8 @@ gRPC services are configured with `AddGrpc` in *Startup.cs*. The following table | Option | Default Value | Description | | ------ | ------------- | ----------- | -| MaxSendMessageSize | `null` | The maximum message size in bytes that can be sent from the server. Attempting to send a message that exceeds the configured maximum message size results in an exception. | -| MaxReceiveMessageSize | 4 MB | The maximum message size in bytes that can be received by the server. If the server receives a message that exceeds this limit, it throws an exception. Increasing this value allows the server to receive larger messages, but can negatively impact memory consumption. | +| MaxSendMessageSize | `null` | The maximum message size in bytes that can be sent from the server. Attempting to send a message that exceeds the configured maximum message size results in an exception. When set to `null`, the message size is unlimited. | +| MaxReceiveMessageSize | 4 MB | The maximum message size in bytes that can be received by the server. If the server receives a message that exceeds this limit, it throws an exception. Increasing this value allows the server to receive larger messages, but can negatively impact memory consumption. When set to `null`, the message size is unlimited. | | EnableDetailedErrors | `false` | If `true`, detailed exception messages are returned to clients when an exception is thrown in a service method. The default is `false`. Setting `EnableDetailedErrors` to `true` can leak sensitive information. | | CompressionProviders | gzip | A collection of compression providers used to compress and decompress messages. Custom compression providers can be created and added to the collection. The default configured providers support **gzip** compression. | | ResponseCompressionAlgorithm | `null` | The compression algorithm used to compress messages sent from the server. The algorithm must match a compression provider in `CompressionProviders`. For the algorithm to compress a response, the client must indicate it supports the algorithm by sending it in the **grpc-accept-encoding** header. | @@ -41,8 +41,8 @@ gRPC client configuration is set on `GrpcChannelOptions`. The following table de | HttpClient | New instance | The `HttpClient` used to make gRPC calls. A client can be set to configure a custom `HttpClientHandler`, or add additional handlers to the HTTP pipeline for gRPC calls. If no `HttpClient` is specified, then a new `HttpClient` instance is created for the channel. It will automatically be disposed. | | DisposeHttpClient | `false` | If `true`, and an `HttpClient` is specified, then the `HttpClient` instance will be disposed when the `GrpcChannel` is disposed. | | LoggerFactory | `null` | The `LoggerFactory` used by the client to log information about gRPC calls. A `LoggerFactory` instance can be resolved from dependency injection or created using `LoggerFactory.Create`. For examples of configuring logging, see . | -| MaxSendMessageSize | `null` | The maximum message size in bytes that can be sent from the client. Attempting to send a message that exceeds the configured maximum message size results in an exception. | -| MaxReceiveMessageSize | 4 MB | The maximum message size in bytes that can be received by the client. If the client receives a message that exceeds this limit, it throws an exception. Increasing this value allows the client to receive larger messages, but can negatively impact memory consumption. | +| MaxSendMessageSize | `null` | The maximum message size in bytes that can be sent from the client. Attempting to send a message that exceeds the configured maximum message size results in an exception. When set to `null`, the message size is unlimited. | +| MaxReceiveMessageSize | 4 MB | The maximum message size in bytes that can be received by the client. If the client receives a message that exceeds this limit, it throws an exception. Increasing this value allows the client to receive larger messages, but can negatively impact memory consumption. When set to `null`, the message size is unlimited. | | Credentials | `null` | A `ChannelCredentials` instance. Credentials are used to add authentication metadata to gRPC calls. | | CompressionProviders | gzip | A collection of compression providers used to compress and decompress messages. Custom compression providers can be created and added to the collection. The default configured providers support **gzip** compression. | diff --git a/aspnetcore/mvc/views/view-compilation.md b/aspnetcore/mvc/views/view-compilation.md index a6d1d92bc3..0238c6bfa9 100644 --- a/aspnetcore/mvc/views/view-compilation.md +++ b/aspnetcore/mvc/views/view-compilation.md @@ -4,7 +4,7 @@ author: rick-anderson description: Learn how compilation of Razor files occurs in an ASP.NET Core app. ms.author: riande ms.custom: mvc -ms.date: 04/13/2020 +ms.date: 04/14/2020 uid: mvc/views/view-compilation --- # Razor file compilation in ASP.NET Core @@ -77,13 +77,23 @@ In the following example, runtime compilation is enabled in the Development envi No code changes are needed in the project's `Startup` class. At runtime, ASP.NET Core searches for an [assembly-level HostingStartup attribute](xref:fundamentals/configuration/platform-specific-configuration#hostingstartup-attribute) in `Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation`. The `HostingStartup` attribute specifies the app startup code to execute. That startup code enables runtime compilation. +## Enable runtime compilation for a Razor Class Library + +Consider a scenario in which a Razor Pages project references a [Razor Class Library (RCL)](xref:razor-pages/ui-class) named *MyClassLib*. The RCL contains a *_Layout.cshtml* file that all of your team's MVC and Razor Pages projects consume. You want to enable runtime compilation for the *_Layout.cshtml* file in that RCL. Make the following changes in the Razor Pages project: + +1. Enable runtime compilation with the instructions at [Conditionally enable runtime compilation in an existing project](#conditionally-enable-runtime-compilation-in-an-existing-project). +1. Configure the runtime compilation options in `Startup.ConfigureServices`: + + [!code-csharp[](~/mvc/views/view-compilation/samples/3.1/Startup.cs?name=snippet_ConfigureServices&highlight=5-10)] + + In the preceding code, an absolute path to the *MyClassLib* RCL is constructed. The [PhysicalFileProvider API](xref:fundamentals/file-providers#physicalfileprovider) is used to locate directories and files at that absolute path. Finally, the `PhysicalFileProvider` instance is added to a file providers collection, which allows access to the RCL's *.cshtml* files. + ## Additional resources * [RazorCompileOnBuild and RazorCompileOnPublish](xref:razor-pages/sdk#properties) properties. * * * -* See the [runtime compilation sample on GitHub](https://github.com/aspnet/samples/tree/master/samples/aspnetcore/mvc/runtimecompilation) for a sample that shows making runtime compilation work across projects. ::: moniker-end diff --git a/aspnetcore/mvc/views/view-compilation/samples/3.1/Startup.cs b/aspnetcore/mvc/views/view-compilation/samples/3.1/Startup.cs new file mode 100644 index 0000000000..2e407d1ac3 --- /dev/null +++ b/aspnetcore/mvc/views/view-compilation/samples/3.1/Startup.cs @@ -0,0 +1,65 @@ +using System.IO; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Hosting; + +namespace MyApp +{ + public class Startup + { + public Startup(IConfiguration configuration, IWebHostEnvironment env) + { + Configuration = configuration; + HostEnvironment = env; + } + + public IConfiguration Configuration { get; } + + public IWebHostEnvironment HostEnvironment { get; } + + #region snippet_ConfigureServices + public void ConfigureServices(IServiceCollection services) + { + services.AddRazorPages(); + + services.Configure(options => + { + var libraryPath = Path.GetFullPath( + Path.Combine(HostEnvironment.ContentRootPath, "..", "MyClassLib")); + options.FileProviders.Add(new PhysicalFileProvider(libraryPath)); + }); + } + #endregion + + public void Configure(IApplicationBuilder app) + { + if (HostEnvironment.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + app.UseExceptionHandler("/Home/Error"); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); + } + app.UseHttpsRedirection(); + app.UseStaticFiles(); + + app.UseRouting(); + + app.UseAuthorization(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllerRoute( + name: "default", + pattern: "{controller=Home}/{action=Index}/{id?}"); + }); + } + } +}