MVVMCross inactive page after click - xamarin.forms

I have a question? Application is implemented in MVVMCross with Xamarin.Forms. I have 3 views. I use TollbarItem for running next pages. If I run it under VisualStudio in Release or Debug mode then all works corectly. If I run it on different phones with Android (ver 8-9) I have problem after back from any next page. This page where I've clicked page becomes inactive :-(
I noticed, when I run few times on first page any options, the second view is sometimes active.
I've installed a lot of different versions of Xamarin.Forms from 2.3... to 4.5...., it's the same.
Could you help me? Thank's in advance :-)
If you need more codes tell me please.
My code the first viewmodel from I navigate to the next view:
public ICommand ShowSettingsPageCommand => new MvxAsyncCommand(() => RunShowSettingsPageCommand());
public ICommand ShowHelpPageCommand => new MvxAsyncCommand(() => RunShowHelpPageCommand());
public async Task RunShowHelpPageCommand()
{
await navigationService.Navigate<HelpViewModel>();
}
public async Task RunShowSettingsPageCommand()
{
await navigationService.Navigate<SettingsViewModel>();
}
Before I've used this form too (but it wasn't working too):
public ICommand ShowSettingsPageCommand => new MvxAsyncCommand(() => navigationService.Navigate<SettingsViewModel>());
I tried changed my code as below (I've pasted more lines):
//public ICommand ShowSettingsPageCommand => new MvxAsyncCommand(() => RunShowSettingsPageCommand());
public ICommand ShowSettingsPageCommand => new MvxAsyncCommand(RunShowSettingsPageCommand);
//public ICommand ShowHelpPageCommand => new MvxAsyncCommand(() => RunShowHelpPageCommand());
public ICommand ShowHelpPageCommand => new MvxAsyncCommand(RunShowHelpPageCommand);
public ICommand OnChangeClicked => new Command(()=>RunChangeClicked());
public ICommand OnEyeClicked => new Command(()=>RunOnEyeClicked());
public ICommand OnPowerClicked => new Command(()=> RunOnPowerClicked());
public ICommand OnCopyToClipboardClicked => new Command((() => RunOnCopyToClipboardClicked()));
public ICommand OnShareClicked => new Command((() => RunOnShareClicked()));
public async Task RunShowHelpPageCommand()
{
await navigationService.Navigate<HelpViewModel>();
}
public async Task RunShowSettingsPageCommand()
{
await navigationService.Navigate<SettingsViewModel>();
}
public async Task RunOnShareClicked()
{
await Task.Run(() => Share.RequestAsync(new ShareTextRequest
{
Text = YourWordCrypted,
Title = "Wygenerowano w Koderek: "
}));
}
public async void RunOnCopyToClipboardClicked()
{
await Clipboard.SetTextAsync(YourWordCrypted);
}
public void RunOnPowerClicked()
{
YourWord=String.Empty;
}
public void RunOnEyeClicked()
{
IsHideYourWord =!IsHideYourWord;
}
public void RunChangeClicked()
{
YourWord = YourWordCrypted;
}
public string RunCodeOn()
{
return CaesarSolve();
}
Unfortunately, the problem still ocurs...

Related

.NET efcore 7 JSON COLUMN PROBLEMS

as you know, jsoncolumn support has arrived for efcore7.
I quickly used
yes, I had no problems with creating columns with migration. I added new data
but i have the following problem in query operation
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<IdentitySchema>().OwnsMany(
identitySchema => identitySchema.AuthorityCodes, ownedNavigationBuilder =>
{
var q=ownedNavigationBuilder.ToJson();
})
.OwnsMany(
identitySchema => identitySchema.UserIds, ownedNavigationBuilder =>
{
var x= ownedNavigationBuilder.ToJson();
}); ;
base.OnModelCreating(builder);
}
public class UserAg
{
public string UserId { get; set; }
}
_context.IdentitySchema.Select(f => new
{
f.UserIds,
f.AuthorityCodes
}).Where(f => f.UserIds.Any(f => f.UserId == "1")).ToList();

Polly Circuit breaker not maintaining state with .net core HTTP Client

