xamarin.forms - Forms.context 已过时。从 2.5 版开始,上下文已过时,请改用本地上下文
问题描述
我遇到了这个问题:Forms.context is obsolete.Context 从 2.5 版开始已经过时,请改用本地上下文。
我正在尝试使用 Azure Active Directory 登录,代码如下。请帮忙。
using Xamarin.Forms;
using myMobile.Service;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Threading.Tasks;
[assembly: Dependency(typeof(myMobile.Droid.Authenticator))]
namespace myMobile.Droid
{
class Authenticator: IAuthenticator
{
public async Task<AuthenticationResult> Authenticate(string tenantUrl, string graphResourceUri, string ApplicationID, string returnUri)
{
try
{
var authContext = new AuthenticationContext(tenantUrl);
if (authContext.TokenCache.ReadItems().Any())
authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().FirstOrDefault().Authority);
var authResult = await authContext.AcquireTokenAsync(graphResourceUri, ApplicationID, new Uri(returnUri), new PlatformParameters((Activity)Forms.Context));
return authResult;
}
catch (Exception)
{
return null;
}
}
}
}
// err encountered on this line :(Activity)Forms.Context)
Forms.context is obsolete.Context is obsolete as of version2.5,please use a local context instead.
var authResult = await authContext.AcquireTokenAsync(graphResourceUri, ApplicationID, new Uri(returnUri), new PlatformParameters((Activity)Forms.Context));
// - - 更新 :
//-------- Login Page:
private async void Login()
{
try
{
var data = await DependencyService.Get<IAuthenticator>()
.Authenticate(AzureSettings.tenanturl, AzureSettings.GraphResourceUri, AzureSettings.ApplicationID, AzureSettings.ReturnUri);
AzureSettings.AuthenticationResult = data;
//NavigateTopage(data);
}
catch (Exception)
{ }
}
}
//--------- in Shared Project :
//-- interface: IAuthenticator
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Threading.Tasks;
namespace myMobile.Service
{
public interface IAuthenticator
{
Task<AuthenticationResult> Authenticate(string tenantUrl, string graphResourceUri, string ApplicationID, string returnUri);
}
}
//-------- in Android Project: add
1) Class : Authenticator.cs
using Android.App;
using Android.Content;
using Xamarin.Forms;
using myMobile.Service;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Threading.Tasks;
[assembly: Dependency(typeof(myMobile.Droid.Authenticator))]
namespace myMobile.Droid
{
class Authenticator: IAuthenticator
{
private readonly Context _context;
public static void Init(Context context)
{
_context = context; //--error
}
public async Task<AuthenticationResult> Authenticate(string tenantUrl, string graphResourceUri, string ApplicationID, string returnUri)
{
try
{
var authContext = new AuthenticationContext(tenantUrl);
if (authContext.TokenCache.ReadItems().Any())
authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().FirstOrDefault().Authority);
var authResult = await authContext.AcquireTokenAsync(graphResourceUri, ApplicationID, new Uri(returnUri), new PlatformParameters((Activity) _context));
return authResult;
}
catch (Exception)
{
return null;
}
}
}
}
error :
An Object reference is required for non-static field,method or property.Authenticator._context
//------- Class: MainActivity
namespace myMobile.Droid
{
[Activity(Label = "myMobile", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
DependencyService.Get<IAuthenticator>().Init(this); //<-- Error
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App());
}
}
}
Error Message:
IUAthenticator does not contain a definition for Init and no extension method accepting
a first argument of type IAuthenticator
解决方案
您现在必须实现一个自定义构造函数,该构造函数将一个Context
放在局部变量中并使用它而不是 this 例如new PlatformParameters((Activity)Forms.Context)
。
对于自定义渲染器,您可以使用下面的解决方案。这样做:
public MyControlRenderer : ControlRenderer
{
private readonly Context _context;
public MyControlRenderer(Context context) : base(context)
{
_context = context;
}
}
对于像您这样的依赖服务,您必须找到一种方法来提供Context
. 由于 Xamarin.Forms 使用单个活动,因此您可以使用某种 init 方法。
将此添加到您的代码中:
public class MyService : IMyService
{
private static Context _context;
public static void Init(Context context)
{
_context = context;
}
}
现在打电话Init
给你MainActivity
,之后你应该会很好。这样做:DependencyService.Get<IMyService>().Init(this);
对于因多项活动而遇到此问题的其他人,请参阅此处的文档:https ://www.davidbritch.com/2017/11/xamarinforms-25-and-local-context-on.html这就是它的灵感来源上。
推荐阅读
- hibernate - 实体未按预期提交(Hibernate ORM with Panache)
- python - 获取名为 region_name 的第三个输入,它是一个字符串。将 region_list 中包含的适当字符串附加到您的打印语句中
- python - 通过 Python 连接到 UCCX 数据库 (Informix)
- javascript - HTML & CSS - DOM 遍历
- python-3.x - TypeError: Sporsmaal() 没有参数
- ruby-on-rails - 如何在 UTC 中为过去日期写一个 ruby on rails 条件?
- sql - PostgreSQL json_build_object 嵌套
- yaml - 订购者连接被拒绝 Hyperledger Fabric
- r - 通过在数据表中动态创建列名进行计算
- haskell - Haskell 用于推测执行条件/替代的策略