@szydlak:
Brak await async.
Coś czytałem o asynchroniczności, ale czuje, że to nie na mój poziom, zostałem zmuszony do użycia await/async, bo Identity posiada niektóre metody tylko asynchroniczne, nie wiem gdzie popełniłem błędy.
Katalog models a w nim services.
Z tego co zrozumiałem/wyczytałem w kontrolerze mają być przekierowania do metod w serwisach, czyli jak najmniej kodu, jak możesz to proszę rozwiń co jest nie tak.
W pętli pobierasz dane z bazy. Może lepiej pobrac wszystkich userów zrobić update i savechanges.
Kopiuj
public async Task<IdentityResult> EditUsersInRole(List<UserRoleViewModel> model, string roleName)
{
var role = await roleManager.FindByNameAsync(roleName);
IdentityResult result = null;
for (int i = 0; i < model.Count; i++)
{
var user = await userManager.FindByIdAsync(model[i].UserId);
if (model[i].IsSelected && !(await userManager.IsInRoleAsync(user, role.Name)))
{
result = await userManager.AddToRoleAsync(user, role.Name);
}
else if (!model[i].IsSelected && await userManager.IsInRoleAsync(user, role.Name))
{
result = await userManager.RemoveFromRoleAsync(user, role.Name);
}
else
{
continue;
}
}
return result;
}
Jeśli chodzi o to, to próbowałem, ale nie umiem inaczej.
Brak Unit testów.
To kolejna rzecz, o której tylko słyszałem, aktualnie odpuszczam, zdaje sobie sprawę, że to ważna sprawa i mnie nie ominie.
@WeiXiao:
Kopiuj
> public void WithdrawMoney(decimal amountToWithdraw, ApplicationUser user)
> {
> var amount = amountToWithdraw;
> var balanceAfter = user.Billing.Balance -= amount;
>
> user.AccountHistory = new List<AccountHistoryEntity>
> {
> new AccountHistoryEntity
> {
> ActionType = "wypłata",
> Amount = (double)amount,
> BalanceAfter = (double)balanceAfter,
> Date = DateTime.Now
> }
> };
>
> dbContext.SaveChanges();
> }
> ```
>
> Dlaczego przy wyciąganiu pieniędzy historia jest nadpisywana historią z jednym wpisem?
>
> ```csharp
> var user = dbContext.Users.Include(x => x.Billing).SingleOrDefault(x => x.Id == id);
> if (data.AmountToWithdraw > user.Billing.Balance)
> {
> ModelState.AddModelError("", "Nie możesz wypłacić więcej pieniędzy, niż masz na koncie");
> return View(data);
> }
> ```
>
> Czy tego checka nie chciałbyś wynieść z kontrolera do np. tego kodu obsługującego wyciąganie kasy?
>
>
> No bo teraz testując `WithdrawMoney` mógłby przejść test gdzie wyciągasz kasę z pustego konta i podobne
Chyba udało mi się poprawić, z tym nadpisywaniem też działało, pewnie dzięki EF, ale wydaje mi się, że teraz jest lepiej.
Dla wynagrodzeń też poprawiłem + dodałem pobieranie użytkowników z czasem większym od 0, zamiast sprawdzać każdego if'em.
```csharp
var users = dbContext.Users.Include(x => x.Billing).Include(x => x.AccountHistory)
.Where(x => x.Billing.MinutesWorked > 0);
Jeszcze był tam błąd logiczny w if'ie data.AmountToWithdraw > user.Billing.Balance
poprawiłem na balanceAfter < 0
Tu poprawiony kod, który wspominałeś.
Kopiuj
public IActionResult Withdrawal(WithdrawalViewModel data, string id)
{
if (!ModelState.IsValid)
{
return View(data);
}
if (data.AmountToWithdraw == 0)
{
ModelState.AddModelError("", "Wpisz kwotę powyżej 0");
return View(data);
}
var error = userDataService.WithdrawMoney(data, id);
if (error)
{
ModelState.AddModelError("", "Nie możesz wypłacić więcej pieniędzy, niż masz na koncie");
return View(data);
}
return RedirectToAction("Index");
}
Kopiuj
public bool WithdrawMoney(WithdrawalViewModel data, string userId)
{
var user = dbContext.Users.Include(x => x.Billing).Include(x => x.AccountHistory)
.SingleOrDefault(x => x.Id == userId);
var amount = data.AmountToWithdraw;
var balanceAfter = user.Billing.Balance -= amount;
if (balanceAfter < 0)
{
return true;
}
user.AccountHistory.Add(new AccountHistoryEntity
{
ActionType = "wypłata",
Amount = (double)amount,
BalanceAfter = (double)balanceAfter,
Date = DateTime.Now
});
dbContext.SaveChanges();
return false;
}
Nie wiem jak dodać ModelState w innym miejscu, niż w kontrolerze, dlatego był taki spaghetti code, zrobiłem zwracanie error jako bool, nie wiem czy to "ma ręce i nogi".
Swoją drogą, dla mnie bez różnicy czy piszę kod w kontrolerze, czy serwisach, przypuszczam, że powinno się w tych serwisach min. do robienia testów i czytelności kodu?
Dzięki za pomoc chłopaki :)