You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Forms安卓端无法加载本地ASP.NET API图片求助

解决Xamarin.Forms安卓端无法加载本地HTTPS图片的问题

问题概述

使用Xamarin.Forms 5.0.0.2545从本地ASP.NET API加载HTTPS图片时,PC/手机浏览器、UWP端均能正常访问显示,但安卓自定义应用加载失败,输出窗口报错:

[0:] ImageLoaderSourceHandler: Could not retrieve image or image data was invalid: Uri: https://192.168.0.207:5001/images/festival/dourfestival.jpg

已尝试更换HttpClient实现为Managed、设置SSL/TLS为Native TLS 1.2+、重新安装应用、更新Xamarin.Forms至最新稳定版,问题仍未解决。绑定图片的XAML代码如下:

<Image Source="{Binding Image}" Aspect="AspectFill" HeightRequest="270" Opacity="0.6"/>

排查与解决方法

1. 信任本地自签名SSL证书

本地ASP.NET API通常使用自签名证书,安卓系统默认不信任这类证书,需手动添加信任:

  • 导出API的SSL证书(格式为.cer),放入安卓项目的Resources/raw文件夹(无此文件夹则新建),设置文件的Build Action为AndroidResource。
  • 在安卓项目的MainActivity.cs中添加证书信任逻辑:
    protected override void OnCreate(Bundle savedInstanceState)
    {
        // 保留原有初始化代码
        ConfigureCertificateTrust();
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        LoadApplication(new App());
    }
    
    private void ConfigureCertificateTrust()
    {
        var certificateFactory = CertificateFactory.GetInstance("X.509");
        using (var certStream = Resources.OpenRawResource(Resource.Raw.your_certificate_name))
        {
            var certificate = certificateFactory.GenerateCertificate(certStream);
            var trustManagerFactory = TrustManagerFactory.GetInstance(TrustManagerFactory.DefaultAlgorithm);
            var keyStore = KeyStore.GetInstance(KeyStore.DefaultType);
            keyStore.Load(null);
            keyStore.SetCertificateEntry("local_api_cert", certificate);
            trustManagerFactory.Init(keyStore);
            var sslContext = SSLContext.GetInstance("TLS");
            sslContext.Init(null, trustManagerFactory.GetTrustManagers(), new SecureRandom());
            SSLContext.Default = sslContext;
        }
    }
    
    注意将your_certificate_name替换为实际证书文件名(无需带.cer后缀)。

2. 配置安卓网络安全策略

在安卓项目的Resources/xml文件夹下创建network_security_config.xml文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">192.168.0.207</domain>
        <trust-anchors>
            <certificates src="@raw/your_certificate_name"/>
        </trust-anchors>
    </domain-config>
</network-security-config>

随后在AndroidManifest.xml的application标签中添加配置引用:

<application android:networkSecurityConfig="@xml/network_security_config">
    <!-- 保留原有应用配置 -->
</application>

该配置允许指定域名的明文流量(若需要),并信任你的自签名证书。

3. 验证图片绑定格式

确保Image绑定的属性是完整的HTTPS Uri字符串,或是UriImageSource类型:

// 字符串格式
public string Image { get; set; } = "https://192.168.0.207:5001/images/festival/dourfestival.jpg";

// 或者UriImageSource类型
public UriImageSource Image { get; set; } = new UriImageSource
{
    Uri = new Uri("https://192.168.0.207:5001/images/festival/dourfestival.jpg"),
    CachingEnabled = true
};

4. 检查安卓网络权限

确认AndroidManifest.xml中已添加必要的网络权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

5. 临时绕过证书验证(仅测试环境)

若处于测试阶段,可临时绕过SSL验证(生产环境绝对禁止使用):
在安卓项目中添加以下自定义HttpClientHandler:

public class UnsafeHttpClientHandler : HttpClientHandler
{
    protected override SSLSocketFactory CreateSSLSocketFactory()
    {
        try
        {
            var sslContext = SSLContext.GetInstance("TLS");
            sslContext.Init(null, new[] { new UnsafeTrustManager() }, new SecureRandom());
            return sslContext.SocketFactory;
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException("Failed to create SSL socket factory", ex);
        }
    }
}

public class UnsafeTrustManager : Java.Lang.Object, ITrustManager
{
    public void CheckClientTrusted(Java.Security.Cert.X509Certificate[] chain, string authType) { }
    public void CheckServerTrusted(Java.Security.Cert.X509Certificate[] chain, string authType) { }
    public Java.Security.Cert.X509Certificate[] GetAcceptedIssuers() => new Java.Security.Cert.X509Certificate[0];
}

之后在Xamarin.Forms中初始化HttpClient时使用该Handler:

var httpClient = new HttpClient(new UnsafeHttpClientHandler());

内容的提问来源于stack exchange,提问作者Iwert Derycke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 20:16:06