Skip to content

WebResourceRequested API Review Spec

Diana Qu edited this page Aug 11, 2020 · 7 revisions

Background

In response to a high volume of user feedback and bug reports, the WebView2 team re-investigated the implementation of the Web Resource Requested event for WebView2 on .NET. The investigation showed that the .NET types: HttpRequestMessage and HttpResponseMessage don’t have parity with COM’s WebResourceRequested and WebResource Response interfaces, specifically for non-http URIs. Therefore, instead of converting COM types to the existing .NET HTTPRequestMessage and HttpResponseMessage types, the COM types will be exposed directly.

In this document we describe the updated API. We'd appreciate your feedback.

Description

The WebResourceRequested event fires when the WebView is performing an HTTP request to a matching URL and resource context filter that was added with AddWebResourceRequestedFilter.

We have modified CoreWebView2HttpRequest, CoreWebView2HttpResponse API and its corresponding CoreWebView2HttpRequestHeaders, CoreWebView2HttpResponseHeaders and CoreWebView2HttpHeadersCollectionIterator behaviors.

Examples

The following code snippet demonstrates how to use the updated WebResourceRequested API:

// Note: The COM types WebResourceRequested are exposed rather than HttpRequestMessage
this.webView2Control.CoreWebView2.WebResourceRequested += CoreWebView2_WebResourceRequested;
this.webView2Control.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.Image);

// Note: You must create a custom environment to create custom WebResourceResponse
private async void CreateEnvironment()
{
    var environment = await CoreWebView2Environment.CreateAsync();
    await this.webView2Control.EnsureCoreWebView2Async(environment);
    Environment = environment;
    this.webView2Control.Source = new Uri("https://www.bing.com/");
}

private void CoreWebView2_WebResourceRequested(object sender, CoreWebView2WebResourceRequestedEventArgs e)
{
    // Set and access the header
    DateTimeOffset value = DateTimeOffset.UtcNow;
    e.Request.Headers.SetHeader("Date", value.ToString());
    var addedDate = e.Request.Headers.GetHeader("Date");
            
    // e.Request.Headers is enumerable
    foreach(var current in e.Request.Headers)
    Console.WriteLine(current);

    // Create response object for custom response and set it
    CoreWebView2WebResourceResponse response = Environment.CreateWebResourceResponse(null, 403, "Blocked", "");
    e.Response = response;

    // statusCode will now be accessible and equal to 403
    var code = e.Response.StatusCode;
}

Remarks

Because the COM API does not have Reset support, based on IEnumerator.Reset Method, NotSupportedException() will be thrown.

API Notes

Below is a more detailed list of the changes to the API surface:

// Return type of EventArgs.Request and EventArgs.Response changed from existing .NET types to custom types
WebResourceRequestedEventArgs.Request: HttpRequestMessage => CoreWebView2WebResourceRequest
WebResourceRequestedEventArgs.Response: HttpResponseMessage => CoreWebView2WebResourceResponse
CoreWebView2NavigationStartingEventArgs.RequestHeaders: HttpRequestHeaders => CoreWebView2HttpRequestHeaders

// Corresponding Request properties changed from existing HttpRequestMessage properites to custom properties
HttpRequestMessage.RequestUri => CoreWebView2WebResourceRequest.Uri
HttpRequestMessage.Method => CoreWebView2WebResourceRequest.Method
HttpRequestMessage.Content => CoreWebView2WebResourceRequest.Content
HttpRequestMessage.Headers => CoreWebView2WebResourceRequest.Headers  (return type HttpRequestHeaders => CoreWebView2HttpRequestHeaders)

// Corresponding Response properties changed from existing HttpResponseMessage properites to custom properties
HttpResponseMessage.Content => CoreWebView2WebResourceResponse.Content
HttpResponseMessage.Headers => CoreWebView2WebResourceResponse.Headers (return type HttpResponseHeaders => CoreWebView2HttpResponseHeaders)
HttpResponseMessage.StatusCode => CoreWebView2WebResourceResponse.StatusCode
HttpResponseMessage.ReasonPhrase => CoreWebView2WebResourceResponse.ReasonPhrase

