我在使用xamarin表单应用程序的webview中显示网页时遇到困难。 我开始使用eshoponcontainers示例应用程序。直到我进入登录阶段才顺利。发送授权请求时,登录页面不会显示。邮递员的一项测试显示了一个无法解决的客户端错误,因此我希望在我的网页浏览中看到该页面已加载,但这种情况并未发生。 我的.xaml页面如下
<AbsoluteLayout
Grid.Column="0"
Grid.ColumnSpan="3"
Grid.Row="0"
Grid.RowSpan="2"
IsVisible="{Binding IsLogin}">
<WebView
Source="{Binding LoginUrl}"
AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
AbsoluteLayout.LayoutFlags="All">
<WebView.Behaviors>
<OnPlatform x:TypeArguments="Behavior">
<On Platform="iOS, Android">
<On.Value>
<behaviors:EventToCommandBehavior
EventName="Navigating"
EventArgsConverter="{StaticResource WebNavigatingEventArgsConverter}"
Command="{Binding NavigateCommand}" />
</On.Value>
</On>
<On Platform="UWP">
<On.Value>
<behaviors:EventToCommandBehavior
EventName="Navigated"
EventArgsConverter="{StaticResource WebNavigatedEventArgsConverter}"
Command="{Binding NavigateCommand}" />
</On.Value>
</On>
</OnPlatform>
</WebView.Behaviors>
</WebView>
</AbsoluteLayout>
背后的代码看起来像这样
public partial class LoginView : ContentPage
{
private bool _animate;
public LoginView ()
{
InitializeComponent ();
}
protected override async void OnAppearing()
{
var content = this.Content;
this.Content = null;
this.Content = content;
var vm = BindingContext as LoginViewModel;
if (vm != null)
{
vm.InvalidateMock();
if (!vm.IsMock)
{
_animate = true;
await AnimateIn();
}
}
}
protected override void OnDisappearing()
{
_animate = false;
}
public async Task AnimateIn()
{
if (Device.RuntimePlatform == Device.UWP)
{
return;
}
await AnimateItem(Banner, 10500);
}
private async Task AnimateItem(View uiElement, uint duration)
{
try
{
while (_animate)
{
await uiElement.ScaleTo(1.05, duration, Easing.SinInOut);
await Task.WhenAll(
uiElement.FadeTo(1, duration, Easing.SinInOut),
uiElement.LayoutTo(new Rectangle(new Point(0, 0), new Size(uiElement.Width, uiElement.Height))),
uiElement.FadeTo(.9, duration, Easing.SinInOut),
uiElement.ScaleTo(1.15, duration, Easing.SinInOut)
);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
}
我在“LoginViewModel”
中有以下内容 public class LoginViewModel: ViewModelBase
{
private ValidatableObject<string> _userName;
private ValidatableObject<string> _password;
private bool _isMock;
private bool _isValid;
private bool _isLogin;
private string _authUrl;
private ISettingsService _settingsService;
private IOpenUrlService _openUrlService;
private IIdentityService _identityService;
public LoginViewModel(
ISettingsService settingsService,
IOpenUrlService openUrlService,
IIdentityService identityService)
{
_settingsService = settingsService;
_openUrlService = openUrlService;
_identityService = identityService;
_userName = new ValidatableObject<string>();
_password = new ValidatableObject<string>();
InvalidateMock();
AddValidations();
}
public ValidatableObject<string> UserName
{
get
{
return _userName;
}
set
{
_userName = value;
RaisePropertyChanged(() => UserName);
}
}
public ValidatableObject<string> Password
{
get
{
return _password;
}
set
{
_password = value;
RaisePropertyChanged(() => Password);
}
}
public bool IsMock
{
get
{
return _isMock;
}
set
{
_isMock = value;
RaisePropertyChanged(() => IsMock);
}
}
public bool IsValid
{
get
{
return _isValid;
}
set
{
_isValid = value;
RaisePropertyChanged(() => IsValid);
}
}
public bool IsLogin
{
get
{
return _isLogin;
}
set
{
_isLogin = value;
RaisePropertyChanged(() => IsLogin);
}
}
public string LoginUrl
{
get
{
return _authUrl;
}
set
{
_authUrl = value;
RaisePropertyChanged(() => LoginUrl);
}
}
public ICommand MockSignInCommand => new Command(async () => await MockSignInAsync());
public ICommand SignInCommand => new Command(async () => await SignInAsync());
public ICommand RegisterCommand => new Command(Register);
public ICommand NavigateCommand => new Command<string>(async (url) => await NavigateAsync(url));
public ICommand SettingsCommand => new Command(async () => await SettingsAsync());
public ICommand ValidateUserNameCommand => new Command(() => ValidateUserName());
public ICommand ValidatePasswordCommand => new Command(() => ValidatePassword());
public override Task InitializeAsync(object navigationData)
{
if (navigationData is LogoutParameter)
{
var logoutParameter = (LogoutParameter)navigationData;
if (logoutParameter.Logout)
{
Logout();
}
}
return base.InitializeAsync(navigationData);
}
private async Task MockSignInAsync()
{
IsBusy = true;
IsValid = true;
bool isValid = Validate();
bool isAuthenticated = false;
if (isValid)
{
try
{
await Task.Delay(10);
isAuthenticated = true;
}
catch (Exception ex)
{
Debug.WriteLine($"[SignIn] Error signing in: {ex}");
}
}
else
{
IsValid = false;
}
if (isAuthenticated)
{
_settingsService.AuthAccessToken = GlobalSetting.Instance.AuthToken;
await NavigationService.NavigateToAsync<MainViewModel>();
await NavigationService.RemoveLastFromBackStackAsync();
}
IsBusy = false;
}
private async Task SignInAsync()
{
IsBusy = true;
await Task.Delay(10);
LoginUrl = _identityService.CreateAuthorizationRequest();
IsValid = true;
IsLogin = true;
IsBusy = false;
}
private void Register()
{
_openUrlService.OpenUrl(GlobalSetting.Instance.RegisterWebsite);
}
private void Logout()
{
var authIdToken = _settingsService.AuthIdToken;
var logoutRequest = _identityService.CreateLogoutRequest(authIdToken);
if (!string.IsNullOrEmpty(logoutRequest))
{
// Logout
LoginUrl = logoutRequest;
}
if (_settingsService.UseMocks)
{
_settingsService.AuthAccessToken = string.Empty;
_settingsService.AuthIdToken = string.Empty;
}
_settingsService.UseFakeLocation = false;
}
private async Task NavigateAsync(string url)
{
var unescapedUrl = System.Net.WebUtility.UrlDecode(url);
if (unescapedUrl.Equals(GlobalSetting.Instance.LogoutCallback))
{
_settingsService.AuthAccessToken = string.Empty;
_settingsService.AuthIdToken = string.Empty;
IsLogin = false;
LoginUrl = _identityService.CreateAuthorizationRequest();
}
else if (unescapedUrl.Contains(GlobalSetting.Instance.IdentityCallback))
{
var authResponse = new AuthorizeResponse(url);
if (!string.IsNullOrWhiteSpace(authResponse.Code))
{
var userToken = await _identityService.GetTokenAsync(authResponse.Code);
string accessToken = userToken.AccessToken;
if (!string.IsNullOrWhiteSpace(accessToken))
{
_settingsService.AuthAccessToken = accessToken;
_settingsService.AuthIdToken = authResponse.IdentityToken;
await NavigationService.NavigateToAsync<MainViewModel>();
await NavigationService.RemoveLastFromBackStackAsync();
}
}
}
}
private async Task SettingsAsync()
{
await NavigationService.NavigateToAsync<SettingsViewModel>();
}
private bool Validate()
{
bool isValidUser = ValidateUserName();
bool isValidPassword = ValidatePassword();
return isValidUser && isValidPassword;
}
private bool ValidateUserName()
{
return _userName.Validate();
}
private bool ValidatePassword()
{
return _password.Validate();
}
private void AddValidations()
{
_userName.Validations.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "A username is required." });
_password.Validations.Add(new IsNotNullOrEmptyRule<string> { ValidationMessage = "A password is required." });
}
public void InvalidateMock()
{
IsMock = _settingsService.UseMocks;
}
}