Skip to main content
All docs
V24.2

Suppress Control Requests to Download Data from External URLs

  • 6 minutes to read

Certain DevExpress UI controls can download data over the internet. For example, the Map Control can download terrain data and the WinForms PictureEdit can download images passed as URLs to the PictureEdit.LoadAsync(String) method. These requests can be initiated in your code or via the internal control engine.

This topic explains how to spot, analyze, and prohibit unwanted download requests.

Apply Global Download Restrictions

The default security policy does not limit web connections. Call one of the following DevExpress.Data.AsyncDownloadPolicy methods at application startup to apply a restrictive policy:

  • SuppressAll – Suppresses all downloads.
  • ThrowAlways – Throws an exception when a control initiates a download.
static void Main() {
    DevExpress.Data.AsyncDownloadPolicy.SuppressAll();  
    Application.Run(new Form1());  
}  

Trusted Resources

If a restrictive download policy is active, you may want to create a “safe” resource whitelist. Downloads from whitelist resources bypass policy restrictions. To “trust’ a specific resource, call the static RegisterTrustedUri method:

static void Main() {  
    DevExpress.Data.AsyncDownloadPolicy.SuppressAll();
    DevExpress.Data.AsyncDownloadPolicy.RegisterTrustedUri(new Uri("https://www.devexpress.com"));
    Application.Run(new Form1());  
}  

Note

Masked resource registration is not available. If you require to validate various requests made to the same host, apply the SuppressAll policy and handle the Downloading event to manually inspect each connection.

Track Control Actions

To track user/app initiated downloads and execute custom actions in response, handle the following DevExpress.Data.AsyncDownloadPolicy events. These events can be raised in a separate thread.

The “Probing” Event

The Probing event allows you to spot the probing of external resources before an actual attempt to download data.

void OnProbing(object sender, ProbingEventArgs e) {
    var shouldClose = XtraMessageBox.Show("Notification",
        "Probing the " + e.Uri.AbsoluteUri + " URL was detected. Close the connection?",
        MessageBoxButtons.YesNo);
    e.Cancel = (shouldClose == DialogResult.Yes) ? true : false;
}

The “Downloading” Event

Downloading is a cancelable event that allows you to spot an initiated download, check connection parameters, and cancel (or allow, if the SupressAll policy is active) the operation.

void OnDownloading(object sender, DownloadingEventArgs e) {
    e.Cancel = !e.Uri.AbsoluteUri.StartsWith(@"https://www.devexpress.com");
}

Tip

Different DevExpress UI components with the same functionality (for example, separate PictureEdit controls that load images from URI paths) utilize the same HttpClient. As a result, the event’s e.ValueType parameter is the same for all individual controls (for aforementioned PictureEdit controls, ValueType returns ImageOrSvgImageResult). This technique allows you to identify the group of controls to which an individual control (that initiated the download) belongs.

public Form1() {
    InitializeComponent();
    AsyncDownloadPolicy.Downloading += AsyncDownloadPolicy_Downloading;
}
Dictionary<int, string> whitelist = new Dictionary<int, string>() {
    { 0, "www.devexpress.com" },
    { 1, "community.devexpress.com" },
    { 2, "docs.devexpress.com" },
    { 3, "supportcenter.devexpress.com" }
};
private void AsyncDownloadPolicy_Downloading(object sender, AsyncDownloadPolicy.DownloadingEventArgs e) {
    string result = e.ValueType.Name;
    // Checks whether a picture editor initiated the download.
    if(result == "ImageOrSvgImageResult")
        // Cancels downloading from domains that are not in the white list.
        e.Cancel = !whitelist.Values.Contains(e.Uri.Authority);
}
private void loadImageButton_Click(object sender, EventArgs e) {
    pictureEdit1.LoadAsync(/* YOUR_URL */);
}  

The “Downloaded” Event

If you did not cancel a download on the Downloading event, the notification Downloaded event fires once the download has completed.

void OnDownloaded(object sender, DownloadedEventArgs e) {
    // Log.WriteMessage("Data from " + e.Uri.AbsoluteUri + " was downloaded");
}

The “Failed” Event

The AsyncDownloadPolicy.Failed event occurs if an external resource fails to load. Handle the Failed event to supply the content instead of the resource that could not be loaded or throw an exception.

Use the e.Content event parameter to specify the content instead of an external resource that fails to load. Call the e.Throw() method to throw an exception.

The following example handles the Failed event to display a placeholder image in a WinForms PictureEdit if an external image fails to load:

AsyncDownloadPolicy Failed Event - WinForms PictureEdit

public Form1() {
    InitializeComponent();
    DevExpress.Data.AsyncDownloadPolicy.Failed += AsyncDownloadPolicy_Failed;
}

void AsyncDownloadPolicy_Failed(object sender, DevExpress.Data.AsyncDownloadPolicy.FailedEventArgs e) {
    if (e.ValueType.Name == "ImageOrSvgImageResult") {
        MemoryStream stream = new MemoryStream();
        /* A placeholder image is obtained from the DevExpress SvgImageCollection.
         * The placeholder image was added to the SvgImageCollection at design time.
         */
        var errorImage = svgImageCollection1[0];
        errorImage.Save(stream);
        e.Content = stream;
    }
}

async void btnLoadImage_Click(object sender, EventArgs e) {
    await pictureEdit1.LoadAsync("EXTERNAL_IMAGE_URL");
}

Custom HTTP Client Parameters

You can handle the ConfigureHttpClient client to customize settings of a standard System.Net.Http.HttpClient component that DevExpress components use to download data: the default proxy, base address, cache size, and more.

For example, the default buffer size of an HttpClient is 2 gigabytes. PictureEdit controls reduce this size to 4096 bytes. If you attempt to download a larger image, the following code…

async void OnFormLoad(object sender, EventArgs e) {
    await pictureEdit1.LoadAsync("...");
}

…fires the “System.Net.Http.HttpRequestException: Cannot write more bytes to the buffer than the configured maximum buffer size: 4194304” exception. The following sample illustrates how to raise this limit to 16MB.

void OnConfigureHttpClient(object sender, ConfigureHttpClientEventArgs e) {
    e.Client.MaxResponseContentBufferSize = 1024*1024*16;
}

You can also modify values for the static AsyncDownloadPolicy class constants. Do so if you wish to set a global limit that can be changed within the ConfigureHttpClient event for individual controls.

DevExpress.Data.AsyncDownloadPolicy.DefaultResponseContentBufferSizeForHttpClient  = 1024 * 1024 * 4; // 4MB
DevExpress.Data.AsyncDownloadPolicy.DefaultBufferSizeForContentCopy = 1024 * 16; // 16KB