【问题标题】:Load Remote Authenticated Image in WinRT/UWP在 WinRT/UWP 中加载远程认证图像
【发布时间】:2015-10-03 02:10:53
【问题描述】:

我正在尝试在 XAML 中加载需要身份验证标头才能成功下载的远程图像。

目前我正在使用自己的缓存服务,我使用 HttpClient 下载图像并将文件存储到磁盘。在后续加载时,我只是将图像绑定到缓存文件的绝对文件路径,如下所示:

              <Image Width="50"
                   Height="50"
                   Stretch="UniformToFill"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center"
                   Source="{Binding CachedImagePath}"/>

这可行,但是我对从文件加载图像所花费的时间不太满意。它似乎比我使用 XAML 缓存要慢得多。

所以我的问题是:

1) 当我将图像绑定到远程 URI 时,有没有办法传递身份验证标头?

2) 如果没有,您能否推荐一种从磁盘加载图像比我目前拥有的方式更快的方法?

【问题讨论】:

    标签: c# xaml windows-runtime uwp


    【解决方案1】:

    Windows Community Toolkit 包含一个 ImageEx 控件,可用于管理远程图像的本地缓存和 UI 中图像的异步加载。

    作为他们如何实现图像下载的副作用,我们可以访问它使用的静态 HttpClient 实例,并使用您的 API 可能需要的身份验证或其他标头设置 DefaultRequestHeaders

    如果您的所有图像都托管在同一个经过身份验证的服务器上,则此解决方案有效,该工具包是开源的,因此您可以下载源代码并根据自己的需要更改实现。

    ImageEx 控件在加载图像时管理可见状态,默认情况下带有漂亮的淡入淡出动画,但是您可以覆盖它,甚至提供PlaceHolder 图像或文本。

    • 一种高级方案是使用PlaceHolder 首先渲染可能被积极缓存的图像的低分辨率版本。这超出了本文的范围,但强调了此解决方案的可扩展性。

    魔术发生在这个控件使用的ImageCache内部,我们可以通过将EnableLazyLoadingIsCacheEnabled属性都设置为True来强制使用ImageCache,只要我们之前设置了请求头图片加载完毕后,我们可以直接将Source绑定到外部URL来访问文件。

    xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
    
    <controls.ImageEx Width="50"
                      Height="50"
                      Stretch="UniformToFill"
                      HorizontalAlignment="Center"
                      VerticalAlignment="Center"
    
                      EnableLazyLoading="True"
                      IsCacheEnabled="True"
                      Source="{Binding ImageUrl}" />
    

    此行为未明确记录,通过使用反射访问内部 HttpClient,我们接受在未来版本中可能无法正常工作的风险。

    理想情况下,由于 ImageCache.Instance 是静态成员,我们只需要在用户登录时设置 Auth 头,以下代码显示了如何使用任意头来做到这一点:

    // set the auth header on the Image Cache!
    var httpClient = ImageCache.Instance
                               .GetType()
                               .GetProperty("HttpClient", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.NonPublic)
                               .GetValue(ImageCache.Instance)
                               as System.Net.Http.HttpClient;
            Runtime.ConfigureHttpClient(httpClient);
    
    httpClient.DefaultRequestHeaders.Authorization = 
        new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "---MyUserAuthToken---");
    httpClient.DefaultRequestHeaders.Add("My-Token", "---arbitrary token---");
    

    运行时性能很好,但你可以配置ImageCache在内存中保留一些图像,或者我们可以显式或预先加载图像:

    在下文中,假设item 是一个数据对象,它具有一个ImageUrl,其中包含一个需要身份验证的资源的URL。

    // Define max memory cache size
    ImageCache.Instance.MaxMemoryCacheCount = 200;
    
    // Precache data and save it in memory
    await ImageCache.Instance.PreCacheAsync(new Uri(item.ImageUrl), Path.GetFileName(item.Thumbnail), true);
    
    // Precache data and save it in on local hard drive
    await ImageCache.Instance.PreCacheAsync(new Uri(item.ImageUrl), Path.GetFileName(item.Thumbnail), false);
    
    // Clear cache
    await ImageCache.Instance.ClearAsync();
    

    【讨论】:

      【解决方案2】:

      这可以通过实现IWeRequestCreate 来实现。您可能需要通过添加已实现接口的类详细信息来更改 app.config 文件。

      因此,每当创建 webrequest 时,它将通过此​​自定义实现,您可以在那里传递身份验证标头,因为 HttpWeRequest 包含属性 Header

      更多详情请查看post

      【讨论】:

      • WinRT/UWP 应用实际上不可能。
      猜你喜欢
      • 2020-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多