我正在使用MvvmCross Forms
和Refit
实现简单的登录屏幕。
通过按下具有' LogInCommand'
命令的按钮启动身份验证任务的开始<Button x:Name="loginButton" Text = "Login" HorizontalOptions = "Center"
VerticalOptions = "StartAndExpand" FontSize="24" Command="{ Binding LogInCommand }"/>
这将在AuthenticationViewModel中执行以下命令:
#region commands
async Task LogInTaskAsync()
{
var errors = _validator.Validate(this);
if (!errors.IsValid)
{
_toastService.DisplayErrors(errors); //Display errors here.
}
else
{
using (new Busy(this))
{
try
{
Status = AuthenticationStatusEnum.LOADING;
// get access token
string accessToken = await _authenticationService.LogIn(_email, _password);
Debug.WriteLine(String.Format("Access Token:t {0} ", accessToken));
// save token on preferences.
Settings.AccessToken = accessToken;
Status = AuthenticationStatusEnum.LOGIN_SUCESS;
}
catch (TaskCanceledException ex) {
Debug.WriteLine("Timeout Operation ...");
}
catch (Exception ex)
{
MessagingCenter.Send(new object(), EventTypeName.EXCEPTION_OCCURRED, ex);
Status = AuthenticationStatusEnum.LOGIN_FAILED;
}
}
}
}
IMvxCommand _logInCommand;
public IMvxCommand LogInCommand =>
_logInCommand ?? (_logInCommand = new MvxCommand(async () => await LogInTaskAsync()));
使用refit的AuthenticationService实例将注入到视图模型中。
async public Task<string> LogIn(string email, string password)
{
Debug.WriteLine(String.Format("Login with {0}/{1}", email, password));
return await _authenticationRestService.getAuthorizationToken(new JwtAuthenticationRequestDTO()
{
Email = email,
Password = password
}).ContinueWith(t => t.Result.Data.Token, TaskContinuationOptions.OnlyOnRanToCompletion);
}
改装服务规范如下:
[Headers("Accept: application/json")]
public interface IAuthenticationRestService
{
[Post("/")]
Task<APIResponse<JwtAuthenticationResponseDTO>> getAuthorizationToken([Body] JwtAuthenticationRequestDTO authorizationRequest);
}
问题是任务总是被取消,总是抛出TaskCanceledException异常。
我还公开了我配置上下文实例的CoreApp。
public class CoreApp : MvvmCross.Core.ViewModels.MvxApplication
{
public override void Initialize()
{
var httpClient = new HttpClient(new HttpLoggingHandler())
{
BaseAddress = new Uri(SharedConfig.BASE_API_URL),
Timeout = TimeSpan.FromMinutes(SharedConfig.TIMEOUT_OPERATION_MINUTES)
};
// Register REST services
Mvx.RegisterSingleton<IAuthenticationRestService>(() => RestServiceFactory.getService<IAuthenticationRestService>(httpClient));
Mvx.RegisterSingleton<IParentsRestService>(() => RestServiceFactory.getService<IParentsRestService>(httpClient));
Mvx.RegisterSingleton<IChildrenRestService>(() => RestServiceFactory.getService<IChildrenRestService>(httpClient));
CreatableTypes()
.InNamespace("Bullytect.Core.Services")
.EndingWith("ServiceImpl")
.AsInterfaces()
.RegisterAsLazySingleton();
Mapper.Initialize(cfg => {
cfg.CreateMap<ParentDTO, ParentEntity>();
cfg.CreateMap<SonDTO, SonEntity>();
});
Mvx.RegisterType<IValidator, Validator>();
RegisterAppStart(new CustomAppStart());
}
}
有人知道如何解决这个问题。在此先感谢!!