Example #1
0
    protected async Task ExecuteAsync(
        ViewContext viewContext,
        string?contentType,
        int?statusCode)
    {
        if (viewContext == null)
        {
            throw new ArgumentNullException(nameof(viewContext));
        }

        var response = viewContext.HttpContext.Response;

        ResponseContentTypeHelper.ResolveContentTypeAndEncoding(
            contentType,
            response.ContentType,
            (DefaultContentType, Encoding.UTF8),
            MediaType.GetEncoding,
            out var resolvedContentType,
            out var resolvedContentTypeEncoding);

        response.ContentType = resolvedContentType;

        if (statusCode != null)
        {
            response.StatusCode = statusCode.Value;
        }

        OnExecuting(viewContext);

        await using (var writer = WriterFactory.CreateWriter(response.Body, resolvedContentTypeEncoding))
        {
            var view = viewContext.View;

            var oldWriter = viewContext.Writer;
            try
            {
                viewContext.Writer = writer;

                DiagnosticListener.BeforeView(view, viewContext);

                await view.RenderAsync(viewContext);

                DiagnosticListener.AfterView(view, viewContext);
            }
            finally
            {
                viewContext.Writer = oldWriter;
            }

            // Perf: Invoke FlushAsync to ensure any buffered content is asynchronously written to the underlying
            // response asynchronously. In the absence of this line, the buffer gets synchronously written to the
            // response as part of the Dispose which has a perf impact.
            await writer.FlushAsync();
        }
    }