I have implemented the polly retry and Circuit breaker policy (wrapped). when the call fails and the circuit is open for the previous call the next call again goes to the retry and hit the circuit breaker again instead of just throwing the circuitbreakexception. I think somehow the HTTP client is getting recreated again even though am using the typed client. I am not able to figure the issue. Here is the code
Startup
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddHttpClient<IIntCall, IntCall>().WrapResilientPolicies();
}
Interface
public interface IIntCall
{
Task<bool> DoSomething();
}
Implementation:
public class IntCall : IIntCall
{
private readonly HttpClient client;
public IntCall(HttpClient httpClient)
{
this.client = httpClient;
}
public async Task<bool> DoSomething()
{
var response = await client.GetAsync("http://www.onegoogle.com");
var content = await response.Content.ReadAsStringAsync();
return false;
}
}
Polly Implementation
public static class CBExtensions
{
public static void WrapResilientPolicies(this IHttpClientBuilder builder)
{
builder.AddPolicyHandler((service, request) =>
GetRetryPolicy().WrapAsync(GetCircuitBreakerPolicy()));
}
private static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
{
return HttpPolicyExtensions.HandleTransientHttpError()
.CircuitBreakerAsync(3, TimeSpan.FromSeconds(30), (result, retryAttempt) =>
{
Debug.WriteLine("circuit broken");
},
() =>
{
Debug.WriteLine("circuit closed");
});
}
private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
return HttpPolicyExtensions.HandleTransientHttpError()
.Or<Exception>(e => !(e is BrokenCircuitException))
.WaitAndRetryAsync(3,
retryAttempt => TimeSpan.FromMilliseconds(500),
onRetry: (context, attempt) =>
{
Debug.WriteLine("error");
}
);
}
}
I figured the issue. because I am fetching the request details the policy is injected every call and hence the state is renewed. I moved my code from
public static void WrapResilientPolicies(this IHttpClientBuilder builder)
{
builder.AddPolicyHandler((service, request) =>
GetRetryPolicy().WrapAsync(GetCircuitBreakerPolicy()));
}
to this
public static void WrapResilientPolicies(this IHttpClientBuilder builder)
{
builder.AddPolicyHandler(
GetRetryPolicy().WrapAsync(GetCircuitBreakerPolicy()));
}

ASP.NET Core policy base Authorize with RequireUser with string array

I am creating policy base authorization and would like to allow multiple users in one policy to access webpage.
I created policy like shown below in start up file. Question, How can I use multiple usernames in one policy? I looked at the method for.RequireUserName, it is only accepting string username.
Policy name AdminServiceAccount is mostly I am interested in to add multiple users. If I use param .RequireUserName("DOMAIN\\USER1,DOMAIN\\USER2") will it work? I don't think so, but wanted to check if there is an alternative way.
services.AddAuthorization(
option =>
{
option.AddPolicy("Admin", policy => policy.RequireRole("Domain\\GroupName"));
option.AddPolicy("SuperAdminUser", policy => policy.RequireUserName("DOMAIN\\SuperAdminUser"));
option.AddPolicy("AdminServiceAccount", policy => policy.RequireUserName("DOMAIN\\USER1"));
}
);
UPDATE 1:
UPDATE 2:
So in my Controller, I added [Authorize(Policy = "UserNamesPolicy")] as show below:
[Authorize(Policy = "UserNamesPolicy")]
public class ServersController : Controller
{
private readonly ServerMatrixDbContext _context;
public ServersController(ServerMatrixDbContext context)
{
_context = context;
}
// GET: Servers
public async Task<IActionResult> Index()
{
// Some code here
return View();
}
}
Here is my startup file:
services.AddAuthorization(
option =>
{
option.AddPolicy("UserNamesPolicy",
policy => policy.Requirements.Add(new UserNamesRequirement("DOMAIN\\USER1", "DOMAIN\\USER2"))
);
}
);
services.AddSingleton<IAuthorizationHandler, UserNamesRequirement();
For .AddSingleTon in startup file I get below error:
Here is the handler class:
public class UserNamesHandler : AuthorizationHandler<UserNamesRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UserNamesRequirement requirement)
{
var userName = context.User.FindFirst(ClaimTypes.NameIdentifier).Value;
if (requirement.Users.ToList().Contains(userName))
context.Succeed(requirement);
return Task.FromResult(0);
}
}
Here is is the UserNamesRequirement class:
public class UserNamesRequirement : IAuthorizationRequirement
{
public UserNamesRequirement(params string[] UserNames)
{
Users = UserNames;
}
public string[] Users { get; set; }
}
UPDATE 3: SOLVED!!!!
Here are few changes that were added from update 2:
In UserNameshandler class changed var userName to get values from context.User.Identity.Name;
public class UserNamesHandler : AuthorizationHandler<UserNamesRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UserNamesRequirement requirement)
{
// var userName = context.User.FindFirst(ClaimTypes.NameIdentifier).Value;
var userName = context.User.Identity.Name;
if (requirement.Users.ToList().Contains(userName))
context.Succeed(requirement);
return Task.FromResult(0);
}
}
In StartUp class fixed from services.AddSingleton<IAuthorizationHandler, UserNamesRequirement>(); to services.AddSingleton<IAuthorizationHandler,UserNamesHandler>();
Thanks to Gevory. :)
public class UserNamesHandler : AuthorizationHandler<UserNamesRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, UserNamesRequirement requirement)
{
var userName = context.User.Identity.Name;
if(requirement.UserNames.ToList().Contains(userName))
context.Succeed(requirement);
return Task.CompletedTask; // if it does not compile use Task.FromResult(0);
}
}
public class UserNamesRequirement : IAuthorizationRequirement
{
public UserNamesRequirement(params string[] userNames)
{
UserNames = userNames;
}
public string[] UserNames { get; set; }
}
in startup.cs add the following
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy("UserNamesPolicy",
policy => policy.Requirements.Add(new UserNamesRequirement("ggg","dsds")));
});
services.AddSingleton<IAuthorizationHandler, UserNamesHandler>()
}
Just for anyone coming to this who wants a different approach, I battled with trying to get the UserNamesHandler to register properly, to no avail. So I solved this in a different way:
static readonly string[] myUserList = { "user1", "user2", "user3" };
options.AddPolicy( "MyNameListPolicy",
policy => policy.RequireAssertion(
context => myUserList.Contains( context.User.Identity.Name ) ) );
This worked fine for me.

