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

Xamarin 4中ADAL组件实现及编译类型转换错误解决问询

解决Xamarin中ADAL 5.1.0的PlatformParameters参数错误问题

你遇到的这个错误是因为ADAL 5.x版本对Xamarin平台的PlatformParameters构造函数做了更新,原来直接传PromptBehavior的方式已经不再适用了——现在它需要你传入当前平台的界面上下文(Android的Activity或iOS的UIViewController),而不是枚举值,所以才会出现类型转换失败的问题。

下面是具体的解决步骤和修改后的代码:

核心问题分析

在ADAL 5.1.0中,针对Xamarin跨平台场景,PlatformParameters的构造函数已经弃用了接受PromptBehavior的重载,转而要求传入当前的界面上下文实例,因为身份验证弹窗需要绑定到当前的页面/活动才能正常显示。

修改方案

1. 确保获取到当前平台的界面上下文

  • 如果是在Xamarin.Android的Activity类中调用这段代码,直接用this即可代表当前Activity;
  • 如果是在Xamarin.iOS的UIViewController类中,this就是当前的视图控制器;
  • 如果是在Xamarin.Forms共享代码中,需要通过依赖服务获取平台上下文(后面会给出示例)。

2. 调整代码中的PlatformParameters初始化

用条件编译适配不同平台,修改后的完整代码如下:

string cloud = "https://login.microsoftonline.com/common/oauth2"; 
string tenantId = App.tenantId; 
string authority = $"{cloud}/{tenantId}"; 
string clientId = App.clientId; // 恢复使用clientId,之前的注释需要去掉
Uri redirectUri = App.redirectUrl; 
string resource = clientId; 
AuthenticationResult authResult = null; 
AuthenticationContext authContext = new AuthenticationContext(authority);

// 初始化平台参数
PlatformParameters platformParams;
#if __ANDROID__
// Android平台传入当前Activity
platformParams = new PlatformParameters(this);
#elif __IOS__
// iOS平台传入当前UIViewController
platformParams = new PlatformParameters(this);
#endif

try { 
    if (authContext.TokenCache.ReadItems().Count() > 0) { 
        authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().First().Authority); 
        authResult = await authContext.AcquireTokenSilentAsync(resource, clientId); 
    } else { 
        // 使用正确构造的platformParams替代原来的错误写法
        authResult = await authContext.AcquireTokenAsync(resource, clientId, redirectUri, platformParams); 
    } 
} catch (AdalSilentTokenAcquisitionException ee) { 
    // 异常分支同样需要传入platformParams
    authResult = await authContext.AcquireTokenAsync(resource, clientId, redirectUri, platformParams); 
}

3. Xamarin.Forms共享代码的适配方案

如果这段代码是写在Xamarin.Forms的共享项目中,需要通过依赖服务获取平台上下文:

第一步:定义共享接口

public interface IPlatformContextProvider
{
    object GetCurrentContext();
}

第二步:Android平台实现

在Android项目中添加实现类:

[assembly: Dependency(typeof(PlatformContextProvider))]
namespace YourAppName.Droid
{
    public class PlatformContextProvider : IPlatformContextProvider
    {
        public object GetCurrentContext()
        {
            // 使用Xamarin.Essentials获取当前Activity
            return Xamarin.Essentials.Platform.CurrentActivity;
        }
    }
}

第三步:iOS平台实现

在iOS项目中添加实现类:

[assembly: Dependency(typeof(PlatformContextProvider))]
namespace YourAppName.iOS
{
    public class PlatformContextProvider : IPlatformContextProvider
    {
        public object GetCurrentContext()
        {
            // 获取当前根视图控制器
            return UIKit.UIApplication.SharedApplication.KeyWindow.RootViewController;
        }
    }
}

第四步:在共享代码中获取上下文

// 获取平台上下文
var platformContext = DependencyService.Get<IPlatformContextProvider>().GetCurrentContext();

// 构造PlatformParameters
PlatformParameters platformParams;
#if __ANDROID__
platformParams = new PlatformParameters((Android.App.Activity)platformContext);
#elif __IOS__
platformParams = new PlatformParameters((UIKit.UIViewController)platformContext);
#endif

这样就能在共享代码中正确构造PlatformParameters,解决类型转换的问题了。

内容的提问来源于stack exchange,提问作者Akoh Victor Gutz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:32:00