diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs index 702c805fb..95412b066 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/BasketController.cs @@ -11,7 +11,8 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers { [Route("api/v1/[controller]")] [Authorize] - public class BasketController : Controller + [ApiController] + public class BasketController : ControllerBase { private readonly ICatalogService _catalog; private readonly IBasketService _basket; @@ -23,7 +24,7 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers [HttpPost] [HttpPut] - public async Task UpdateAllBasket([FromBody] UpdateBasketRequest data) + public async Task> UpdateAllBasket([FromBody] UpdateBasketRequest data) { if (data.Items == null || !data.Items.Any()) @@ -61,12 +62,13 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers } await _basket.Update(newBasket); - return Ok(newBasket); + + return newBasket; } [HttpPut] [Route("items")] - public async Task UpdateQuantities([FromBody] UpdateBasketItemsRequest data) + public async Task> UpdateQuantities([FromBody] UpdateBasketItemsRequest data) { if (!data.Updates.Any()) { @@ -93,12 +95,13 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers // Save the updated basket await _basket.Update(currentBasket); - return Ok(currentBasket); + + return currentBasket; } [HttpPost] [Route("items")] - public async Task AddBasketItem([FromBody] AddBasketItemRequest data) + public async Task AddBasketItem([FromBody] AddBasketItemRequest data) { if (data == null || data.Quantity == 0) { @@ -126,7 +129,6 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers // Step 4: Update basket await _basket.Update(currentBasket); - return Ok(); } } diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs index 4c18d25ae..f138b1ab6 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Controllers/OrderController.cs @@ -1,16 +1,14 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services; -using System; -using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers { [Route("api/v1/[controller]")] [Authorize] - public class OrderController : Controller + [ApiController] + public class OrderController : ControllerBase { private readonly IBasketService _basketService; private readonly IOrderApiClient _orderClient; diff --git a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs index 3a11975c7..ca11e28f9 100644 --- a/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs +++ b/src/ApiGateways/Mobile.Bff.Shopping/aggregator/Startup.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config; using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters; using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure; @@ -53,9 +54,14 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator { app.UseDeveloperExceptionPage(); } + else + { + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); + } app.UseAuthentication(); - + app.UseHttpsRedirection(); app.UseMvc(); app.UseSwagger().UseSwaggerUI(c => @@ -77,7 +83,8 @@ namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator services.AddOptions(); services.Configure(configuration.GetSection("urls")); - services.AddMvc(); + services.AddMvc() + .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddSwaggerGen(options => { diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/BasketController.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/BasketController.cs index bfef55726..5fc583ad4 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/BasketController.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/BasketController.cs @@ -11,7 +11,8 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers { [Route("api/v1/[controller]")] [Authorize] - public class BasketController : Controller + [ApiController] + public class BasketController : ControllerBase { private readonly ICatalogService _catalog; private readonly IBasketService _basket; @@ -23,7 +24,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers [HttpPost] [HttpPut] - public async Task UpdateAllBasket([FromBody] UpdateBasketRequest data) + public async Task> UpdateAllBasket([FromBody] UpdateBasketRequest data) { if (data.Items == null || !data.Items.Any()) @@ -61,12 +62,13 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers } await _basket.Update(newBasket); - return Ok(newBasket); + + return newBasket; } [HttpPut] [Route("items")] - public async Task UpdateQuantities([FromBody] UpdateBasketItemsRequest data) + public async Task> UpdateQuantities([FromBody] UpdateBasketItemsRequest data) { if (!data.Updates.Any()) { @@ -93,12 +95,13 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers // Save the updated basket await _basket.Update(currentBasket); - return Ok(currentBasket); + + return currentBasket; } [HttpPost] [Route("items")] - public async Task AddBasketItem([FromBody] AddBasketItemRequest data) + public async Task AddBasketItem([FromBody] AddBasketItemRequest data) { if (data == null || data.Quantity == 0) { diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/OrderController.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/OrderController.cs index fd108ffb8..d3a51e000 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/OrderController.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Controllers/OrderController.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models; using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services; using System; using System.Collections.Generic; @@ -10,7 +11,8 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers { [Route("api/v1/[controller]")] [Authorize] - public class OrderController : Controller + [ApiController] + public class OrderController : ControllerBase { private readonly IBasketService _basketService; private readonly IOrderApiClient _orderClient; @@ -22,7 +24,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers [Route("draft/{basketId}")] [HttpGet] - public async Task GetOrderDraft(string basketId) + public async Task> GetOrderDraft(string basketId) { if (string.IsNullOrEmpty(basketId)) { @@ -35,8 +37,7 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers return BadRequest($"No basket found for id {basketId}"); } - var orderDraft = await _orderClient.GetOrderDraftFromBasket(basket); - return Ok(orderDraft); + return await _orderClient.GetOrderDraftFromBasket(basket); } } } diff --git a/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs b/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs index e4a080289..1b545f7e7 100644 --- a/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs +++ b/src/ApiGateways/Web.Bff.Shopping/aggregator/Startup.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config; using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters; using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Infrastructure; @@ -53,9 +54,14 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator { app.UseDeveloperExceptionPage(); } + else + { + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); + } app.UseAuthentication(); - + app.UseHttpsRedirection(); app.UseMvc(); app.UseSwagger().UseSwaggerUI(c => @@ -104,7 +110,8 @@ namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator services.AddOptions(); services.Configure(configuration.GetSection("urls")); - services.AddMvc(); + services.AddMvc() + .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddSwaggerGen(options => { diff --git a/src/Services/Basket/Basket.API/Controllers/BasketController.cs b/src/Services/Basket/Basket.API/Controllers/BasketController.cs index c7fdac57d..f230efd84 100644 --- a/src/Services/Basket/Basket.API/Controllers/BasketController.cs +++ b/src/Services/Basket/Basket.API/Controllers/BasketController.cs @@ -13,7 +13,8 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers { [Route("api/v1/[controller]")] [Authorize] - public class BasketController : Controller + [ApiController] + public class BasketController : ControllerBase { private readonly IBasketRepository _repository; private readonly IIdentityService _identitySvc; @@ -31,32 +32,31 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers // GET /id [HttpGet("{id}")] [ProducesResponseType(typeof(CustomerBasket), (int)HttpStatusCode.OK)] - public async Task Get(string id) + public async Task> Get(string id) { var basket = await _repository.GetBasketAsync(id); + if (basket == null) { - return Ok(new CustomerBasket(id) { }); + return new CustomerBasket(id); } - return Ok(basket); + return basket; } // POST /value [HttpPost] [ProducesResponseType(typeof(CustomerBasket), (int)HttpStatusCode.OK)] - public async Task Post([FromBody]CustomerBasket value) + public async Task> Post([FromBody]CustomerBasket value) { - var basket = await _repository.UpdateBasketAsync(value); - - return Ok(basket); + return await _repository.UpdateBasketAsync(value); } [Route("checkout")] [HttpPost] [ProducesResponseType((int)HttpStatusCode.Accepted)] [ProducesResponseType((int)HttpStatusCode.BadRequest)] - public async Task Checkout([FromBody]BasketCheckout basketCheckout, [FromHeader(Name = "x-requestid")] string requestId) + public async Task Checkout([FromBody]BasketCheckout basketCheckout, [FromHeader(Name = "x-requestid")] string requestId) { var userId = _identitySvc.GetUserIdentity(); @@ -91,6 +91,5 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers { _repository.DeleteBasketAsync(id); } - } } diff --git a/src/Services/Basket/Basket.API/Startup.cs b/src/Services/Basket/Basket.API/Startup.cs index 7d65ba8b4..cc100789d 100644 --- a/src/Services/Basket/Basket.API/Startup.cs +++ b/src/Services/Basket/Basket.API/Startup.cs @@ -10,6 +10,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.ServiceBus; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; @@ -51,11 +52,13 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API // Add framework services. services.AddMvc(options => - { - options.Filters.Add(typeof(HttpGlobalExceptionFilter)); - options.Filters.Add(typeof(ValidateModelStateFilter)); + { + options.Filters.Add(typeof(HttpGlobalExceptionFilter)); + options.Filters.Add(typeof(ValidateModelStateFilter)); - }).AddControllersAsServices(); + }) + .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) + .AddControllersAsServices(); ConfigureAuthService(services); diff --git a/src/Services/Basket/Basket.UnitTests/Application/BasketWebApiTest.cs b/src/Services/Basket/Basket.UnitTests/Application/BasketWebApiTest.cs index 88dda058d..522eb6e44 100644 --- a/src/Services/Basket/Basket.UnitTests/Application/BasketWebApiTest.cs +++ b/src/Services/Basket/Basket.UnitTests/Application/BasketWebApiTest.cs @@ -44,10 +44,10 @@ namespace UnitTest.Basket.Application //Act var basketController = new BasketController( _basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object); - var actionResult = await basketController.Get(fakeCustomerId) as OkObjectResult; + var actionResult = await basketController.Get(fakeCustomerId); //Assert - Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK); + Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK); Assert.Equal(((CustomerBasket)actionResult.Value).BuyerId, fakeCustomerId); } @@ -67,10 +67,10 @@ namespace UnitTest.Basket.Application var basketController = new BasketController( _basketRepositoryMock.Object, _identityServiceMock.Object, _serviceBusMock.Object); - var actionResult = await basketController.Post(fakeCustomerBasket) as OkObjectResult; + var actionResult = await basketController.Post(fakeCustomerBasket); //Assert - Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK); + Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK); Assert.Equal(((CustomerBasket)actionResult.Value).BuyerId, fakeCustomerId); } diff --git a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs index 584f7a0af..6bbe9a092 100644 --- a/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs +++ b/src/Services/Catalog/Catalog.API/Controllers/CatalogController.cs @@ -84,7 +84,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [Route("items/{id:int}")] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType(typeof(CatalogItem), (int)HttpStatusCode.OK)] - public async Task GetItemById(int id) + public async Task> GetItemById(int id) { if (id <= 0) { @@ -99,7 +99,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers if (item != null) { - return Ok(item); + return item; } return NotFound(); @@ -109,9 +109,8 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [HttpGet] [Route("[action]/withname/{name:minlength(1)}")] [ProducesResponseType(typeof(PaginatedItemsViewModel), (int)HttpStatusCode.OK)] - public async Task Items(string name, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) + public async Task>> Items(string name, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) { - var totalItems = await _catalogContext.CatalogItems .Where(c => c.Name.StartsWith(name)) .LongCountAsync(); @@ -124,17 +123,14 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers itemsOnPage = ChangeUriPlaceholder(itemsOnPage); - var model = new PaginatedItemsViewModel( - pageIndex, pageSize, totalItems, itemsOnPage); - - return Ok(model); + return new PaginatedItemsViewModel(pageIndex, pageSize, totalItems, itemsOnPage); } // GET api/v1/[controller]/items/type/1/brand[?pageSize=3&pageIndex=10] [HttpGet] [Route("[action]/type/{catalogTypeId}/brand/{catalogBrandId:int?}")] [ProducesResponseType(typeof(PaginatedItemsViewModel), (int)HttpStatusCode.OK)] - public async Task Items(int catalogTypeId, int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) + public async Task>> Items(int catalogTypeId, int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) { var root = (IQueryable)_catalogContext.CatalogItems; @@ -155,16 +151,13 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers itemsOnPage = ChangeUriPlaceholder(itemsOnPage); - var model = new PaginatedItemsViewModel( - pageIndex, pageSize, totalItems, itemsOnPage); - - return Ok(model); + return new PaginatedItemsViewModel(pageIndex, pageSize, totalItems, itemsOnPage); } // GET api/v1/[controller]/items/type/all/brand[?pageSize=3&pageIndex=10] [HttpGet] [Route("[action]/type/all/brand/{catalogBrandId:int?}")] [ProducesResponseType(typeof(PaginatedItemsViewModel), (int)HttpStatusCode.OK)] - public async Task Items(int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) + public async Task>> Items(int? catalogBrandId, [FromQuery]int pageSize = 10, [FromQuery]int pageIndex = 0) { var root = (IQueryable)_catalogContext.CatalogItems; @@ -183,34 +176,25 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers itemsOnPage = ChangeUriPlaceholder(itemsOnPage); - var model = new PaginatedItemsViewModel( - pageIndex, pageSize, totalItems, itemsOnPage); - - return Ok(model); + return new PaginatedItemsViewModel(pageIndex, pageSize, totalItems, itemsOnPage); } // GET api/v1/[controller]/CatalogTypes [HttpGet] [Route("[action]")] - [ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)] - public async Task CatalogTypes() + [ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)] + public async Task>> CatalogTypes() { - var items = await _catalogContext.CatalogTypes - .ToListAsync(); - - return Ok(items); + return await _catalogContext.CatalogTypes.ToListAsync(); } // GET api/v1/[controller]/CatalogBrands [HttpGet] [Route("[action]")] - [ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)] - public async Task CatalogBrands() + [ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)] + public async Task>> CatalogBrands() { - var items = await _catalogContext.CatalogBrands - .ToListAsync(); - - return Ok(items); + return await _catalogContext.CatalogBrands.ToListAsync(); } //PUT api/v1/[controller]/items @@ -218,7 +202,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [HttpPut] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType((int)HttpStatusCode.Created)] - public async Task UpdateProduct([FromBody]CatalogItem productToUpdate) + public async Task UpdateProduct([FromBody]CatalogItem productToUpdate) { var catalogItem = await _catalogContext.CatalogItems .SingleOrDefaultAsync(i => i.Id == productToUpdate.Id); @@ -259,7 +243,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [Route("items")] [HttpPost] [ProducesResponseType((int)HttpStatusCode.Created)] - public async Task CreateProduct([FromBody]CatalogItem product) + public async Task CreateProduct([FromBody]CatalogItem product) { var item = new CatalogItem { @@ -281,7 +265,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [Route("{id}")] [HttpDelete] [ProducesResponseType((int)HttpStatusCode.NoContent)] - public async Task DeleteProduct(int id) + public async Task DeleteProduct(int id) { var product = _catalogContext.CatalogItems.SingleOrDefault(x => x.Id == id); diff --git a/src/Services/Catalog/Catalog.API/Controllers/PicController.cs b/src/Services/Catalog/Catalog.API/Controllers/PicController.cs index c7af86eed..6ea7c802c 100644 --- a/src/Services/Catalog/Catalog.API/Controllers/PicController.cs +++ b/src/Services/Catalog/Catalog.API/Controllers/PicController.cs @@ -9,8 +9,9 @@ using System.Threading.Tasks; // For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860 namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers -{ - public class PicController : Controller +{ + [ApiController] + public class PicController : ControllerBase { private readonly IHostingEnvironment _env; private readonly CatalogContext _catalogContext; @@ -27,7 +28,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType((int)HttpStatusCode.BadRequest)] // GET: // - public async Task GetImage(int catalogItemId) + public async Task GetImage(int catalogItemId) { if (catalogItemId <= 0) { diff --git a/src/Services/Catalog/Catalog.API/Startup.cs b/src/Services/Catalog/Catalog.API/Startup.cs index 408f870af..5a979e306 100644 --- a/src/Services/Catalog/Catalog.API/Startup.cs +++ b/src/Services/Catalog/Catalog.API/Startup.cs @@ -139,9 +139,11 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API }); services.AddMvc(options => - { - options.Filters.Add(typeof(HttpGlobalExceptionFilter)); - }).AddControllersAsServices(); + { + options.Filters.Add(typeof(HttpGlobalExceptionFilter)); + }) + .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) + .AddControllersAsServices(); services.AddCors(options => { diff --git a/src/Services/Identity/Identity.API/Startup.cs b/src/Services/Identity/Identity.API/Startup.cs index 789047657..049bac090 100644 --- a/src/Services/Identity/Identity.API/Startup.cs +++ b/src/Services/Identity/Identity.API/Startup.cs @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.eShopOnContainers.Services.Identity.API.Certificates; using Microsoft.eShopOnContainers.Services.Identity.API.Data; @@ -52,7 +53,8 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API services.Configure(Configuration); - services.AddMvc(); + services.AddMvc() + .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); if (Configuration.GetValue("IsClusterEnv") == bool.TrueString) { @@ -159,6 +161,7 @@ namespace Microsoft.eShopOnContainers.Services.Identity.API // Adds IdentityServer app.UseIdentityServer(); + app.UseHttpsRedirection(); app.UseMvc(routes => { routes.MapRoute( diff --git a/src/Services/Location/Locations.API/Controllers/LocationsController.cs b/src/Services/Location/Locations.API/Controllers/LocationsController.cs index 45f4d2ba7..09f529449 100644 --- a/src/Services/Location/Locations.API/Controllers/LocationsController.cs +++ b/src/Services/Location/Locations.API/Controllers/LocationsController.cs @@ -12,6 +12,7 @@ namespace Locations.API.Controllers { [Route("api/v1/[controller]")] [Authorize] + [ApiController] public class LocationsController : ControllerBase { private readonly ILocationsService _locationsService; @@ -27,30 +28,27 @@ namespace Locations.API.Controllers [Route("user/{userId:guid}")] [HttpGet] [ProducesResponseType(typeof(UserLocation), (int)HttpStatusCode.OK)] - public async Task GetUserLocation(Guid userId) + public async Task> GetUserLocation(Guid userId) { - var userLocation = await _locationsService.GetUserLocation(userId.ToString()); - return Ok(userLocation); + return await _locationsService.GetUserLocation(userId.ToString()); } //GET api/v1/[controller]/ [Route("")] [HttpGet] - //[ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)] - public async Task GetAllLocations() + [ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)] + public async Task>> GetAllLocations() { - var locations = await _locationsService.GetAllLocation(); - return Ok(locations); + return await _locationsService.GetAllLocation(); } //GET api/v1/[controller]/1 [Route("{locationId}")] [HttpGet] - //[ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)] - public async Task GetLocation(int locationId) + [ProducesResponseType(typeof(Microsoft.eShopOnContainers.Services.Locations.API.Model.Locations), (int)HttpStatusCode.OK)] + public async Task> GetLocation(int locationId) { - var location = await _locationsService.GetLocation(locationId); - return Ok(location); + return await _locationsService.GetLocation(locationId); } //POST api/v1/[controller]/ diff --git a/src/Services/Location/Locations.API/Startup.cs b/src/Services/Location/Locations.API/Startup.cs index be0263312..eaad3c921 100644 --- a/src/Services/Location/Locations.API/Startup.cs +++ b/src/Services/Location/Locations.API/Startup.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.ServiceBus; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus; using Microsoft.eShopOnContainers.BuildingBlocks.EventBus.Abstractions; @@ -43,9 +44,11 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API RegisterAppInsights(services); services.AddMvc(options => - { - options.Filters.Add(typeof(HttpGlobalExceptionFilter)); - }).AddControllersAsServices(); + { + options.Filters.Add(typeof(HttpGlobalExceptionFilter)); + }) + .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) + .AddControllersAsServices(); ConfigureAuthService(services); diff --git a/src/Services/Marketing/Marketing.API/Controllers/CampaignsController.cs b/src/Services/Marketing/Marketing.API/Controllers/CampaignsController.cs index 313d4d77b..95d14c475 100644 --- a/src/Services/Marketing/Marketing.API/Controllers/CampaignsController.cs +++ b/src/Services/Marketing/Marketing.API/Controllers/CampaignsController.cs @@ -20,7 +20,8 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers [Route("api/v1/[controller]")] [Authorize] - public class CampaignsController : Controller + [ApiController] + public class CampaignsController : ControllerBase { private readonly MarketingContext _context; private readonly MarketingSettings _settings; @@ -40,25 +41,22 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers [HttpGet] [ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)] - public async Task GetAllCampaigns() + public async Task>> GetAllCampaigns() { - var campaignList = await _context.Campaigns - .ToListAsync(); + var campaignList = await _context.Campaigns.ToListAsync(); if (campaignList is null) { return Ok(); } - var campaignDtoList = MapCampaignModelListToDtoList(campaignList); - - return Ok(campaignDtoList); + return MapCampaignModelListToDtoList(campaignList); } [HttpGet("{id:int}")] [ProducesResponseType(typeof(CampaignDTO), (int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.NotFound)] - public async Task GetCampaignById(int id) + public async Task> GetCampaignById(int id) { var campaign = await _context.Campaigns .SingleOrDefaultAsync(c => c.Id == id); @@ -68,15 +66,13 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers return NotFound(); } - var campaignDto = MapCampaignModelToDto(campaign); - - return Ok(campaignDto); + return MapCampaignModelToDto(campaign); } [HttpPost] [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.Created)] - public async Task CreateCampaign([FromBody] CampaignDTO campaignDto) + public async Task CreateCampaign([FromBody] CampaignDTO campaignDto) { if (campaignDto is null) { @@ -95,7 +91,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType((int)HttpStatusCode.Created)] - public async Task UpdateCampaign(int id, [FromBody] CampaignDTO campaignDto) + public async Task UpdateCampaign(int id, [FromBody] CampaignDTO campaignDto) { if (id < 1 || campaignDto is null) { @@ -123,7 +119,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType((int)HttpStatusCode.NoContent)] - public async Task Delete(int id) + public async Task Delete(int id) { if (id < 1) { @@ -144,7 +140,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers [HttpGet("user")] [ProducesResponseType(typeof(PaginatedItemsViewModel), (int)HttpStatusCode.OK)] - public async Task GetCampaignsByUserId( int pageSize = 10, int pageIndex = 0) + public async Task>> GetCampaignsByUserId( int pageSize = 10, int pageIndex = 0) { var userId = _identityService.GetUserIdentity(); @@ -177,10 +173,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers .Skip(pageSize * pageIndex) .Take(pageSize).ToList(); - var model = new PaginatedItemsViewModel( - pageIndex, pageSize, totalItems, campaignDtoList); - - return Ok(model); + return new PaginatedItemsViewModel(pageIndex, pageSize, totalItems, campaignDtoList); } diff --git a/src/Services/Marketing/Marketing.API/Controllers/LocationsController.cs b/src/Services/Marketing/Marketing.API/Controllers/LocationsController.cs index 0d47a63a4..98bef1e70 100644 --- a/src/Services/Marketing/Marketing.API/Controllers/LocationsController.cs +++ b/src/Services/Marketing/Marketing.API/Controllers/LocationsController.cs @@ -11,7 +11,8 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers using System.Threading.Tasks; [Authorize] - public class LocationsController : Controller + [ApiController] + public class LocationsController : ControllerBase { private readonly MarketingContext _context; @@ -25,7 +26,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType(typeof(UserLocationRuleDTO),(int)HttpStatusCode.OK)] - public IActionResult GetLocationByCampaignAndLocationRuleId(int campaignId, + public ActionResult GetLocationByCampaignAndLocationRuleId(int campaignId, int userLocationRuleId) { if (campaignId < 1 || userLocationRuleId < 1) @@ -42,9 +43,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers return NotFound(); } - var locationDto = MapUserLocationRuleModelToDto(location); - - return Ok(locationDto); + return MapUserLocationRuleModelToDto(location); } [HttpGet] @@ -52,7 +51,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.OK)] [ProducesResponseType(typeof(List), (int)HttpStatusCode.OK)] - public IActionResult GetAllLocationsByCampaignId(int campaignId) + public ActionResult> GetAllLocationsByCampaignId(int campaignId) { if (campaignId < 1) { @@ -69,17 +68,14 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers return Ok(); } - var locationDtoList = MapUserLocationRuleModelListToDtoList(locationList); - - return Ok(locationDtoList); + return MapUserLocationRuleModelListToDtoList(locationList); } [HttpPost] [Route("api/v1/campaigns/{campaignId:int}/locations")] [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.Created)] - public async Task CreateLocation(int campaignId, - [FromBody] UserLocationRuleDTO locationRuleDto) + public async Task CreateLocation(int campaignId, [FromBody] UserLocationRuleDTO locationRuleDto) { if (campaignId < 1 || locationRuleDto is null) { @@ -100,7 +96,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Controllers [Route("api/v1/campaigns/{campaignId:int}/locations/{userLocationRuleId:int}")] [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType((int)HttpStatusCode.NotFound)] - public async Task DeleteLocationById(int campaignId, int userLocationRuleId) + public async Task DeleteLocationById(int campaignId, int userLocationRuleId) { if (campaignId < 1 || userLocationRuleId < 1) { diff --git a/src/Services/Marketing/Marketing.API/Controllers/PicController.cs b/src/Services/Marketing/Marketing.API/Controllers/PicController.cs index 9c2b73c36..66ce1e750 100644 --- a/src/Services/Marketing/Marketing.API/Controllers/PicController.cs +++ b/src/Services/Marketing/Marketing.API/Controllers/PicController.cs @@ -4,8 +4,8 @@ using Microsoft.AspNetCore.Mvc; using System.IO; - - public class PicController : Controller + [ApiController] + public class PicController : ControllerBase { private readonly IHostingEnvironment _env; public PicController(IHostingEnvironment env) @@ -15,7 +15,7 @@ [HttpGet] [Route("api/v1/campaigns/{campaignId:int}/pic")] - public IActionResult GetImage(int campaignId) + public ActionResult GetImage(int campaignId) { var webRoot = _env.WebRootPath; var path = Path.Combine(webRoot, campaignId + ".png"); diff --git a/src/Services/Marketing/Marketing.API/Startup.cs b/src/Services/Marketing/Marketing.API/Startup.cs index 5683dc72d..04fdc07a2 100644 --- a/src/Services/Marketing/Marketing.API/Startup.cs +++ b/src/Services/Marketing/Marketing.API/Startup.cs @@ -24,6 +24,7 @@ using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.ServiceFabric; using Microsoft.AspNetCore.Authentication.JwtBearer; + using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.Middlewares; using RabbitMQ.Client; @@ -53,7 +54,9 @@ services.AddMvc(options => { options.Filters.Add(typeof(HttpGlobalExceptionFilter)); - }).AddControllersAsServices(); //Injecting Controllers themselves thru DIFor further info see: http://docs.autofac.org/en/latest/integration/aspnetcore.html#controllers-as-services + }) + .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) + .AddControllersAsServices(); //Injecting Controllers themselves thru DIFor further info see: http://docs.autofac.org/en/latest/integration/aspnetcore.html#controllers-as-services services.Configure(Configuration); diff --git a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs index 5542caf11..0f6cbc69c 100644 --- a/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs +++ b/src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs @@ -15,7 +15,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers [Route("api/v1/[controller]")] [Authorize] [ApiController] - public class OrdersController : Controller + public class OrdersController : ControllerBase { private readonly IMediator _mediator; private readonly IOrderQueries _orderQueries; @@ -67,12 +67,11 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers [HttpGet] [ProducesResponseType(typeof(Order),(int)HttpStatusCode.OK)] [ProducesResponseType((int)HttpStatusCode.NotFound)] - public async Task GetOrder(int orderId) + public async Task GetOrder(int orderId) { try { - var order = await _orderQueries - .GetOrderAsync(orderId); + var order = await _orderQueries.GetOrderAsync(orderId); return Ok(order); } @@ -85,7 +84,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers [Route("")] [HttpGet] [ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)] - public async Task GetOrders() + public async Task>> GetOrders() { var userid = _identityService.GetUserIdentity(); var orders = await _orderQueries.GetOrdersFromUserAsync(Guid.Parse(userid)); @@ -95,7 +94,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers [Route("cardtypes")] [HttpGet] [ProducesResponseType(typeof(IEnumerable), (int)HttpStatusCode.OK)] - public async Task GetCardTypes() + public async Task>> GetCardTypes() { var cardTypes = await _orderQueries .GetCardTypesAsync(); @@ -105,10 +104,9 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers [Route("draft")] [HttpPost] - public async Task GetOrderDraftFromBasketData([FromBody] CreateOrderDraftCommand createOrderDraftCommand) + public async Task> GetOrderDraftFromBasketData([FromBody] CreateOrderDraftCommand createOrderDraftCommand) { - var draft = await _mediator.Send(createOrderDraftCommand); - return Ok(draft); + return await _mediator.Send(createOrderDraftCommand); } } } diff --git a/src/Services/Ordering/Ordering.API/Startup.cs b/src/Services/Ordering/Ordering.API/Startup.cs index 42567641a..79a5e28a4 100644 --- a/src/Services/Ordering/Ordering.API/Startup.cs +++ b/src/Services/Ordering/Ordering.API/Startup.cs @@ -154,9 +154,11 @@ { // Add framework services. services.AddMvc(options => - { - options.Filters.Add(typeof(HttpGlobalExceptionFilter)); - }).AddControllersAsServices(); //Injecting Controllers themselves thru DI + { + options.Filters.Add(typeof(HttpGlobalExceptionFilter)); + }) + .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) + .AddControllersAsServices(); //Injecting Controllers themselves thru DI //For further info see: http://docs.autofac.org/en/latest/integration/aspnetcore.html#controllers-as-services services.AddCors(options => diff --git a/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs b/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs index aadd6c62a..066a7078c 100644 --- a/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs +++ b/src/Services/Ordering/Ordering.UnitTests/Application/OrdersWebApiTest.cs @@ -103,10 +103,10 @@ namespace UnitTest.Ordering.Application //Act var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object); - var actionResult = await orderController.GetOrders() as OkObjectResult; + var actionResult = await orderController.GetOrders(); //Assert - Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK); + Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK); } [Fact] @@ -136,10 +136,10 @@ namespace UnitTest.Ordering.Application //Act var orderController = new OrdersController(_mediatorMock.Object, _orderQueriesMock.Object, _identityServiceMock.Object); - var actionResult = await orderController.GetCardTypes() as OkObjectResult; + var actionResult = await orderController.GetCardTypes(); //Assert - Assert.Equal(actionResult.StatusCode, (int)System.Net.HttpStatusCode.OK); + Assert.Equal((actionResult.Result as OkObjectResult).StatusCode, (int)System.Net.HttpStatusCode.OK); } } } diff --git a/src/Web/WebMVC/Startup.cs b/src/Web/WebMVC/Startup.cs index fe1f5de21..c313f87fd 100644 --- a/src/Web/WebMVC/Startup.cs +++ b/src/Web/WebMVC/Startup.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; using Microsoft.eShopOnContainers.WebMVC.Services; using Microsoft.eShopOnContainers.WebMVC.ViewModels; using Microsoft.Extensions.Configuration; @@ -59,6 +60,7 @@ namespace Microsoft.eShopOnContainers.WebMVC else { app.UseExceptionHandler("/Error"); + app.UseHsts(); } var pathBase = Configuration["PATH_BASE"]; @@ -87,6 +89,7 @@ namespace Microsoft.eShopOnContainers.WebMVC WebContextSeed.Seed(app, env, loggerFactory); + app.UseHttpsRedirection(); app.UseMvc(routes => { routes.MapRoute( @@ -149,7 +152,8 @@ namespace Microsoft.eShopOnContainers.WebMVC services.AddOptions(); services.Configure(configuration); - services.AddMvc(); + services.AddMvc() + .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddSession(); diff --git a/src/Web/WebSPA/Startup.cs b/src/Web/WebSPA/Startup.cs index f49eba772..c979dbafb 100644 --- a/src/Web/WebSPA/Startup.cs +++ b/src/Web/WebSPA/Startup.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Antiforgery; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.HealthChecks; @@ -71,6 +72,7 @@ namespace eShopConContainers.WebSPA services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN"); services.AddMvc() + .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) .AddJsonOptions(options => { options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); @@ -89,6 +91,11 @@ namespace eShopConContainers.WebSPA { app.UseDeveloperExceptionPage(); } + else + { + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); + } // Configure XSRF middleware, This pattern is for SPA style applications where XSRF token is added on Index page // load and passed back token on every subsequent async request diff --git a/src/Web/WebStatus/Startup.cs b/src/Web/WebStatus/Startup.cs index 6a9ed32d1..b4a1049d8 100644 --- a/src/Web/WebStatus/Startup.cs +++ b/src/Web/WebStatus/Startup.cs @@ -10,6 +10,7 @@ using Microsoft.Extensions.Logging; using WebStatus.Extensions; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.ApplicationInsights.ServiceFabric; +using Microsoft.AspNetCore.Mvc; namespace WebStatus { @@ -50,7 +51,8 @@ namespace WebStatus checks.AddUrlCheckIfNotNull(Configuration["spa"], TimeSpan.Zero); //No cache for this HealthCheck, better just for demos }); - services.AddMvc(); + services.AddMvc() + .SetCompatibilityVersion(CompatibilityVersion.Version_2_2); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -66,6 +68,8 @@ namespace WebStatus else { app.UseExceptionHandler("/Home/Error"); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); } var pathBase = Configuration["PATH_BASE"]; @@ -74,13 +78,14 @@ namespace WebStatus app.UsePathBase(pathBase); } - #pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously app.Map("/liveness", lapp => lapp.Run(async ctx => ctx.Response.StatusCode = 200)); #pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously app.UseStaticFiles(); + app.UseHttpsRedirection(); + app.UseMvc(routes => { routes.MapRoute(