// Corresponding Request Header properties changed from HttpRequestHeaders properties to custom properties 
HttpRequestHeaders.GetValues => CoreWebView2HttpRequestHeaders.GetHeader
HttpRequestHeaders.Contains => CoreWebView2HttpRequestHeaders.Contains
HttpRequestHeaders.Add => CoreWebView2HttpRequestHeaders.SetHeader
HttpRequestHeaders.Remove => CoreWebView2HttpRequestHeaders.RemoveHeader
HttpRequestHeaders.GetEnumerator => CoreWebView2HttpRequestHeaders.GetEnumerator (return type HttpHeaders => CoreWebView2HttpHeadersCollectionIterator)

// Corresponding Response Header properties changed from HttpResponseHeaders properties to custom properties 
HttpResponseHeaders.Add => CoreWebView2HttpResponseHeaders.AppendHeader
HttpResponseHeaders.Contains => CoreWebView2HttpResponseHeaders.Contains
HttpResponseHeaders.GetValues => CoreWebView2HttpResponseHeaders.GetHeader
HttpResponseHeaders.GetEnumerator => CoreWebView2HttpResponseHeaders.GetEnumerator (return type HttpHeaders => CoreWebView2HttpHeadersCollectionIterator)

API Details

namespace Microsoft.Web.WebView2.Core
{
    // Generated from COM, Please refer to COM documentation for details
    public partial class CoreWebView2WebResourceRequest
    {
        public string Uri { get; set; };
        public string Method { get; set; };
        public Stream Content { get; set; };
        public CoreWebView2HttpRequestHeaders Headers { get; };
    }

    // Generated from COM, Please refer to COM documentation for details
    public partial class CoreWebView2WebResourceResponse
    {
        public Stream Content { get; set; };
        public CoreWebView2HttpResponseHeaders Headers { get; };
        public int StatusCode { get; set; };
        public string ReasonPhrase { get; set; };
    }

    // Generated from COM, Please refer to COM documentation for details
    public partial class CoreWebView2Environment
    {
        public CoreWebView2WebResourceResponse CreateWebResourceResponse(Stream Content, int StatusCode, string ReasonPhrase, string Headers);
    }
    
    // Generated from COM, Please refer to COM documentation for details
    public partial class CoreWebView2HttpResponseHeaders
    {
        public void AppendHeader(string name, string value);
        public bool Contains(string name);
        public string GetHeader(string name);
        public CoreWebView2HttpHeadersCollectionIterator GetHeaders(string name);
        public CoreWebView2HttpHeadersCollectionIterator GetIterator();
    }

    // Generated from COM, Please refer to COM documentation for details
    public partial class CoreWebView2HttpRequestHeaders
    {
        public void SetHeader(string name, string value);
        public void RemoveHeader(string name);
        public bool Contains(string name);
        public string GetHeader(string name);
        public CoreWebView2HttpHeadersCollectionIterator GetHeaders(string name);
        public CoreWebView2HttpHeadersCollectionIterator GetIterator();
    }

    // Generated from COM, Please refer to COM documentation for details
    public partial class CoreWebView2HttpHeadersCollectionIterator
    {
        public bool HasCurrentHeader;
        public bool MoveNext();
        private void GetCurrentHeader(out string name, out string value); // Note: developer should instead call Current to get the current header
    }

    public partial class CoreWebView2HttpRequestHeaders : IEnumerable
    {
        CoreWebView2HttpHeadersCollectionIterator GetEnumerator();
    }

    public partial class CoreWebView2HttpResponseHeaders : IEnumerable
    {
        CoreWebView2HttpHeadersCollectionIterator GetEnumerator();
    }

    public partial class CoreWebView2HttpHeadersCollectionIterator : IEnumerator
    {
        void Reset();
        KeyValuePair<string, string> Current;
    }
}
Clone this wiki locally