131 lines
4.4 KiB
C#
Raw Normal View History

using Microsoft.AspNetCore.Authentication;
2016-11-02 20:41:12 +01:00
using Microsoft.AspNetCore.Http;
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using WebMVC.Services.Utilities;
2016-11-02 20:41:12 +01:00
namespace Microsoft.eShopOnContainers.WebMVC.Services
{
public class BasketService : IBasketService
{
private readonly IOptionsSnapshot<AppSettings> _settings;
2017-03-17 13:12:34 +01:00
private IHttpClient _apiClient;
private readonly string _remoteServiceBaseUrl;
private IHttpContextAccessor _httpContextAccesor;
2016-11-02 20:41:12 +01:00
2017-03-17 13:12:34 +01:00
public BasketService(IOptionsSnapshot<AppSettings> settings, IHttpContextAccessor httpContextAccesor, IHttpClient httpClient)
2016-11-02 20:41:12 +01:00
{
_settings = settings;
_remoteServiceBaseUrl = _settings.Value.BasketUrl;
_httpContextAccesor = httpContextAccesor;
2017-03-17 13:12:34 +01:00
_apiClient = httpClient;
2016-11-02 20:41:12 +01:00
}
public async Task<Basket> GetBasket(ApplicationUser user)
2016-11-02 20:41:12 +01:00
{
var context = _httpContextAccesor.HttpContext;
var token = await context.Authentication.GetTokenAsync("access_token");
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
C# 7 language feature updates Controllers/AccountController: Replace single line methods with expression bodied members. Includes constructor, C# 7 feature. Controllers/CatalogController: Remove unnecessary ToString() call. Replace single line methods with expression bodied members. Extensions/HttpClientExtensions: Replace single line methods with expression bodied members. Extensions/SessionExtensions: Replace single line methods with expression bodied members. Services/BasketService: Remove unnecessary ToString() calls. Add ?? to simplify conditional initialization Use TryGetValue and out variable initialization to simplify Quantity calculation Services/CatalogService: Use Value<T> generic method instead of dynamic types. There is a lot of overhead for dynamic and it seems overkill here. Services/IdentityParser: Use the pattern matching is expression. Refactor the LINQ queries to enumerate the collection (and create an enumerator) only once. The previous code had 3 enumerations. Services/Utilities/HttpApiClient: Remove the 'async' modifier and 'await' statements from methods where the only asynchronous statement is the final statement of the method, and the task from the underlying method can be returned. Services/Utilities/HttpApiClientWrapper: Use expression bodied members where applicable. Remove the 'async' modifier and 'await' statements from methods where the only asynchronous statement is the final statement of the method, and the task from the underlying method can be returned. ViewComponents/Cart: Use expression bodied members where applicable. ViewComponents/CartList: Use expression bodied members where applicable. Remove the 'async' modifier and 'await' statements from methods where the only asynchronous statement is the final statement of the method, and the task from the underlying method can be returned. ViewModels/Annotations/CardExpiration: Use the out variable initializer to simplify the validation of the card expiration date. ViewModels/Basket: Use property initializer syntax instead of constructor body ViewModels/CatalogViewModels/IndexViewModel: Use expression bodied property to return the calculated 'Disabled' property ViewModels/Order: Use property initializer syntax.
2017-03-20 14:18:20 -04:00
var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id}";
var dataString = await _apiClient.GetStringAsync(basketUrl);
C# 7 language feature updates Controllers/AccountController: Replace single line methods with expression bodied members. Includes constructor, C# 7 feature. Controllers/CatalogController: Remove unnecessary ToString() call. Replace single line methods with expression bodied members. Extensions/HttpClientExtensions: Replace single line methods with expression bodied members. Extensions/SessionExtensions: Replace single line methods with expression bodied members. Services/BasketService: Remove unnecessary ToString() calls. Add ?? to simplify conditional initialization Use TryGetValue and out variable initialization to simplify Quantity calculation Services/CatalogService: Use Value<T> generic method instead of dynamic types. There is a lot of overhead for dynamic and it seems overkill here. Services/IdentityParser: Use the pattern matching is expression. Refactor the LINQ queries to enumerate the collection (and create an enumerator) only once. The previous code had 3 enumerations. Services/Utilities/HttpApiClient: Remove the 'async' modifier and 'await' statements from methods where the only asynchronous statement is the final statement of the method, and the task from the underlying method can be returned. Services/Utilities/HttpApiClientWrapper: Use expression bodied members where applicable. Remove the 'async' modifier and 'await' statements from methods where the only asynchronous statement is the final statement of the method, and the task from the underlying method can be returned. ViewComponents/Cart: Use expression bodied members where applicable. ViewComponents/CartList: Use expression bodied members where applicable. Remove the 'async' modifier and 'await' statements from methods where the only asynchronous statement is the final statement of the method, and the task from the underlying method can be returned. ViewModels/Annotations/CardExpiration: Use the out variable initializer to simplify the validation of the card expiration date. ViewModels/Basket: Use property initializer syntax instead of constructor body ViewModels/CatalogViewModels/IndexViewModel: Use expression bodied property to return the calculated 'Disabled' property ViewModels/Order: Use property initializer syntax.
2017-03-20 14:18:20 -04:00
// Use the ?? Null conditional operator to simplify the initialization of response
var response = JsonConvert.DeserializeObject<Basket>(dataString) ??
new Basket()
{
BuyerId = user.Id
};
2016-11-02 20:41:12 +01:00
return response;
2016-11-02 20:41:12 +01:00
}
public async Task<Basket> UpdateBasket(Basket basket)
2016-11-02 20:41:12 +01:00
{
var context = _httpContextAccesor.HttpContext;
var token = await context.Authentication.GetTokenAsync("access_token");
2017-03-17 13:12:34 +01:00
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var basketUrl = _remoteServiceBaseUrl;
var response = await _apiClient.PostAsync(basketUrl, basket);
return basket;
2016-11-02 20:41:12 +01:00
}
public async Task<Basket> SetQuantities(ApplicationUser user, Dictionary<string, int> quantities)
2016-11-02 20:41:12 +01:00
{
var basket = await GetBasket(user);
2016-11-02 20:41:12 +01:00
basket.Items.ForEach(x =>
{
C# 7 language feature updates Controllers/AccountController: Replace single line methods with expression bodied members. Includes constructor, C# 7 feature. Controllers/CatalogController: Remove unnecessary ToString() call. Replace single line methods with expression bodied members. Extensions/HttpClientExtensions: Replace single line methods with expression bodied members. Extensions/SessionExtensions: Replace single line methods with expression bodied members. Services/BasketService: Remove unnecessary ToString() calls. Add ?? to simplify conditional initialization Use TryGetValue and out variable initialization to simplify Quantity calculation Services/CatalogService: Use Value<T> generic method instead of dynamic types. There is a lot of overhead for dynamic and it seems overkill here. Services/IdentityParser: Use the pattern matching is expression. Refactor the LINQ queries to enumerate the collection (and create an enumerator) only once. The previous code had 3 enumerations. Services/Utilities/HttpApiClient: Remove the 'async' modifier and 'await' statements from methods where the only asynchronous statement is the final statement of the method, and the task from the underlying method can be returned. Services/Utilities/HttpApiClientWrapper: Use expression bodied members where applicable. Remove the 'async' modifier and 'await' statements from methods where the only asynchronous statement is the final statement of the method, and the task from the underlying method can be returned. ViewComponents/Cart: Use expression bodied members where applicable. ViewComponents/CartList: Use expression bodied members where applicable. Remove the 'async' modifier and 'await' statements from methods where the only asynchronous statement is the final statement of the method, and the task from the underlying method can be returned. ViewModels/Annotations/CardExpiration: Use the out variable initializer to simplify the validation of the card expiration date. ViewModels/Basket: Use property initializer syntax instead of constructor body ViewModels/CatalogViewModels/IndexViewModel: Use expression bodied property to return the calculated 'Disabled' property ViewModels/Order: Use property initializer syntax.
2017-03-20 14:18:20 -04:00
// Simplify this logic by using the
// new out variable initializer.
if (quantities.TryGetValue(x.Id, out var quantity))
{
x.Quantity = quantity;
}
2016-11-02 20:41:12 +01:00
});
return basket;
}
public Order MapBasketToOrder(Basket basket)
{
var order = new Order();
order.Total = 0;
2016-11-02 20:41:12 +01:00
basket.Items.ForEach(x =>
{
order.OrderItems.Add(new OrderItem()
{
ProductId = int.Parse(x.ProductId),
2016-11-02 20:41:12 +01:00
PictureUrl = x.PictureUrl,
ProductName = x.ProductName,
Units = x.Quantity,
2016-11-02 20:41:12 +01:00
UnitPrice = x.UnitPrice
});
order.Total += (x.Quantity * x.UnitPrice);
2016-11-02 20:41:12 +01:00
});
return order;
}
public async Task AddItemToBasket(ApplicationUser user, BasketItem product)
{
Basket basket = await GetBasket(user);
if (basket == null)
{
basket = new Basket()
{
BuyerId = user.Id,
Items = new List<BasketItem>()
};
}
basket.Items.Add(product);
await UpdateBasket(basket);
}
public async Task CleanBasket(ApplicationUser user)
{
var context = _httpContextAccesor.HttpContext;
var token = await context.Authentication.GetTokenAsync("access_token");
_apiClient.Inst.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
C# 7 language feature updates Controllers/AccountController: Replace single line methods with expression bodied members. Includes constructor, C# 7 feature. Controllers/CatalogController: Remove unnecessary ToString() call. Replace single line methods with expression bodied members. Extensions/HttpClientExtensions: Replace single line methods with expression bodied members. Extensions/SessionExtensions: Replace single line methods with expression bodied members. Services/BasketService: Remove unnecessary ToString() calls. Add ?? to simplify conditional initialization Use TryGetValue and out variable initialization to simplify Quantity calculation Services/CatalogService: Use Value<T> generic method instead of dynamic types. There is a lot of overhead for dynamic and it seems overkill here. Services/IdentityParser: Use the pattern matching is expression. Refactor the LINQ queries to enumerate the collection (and create an enumerator) only once. The previous code had 3 enumerations. Services/Utilities/HttpApiClient: Remove the 'async' modifier and 'await' statements from methods where the only asynchronous statement is the final statement of the method, and the task from the underlying method can be returned. Services/Utilities/HttpApiClientWrapper: Use expression bodied members where applicable. Remove the 'async' modifier and 'await' statements from methods where the only asynchronous statement is the final statement of the method, and the task from the underlying method can be returned. ViewComponents/Cart: Use expression bodied members where applicable. ViewComponents/CartList: Use expression bodied members where applicable. Remove the 'async' modifier and 'await' statements from methods where the only asynchronous statement is the final statement of the method, and the task from the underlying method can be returned. ViewModels/Annotations/CardExpiration: Use the out variable initializer to simplify the validation of the card expiration date. ViewModels/Basket: Use property initializer syntax instead of constructor body ViewModels/CatalogViewModels/IndexViewModel: Use expression bodied property to return the calculated 'Disabled' property ViewModels/Order: Use property initializer syntax.
2017-03-20 14:18:20 -04:00
var basketUrl = $"{_remoteServiceBaseUrl}/{user.Id}";
var response = await _apiClient.DeleteAsync(basketUrl);
//CCE: response status code...
}
2016-11-02 20:41:12 +01:00
}
}