Moq callback with invoking parameter

I have these three lines of c# code using Moq, how can I write a single line?
JobQueueRepository.Setup(r => r.UpdateJobQueueStatus(DefaultJobId, JobStatus.Success)).Callback(() => statuses.Add(JobStatus.Success));
JobQueueRepository.Setup(r => r.UpdateJobQueueStatus(DefaultJobId, JobStatus.Failed)).Callback(() => statuses.Add(JobStatus.Failed));
JobQueueRepository.Setup(r => r.UpdateJobQueueStatus(DefaultJobId, JobStatus.Running)).Callback(() => statuses.Add(JobStatus.Running));
Thanks for the help.
There is a piece of code you are asking for
JobQueueRepository
.Setup(it => it.UpdateJobQueueStatus(DefaultJobId, It.IsAny<JobStatus>()))
.Callback<int, JobStatus>((id, status) => statuses.Add(status));
And a test that tests how it works
[TestClass]
public class TestClass
{
[TestMethod]
public void TestMethod()
{
var statuses = new List<JobStatus>();
var JobQueueRepository = new Mock<IJobQueueRepository>();
int DefaultJobId = 100500;
JobQueueRepository
.Setup(it => it.UpdateJobQueueStatus(DefaultJobId, It.IsAny<JobStatus>()))
.Callback<int, JobStatus>((id, status) => statuses.Add(status));
JobQueueRepository.Object.UpdateJobQueueStatus(DefaultJobId, JobStatus.Failed);
JobQueueRepository.Object.UpdateJobQueueStatus(DefaultJobId, JobStatus.Running);
JobQueueRepository.Object.UpdateJobQueueStatus(DefaultJobId, JobStatus.Success);
statuses.Should().HaveCount(3);
statuses.Should().Contain(JobStatus.Failed);
statuses.Should().Contain(JobStatus.Running);
statuses.Should().Contain(JobStatus.Success);
}
public enum JobStatus
{
Success,
Failed,
Running
}
public interface IJobQueueRepository
{
void UpdateJobQueueStatus(int id, JobStatus status);
}
}
You can easily create an extension method to do that as below.
public class Class1
{
[Test]
public void CallBackDemo() {
var statuses = new List<JobStatus>();
var jobQueueRepositoryStub = new Mock<IJobQueueRepository>();
const int defaultJobId = 100500;
jobQueueRepositoryStub.Setup(r => r.UpdateJobQueueStatus(defaultJobId, JobStatus.Success))
.Callback( new Action[]
{
() => statuses.Add(JobStatus.Success),
() => statuses.Add(JobStatus.Failed),
() => statuses.Add(JobStatus.Running)
});
var sut = new Sut(jobQueueRepositoryStub.Object);
sut.Do(defaultJobId);
Assert.True(statuses.Count == 3);
Assert.True(statuses.Any(x => x == JobStatus.Failed));
Assert.True(statuses.Any(x => x == JobStatus.Running));
Assert.True(statuses.Any(x => x == JobStatus.Success));
}
Callback extension method:
public static class Ext
{
public static void Callback<TRepo>(this ISetup<TRepo> repo, IEnumerable<Action> actions ) where TRepo : class {
foreach (var action in actions) {
action();
}
}
}
Sut (System Under Test) and other classes:
public enum JobStatus { Success, Failed, Running }
public interface IJobQueueRepository {
void UpdateJobQueueStatus(int id, JobStatus status);
}
public class Sut {
private readonly IJobQueueRepository _repository;
public Sut(IJobQueueRepository repository) {
_repository = repository;
}
public void Do(int jobId) {
_repository.UpdateJobQueueStatus(jobId, JobStatus.Success);
_repository.UpdateJobQueueStatus(jobId, JobStatus.Failed);
_repository.UpdateJobQueueStatus(jobId, JobStatus.Running);
}
}

is this a correct way to test a presenter

i'm creating a shopping website using web forms and MVP pattern in a three layered architecture. i also decided to do the validation and type castings inside of presenter class.for testing framework i use NUnit and for my mocks i use NSubstitude. here is my category model class:
//we're doing Dependency injection here.
public abstract class BaseRepository
{
EntityContext context;
public BaseRepository()
{
context = new EntityContext();
}
public EntityContext Context
{
get { return context; }
}
}
public class CategoryRepository : BaseRepository
{
public int Add(long id, string name)
{
Category cat = new Category();
cat.Id = id;
cat.Name = name;
Context.Category.Add(cat);
Context.SaveChanges();
}
}
here is the category presenter:
public class CategoryPresenter : BasePresenter //has nothing but a dependency property to Logger
{
BaseRepository _model;
IView _view;
public CategoryPresenter(IView view)
{
_model = new CategoryRepository();
_view = view;
}
public void Add()
{
//havn't passed the tests yet since i'm not sure if i'm on the correct path.
//whatever validation, loggin and type casting will go here.
_model.Add(_view.CategoryId, _view.CategoryName);
}
}
and here is the test class for the presenter:
[Test]
public void Add_NullId_ThrowException()
{
_view.CategoryId.Returns(p => null);
_view.CategoryName.Returns(p => "test");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_EmptyId_ThrowException()
{
_view.CategoryId.Returns(p => "");
_view.CategoryName.Returns(p => "test");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_SpaceOnlyId_ThrowException()
{
_view.CategoryId.Returns(p => " ");
_view.CategoryName.Returns(p => "test");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_InvalidLowBoundId_ThrowException()
{
_view.CategoryId.Returns(p => "-1");
_view.CategoryName.Returns(p => "test");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_InvalidHighBoundId_ThrowException()
{
_view.CategoryId.Returns(p => long.MaxValue.ToString() + "1");
_view.CategoryName.Returns(p => "test");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_EmptyName_ThrowException()
{
_view.CategoryId.Returns(p => "1");
_view.CategoryName.Returns(p => "");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_NullName_ThrowException()
{
_view.CategoryId.Returns(p => "1");
_view.CategoryName.Returns(p => null);
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_SpaceOnlyName_ThrowException()
{
_view.CategoryId.Returns(p => "1");
_view.CategoryName.Returns(p => " ");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_NumberOnlyName_ThrowException()
{
_view.CategoryId.Returns(p => "1");
_view.CategoryName.Returns(p => "123");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
am i testing correctly? i mean is this what the test class should look like? i'm i missing something? is this too much? like "you don't need to test emptiness" or any other issues associated with my tests or code? if you notice anything wrong within my whole code and/or architecture i appreciate it if you correct me. thanks!
Update: IView is inherited by a .aspx page. on code behind i simply call the presenter method from inside of a click event that user is triggered by pressing a button. as for memory i havn't gone that far yet. simply stuck on TDD.
I'd remove the validation logic from the application layer (where presenters live) and extract it into the domain layer (where the repositories live).
Then don't do the validation right there in the presenter, but instead have the presenter call the necessary validators.
For unit tests of the presenter you provide validator mock objects to the presenter and verify that the correct validation methods are called for the data.
So you have to test two things:
1) Test if the presenter calls the validators with the data from the view
2) Test the validators on their own
Tests might look like this:
For the presenter (class CategoryPresenterTests):
[Test]
public void Add_CallsTheValidatorWithDataFromTheView()
{
_viewMock.CategoryId.Returns(p => "id");
_viewMock.CategoryName.Returns(p => "name");
_presenter.Add();
_categoryValidatorMock.Verify(x=>x.Validate("id", "name"), Times.Once);
}
[Test]
public void Add_ForwardsValidationExceptions()
{
_viewMock.CategoryId.Returns(p => "id");
_viewMock.CategoryName.Returns(p => "name");
_categoryValidatorMock.Setup(x=>x.Validate(...)).Throws<ValidationException>();
Assert.Throws<ValidationException>(() => _presenter.Add());
}
Note that we don't care about concrete inputs from the view, only that the validator is called with this exact data from the view and that the result (in this case exception or no exception) is passed back.
For the validator (class CategoryValidatorTests. Basically all your current tests go here):
[Test]
public void NullId_ThrowsException() {
string id = null;
string name = "test";
Assert.Throws<ValidationException>(() => _validator.Validate(id, name));
}
Note that I don't know NSubstitutes syntax so the above is pseudo code.. hope you can decipher it :)
Besides that I wouldn't create the repositories within the presenters, instead inject their interfaces through the constructor (like you did with the IView). Then provide mock objects and, like with the validators, verify that they are called correctly by the presenter.
All of the above should allow you to reuse your validation logic outside of the presenters and it'll take some complexity away from the presenters, allowing them to concentrate more on their actual purpose of mediating between model and view and handling workflows.

Resources