Browse Source

Add Swagger to Basket Api

SQL databases with the same prefix for services
Move application tier to api tier in ordering api
pull/49/merge
Carlos Cañizares Estévez 8 years ago
parent
commit
10f3e17b55
26 changed files with 429 additions and 83 deletions
  1. +22
    -21
      docker-compose.override.yml
  2. +11
    -9
      docker-compose.yml
  3. +19
    -0
      src/Services/Basket/Basket.API/Controllers/HomeController.cs
  4. +19
    -1
      src/Services/Basket/Basket.API/Startup.cs
  5. +2
    -1
      src/Services/Basket/Basket.API/project.json
  6. +1
    -1
      src/Services/Catalog/Catalog.API/settings.json
  7. +12
    -0
      src/Services/Identity/eShopOnContainers.Identity/AppSettings.cs
  8. +1
    -1
      src/Services/Identity/eShopOnContainers.Identity/Configuration/Config.cs
  9. +2
    -16
      src/Services/Identity/eShopOnContainers.Identity/Controllers/AccountController.cs
  10. +9
    -2
      src/Services/Identity/eShopOnContainers.Identity/Controllers/HomeController.cs
  11. +2
    -2
      src/Services/Identity/eShopOnContainers.Identity/Startup.cs
  12. +0
    -14
      src/Services/Identity/eShopOnContainers.Identity/Views/Shared/_Layout.cshtml
  13. +1
    -1
      src/Services/Identity/eShopOnContainers.Identity/appsettings.json
  14. +2
    -2
      src/Services/Identity/eShopOnContainers.Identity/docker-compose.yml
  15. +48
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/NewOrderRequest.cs
  16. +118
    -0
      src/Services/Ordering/Ordering.API/Application/Commands/NewOrderRequestHandler.cs
  17. +34
    -0
      src/Services/Ordering/Ordering.API/Application/Decorators/LogDecorator.cs
  18. +13
    -0
      src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs
  19. +101
    -0
      src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs
  20. +3
    -3
      src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs
  21. +1
    -1
      src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs
  22. +2
    -2
      src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs
  23. +3
    -3
      src/Services/Ordering/Ordering.API/project.json
  24. +1
    -1
      src/Web/WebMVC/Services/OrderingService.cs
  25. +1
    -1
      src/Web/WebMVC/wwwroot/css/site.min.css
  26. +1
    -1
      src/Web/WebSPA/eShopOnContainers.WebSPA/Program.cs

+ 22
- 21
docker-compose.override.yml View File

@ -9,21 +9,22 @@ version: '2'
services: services:
# webmvc:
# environment:
# - CatalogUrl=http://catalog.api
# - OrderingUrl=http://ordering.api:5102
#- IdentityUrl=http://104.40.62.65:5105 #Remote: VM Needs to have public access at 5105.
# - IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
# - BasketUrl=http://basket.api:5103
# ports:
# - "5100:5100"
webmvc:
environment:
- CatalogUrl=http://catalog.api
- OrderingUrl=http://ordering.api:5102
#- IdentityUrl=http://13.88.8.119:5105 #Remote: VM Needs to have public access at 5105.
#- IdentityUrl=http://10.0.75.1:5105 #Local: You need to open windows firewall at range 5100-5105.
- IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
- BasketUrl=http://basket.api:5103
ports:
- "5100:5100"
webspa: webspa:
environment: environment:
- CatalogUrl=http://catalog.api - CatalogUrl=http://catalog.api
- OrderingUrl=http://ordering.api - OrderingUrl=http://ordering.api
#- IdentityUrl=http://104.40.62.65:5105 #Remote: VM Needs to have public access at 5105.
#- IdentityUrl=http://13.88.8.119:5105 #Remote: VM Needs to have public access at 5105.
- IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker. - IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
- BasketUrl=http://basket.api:5103 - BasketUrl=http://basket.api:5103
ports: ports:
@ -32,30 +33,30 @@ services:
basket.api: basket.api:
environment: environment:
- ConnectionString=basket.data - ConnectionString=basket.data
#- identityUrl=http://104.40.62.65:5105 #Remote: VM Needs to have public access at 5105.
#- identityUrl=http://13.88.8.119:5105 #Remote
- identityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker. - identityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
ports: ports:
- "5103:5103" - "5103:5103"
catalog.api: catalog.api:
environment: environment:
- ConnectionString=Server=sql.data;Database=CatalogDB;User Id=sa;Password=Pass@word
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word
ports: ports:
- "5101:80" - "5101:80"
# ordering.api:
# environment:
# - ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
# - identityUrl=http://identity.service:5105 #local
#- identityUrl=http://104.40.62.65:5105 #remote
# ports:
# - "5102:5102"
ordering.api:
environment:
- ConnectionString=Server=sql.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
- identityUrl=http://identity.service:5105 #local
#- identityUrl=http://13.88.8.119:5105 #remote
ports:
- "5102:5102"
identity.service: identity.service:
environment: environment:
- SpaClient=http://localhost:5104 - SpaClient=http://localhost:5104
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word
#- MvcClient=http://104.40.62.65:5100 #Remote: VM Needs to have public access at 5105.
- ConnectionStrings__DefaultConnection=Server=sql.data;Database=Microsoft.eShopOnContainers.Service.IdentityDb;User Id=sa;Password=Pass@word
#- MvcClient=http://13.88.8.119:5100 #Remote: VM Needs to have public access at 5105.
- MvcClient=http://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker. - MvcClient=http://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker.
#10.0.75.1:5105 CCE/TODO: try to avoid host entry. #10.0.75.1:5105 CCE/TODO: try to avoid host entry.
ports: ports:


+ 11
- 9
docker-compose.yml View File

@ -7,11 +7,13 @@
version: '2' version: '2'
services: services:
# webmvc:
# image: eshop/web
# depends_on:
# - identity.service
# - basket.api
webmvc:
image: eshop/web
links:
- identity.service:localhost
depends_on:
- identity.service
- basket.api
webspa: webspa:
image: eshop/webspa image: eshop/webspa
@ -30,10 +32,10 @@ services:
depends_on: depends_on:
- sql.data - sql.data
# ordering.api:
# image: eshop/ordering.api
# depends_on:
# - sql.data
ordering.api:
image: eshop/ordering.api
depends_on:
- sql.data
identity.service: identity.service:
image: eshop/identity image: eshop/identity


+ 19
- 0
src/Services/Basket/Basket.API/Controllers/HomeController.cs View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
// For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
namespace Microsoft.eShopOnContainers.Services.Basket.API.Controllers
{
public class HomeController : Controller
{
// GET: /<controller>/
public IActionResult Index()
{
return new RedirectResult("~/swagger/ui");
}
}
}

+ 19
- 1
src/Services/Basket/Basket.API/Startup.cs View File

@ -47,6 +47,20 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
return ConnectionMultiplexer.Connect(ips.First().ToString()); return ConnectionMultiplexer.Connect(ips.First().ToString());
}); });
services.AddSwaggerGen();
services.ConfigureSwaggerGen(options =>
{
options.DescribeAllEnumsAsStrings();
options.SingleApiVersion(new Swashbuckle.Swagger.Model.Info()
{
Title = "Basket HTTP API",
Version = "v1",
Description = "The Basket Service HTTP API",
TermsOfService = "Terms Of Service"
});
});
services.AddCors(options => services.AddCors(options =>
{ {
options.AddPolicy("CorsPolicy", options.AddPolicy("CorsPolicy",
@ -77,7 +91,11 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
RequireHttpsMetadata = false RequireHttpsMetadata = false
}); });
app.UseMvc();
app.UseMvcWithDefaultRoute();
app.UseSwagger()
.UseSwaggerUi();
} }
} }
} }

+ 2
- 1
src/Services/Basket/Basket.API/project.json View File

@ -17,7 +17,8 @@
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"StackExchange.Redis": "1.1.608", "StackExchange.Redis": "1.1.608",
"Newtonsoft.Json": "9.0.1", "Newtonsoft.Json": "9.0.1",
"IdentityServer4.AccessTokenValidation": "1.0.1-rc3"
"IdentityServer4.AccessTokenValidation": "1.0.1-rc3",
"Swashbuckle": "6.0.0-beta902"
}, },
"tools": { "tools": {
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"


+ 1
- 1
src/Services/Catalog/Catalog.API/settings.json View File

@ -1,5 +1,5 @@
{ {
"ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=CatalogDB;User Id=sa;Password=Pass@word",
"ConnectionString": "Server=tcp:127.0.0.1,5433;Initial Catalog=Microsoft.eShopOnContainers.Services.CatalogDb;User Id=sa;Password=Pass@word",
"Logging": { "Logging": {
"IncludeScopes": false, "IncludeScopes": false,
"LogLevel": { "LogLevel": {


+ 12
- 0
src/Services/Identity/eShopOnContainers.Identity/AppSettings.cs View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace eShopOnContainers.Identity
{
public class AppSettings
{
public string MvcClient { get; set; }
}
}

+ 1
- 1
src/Services/Identity/eShopOnContainers.Identity/Configuration/Config.cs View File

@ -78,7 +78,7 @@ namespace eShopOnContainers.Identity.Configuration
new Secret("secret".Sha256()) new Secret("secret".Sha256())
}, },
ClientUri = $"{clientsUrl["Mvc"]}", // public uri of the client ClientUri = $"{clientsUrl["Mvc"]}", // public uri of the client
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
AllowedGrantTypes = GrantTypes.Hybrid,
RedirectUris = new List<string> RedirectUris = new List<string>
{ {
$"{clientsUrl["Mvc"]}/signin-oidc", $"{clientsUrl["Mvc"]}/signin-oidc",


+ 2
- 16
src/Services/Identity/eShopOnContainers.Identity/Controllers/AccountController.cs View File

@ -85,15 +85,9 @@ namespace IdentityServer4.Quickstart.UI.Controllers
if (ModelState.IsValid) if (ModelState.IsValid)
{ {
var user = await _loginService.FindByUsername(model.Email); var user = await _loginService.FindByUsername(model.Email);
// validate username/password against in-memory store
if (await _loginService.ValidateCredentials(user, model.Password)) if (await _loginService.ValidateCredentials(user, model.Password))
{ {
// issue authentication cookie with subject ID and username
//var user = _loginService.FindByUsername(model.Username);
AuthenticationProperties props = null;
// only set explicit expiration here if persistent.
// otherwise we reply upon expiration configured in cookie middleware.
AuthenticationProperties props = null;
if (model.RememberMe) if (model.RememberMe)
{ {
props = new AuthenticationProperties props = new AuthenticationProperties
@ -217,15 +211,7 @@ namespace IdentityServer4.Quickstart.UI.Controllers
// get context information (client name, post logout redirect URI and iframe for federated signout) // get context information (client name, post logout redirect URI and iframe for federated signout)
var logout = await _interaction.GetLogoutContextAsync(model.LogoutId); var logout = await _interaction.GetLogoutContextAsync(model.LogoutId);
var vm = new LoggedOutViewModel
{
PostLogoutRedirectUri = logout?.PostLogoutRedirectUri,
ClientName = logout?.ClientId,
SignOutIframeUrl = logout?.SignOutIFrameUrl
};
return View("LoggedOut", vm);
return Redirect(logout?.PostLogoutRedirectUri);
} }
/// <summary> /// <summary>


+ 9
- 2
src/Services/Identity/eShopOnContainers.Identity/Controllers/HomeController.cs View File

@ -2,9 +2,11 @@
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
using eShopOnContainers.Identity;
using IdentityServer4.Quickstart.UI.Models; using IdentityServer4.Quickstart.UI.Models;
using IdentityServer4.Services; using IdentityServer4.Services;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace IdentityServer4.Quickstart.UI.Controllers namespace IdentityServer4.Quickstart.UI.Controllers
@ -12,14 +14,19 @@ namespace IdentityServer4.Quickstart.UI.Controllers
public class HomeController : Controller public class HomeController : Controller
{ {
private readonly IIdentityServerInteractionService _interaction; private readonly IIdentityServerInteractionService _interaction;
private readonly IOptions<AppSettings> _settings;
public HomeController(IIdentityServerInteractionService interaction)
public HomeController(IIdentityServerInteractionService interaction, IOptions<AppSettings> settings)
{ {
_interaction = interaction; _interaction = interaction;
_settings = settings;
} }
public IActionResult Index()
public IActionResult Index(string returnUrl)
{ {
if (returnUrl != "")
return Redirect(_settings.Value.MvcClient);
return View(); return View();
} }


+ 2
- 2
src/Services/Identity/eShopOnContainers.Identity/Startup.cs View File

@ -51,8 +51,8 @@ namespace eShopOnContainers.Identity
services.AddIdentity<ApplicationUser, IdentityRole>() services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>() .AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders(); .AddDefaultTokenProviders();
services.Configure<AppSettings>(Configuration);
services.AddMvc(); services.AddMvc();


+ 0
- 14
src/Services/Identity/eShopOnContainers.Identity/Views/Shared/_Layout.cshtml View File

@ -18,20 +18,6 @@
<div class="navbar-brand"></div> <div class="navbar-brand"></div>
</a> </a>
</div> </div>
<div>
<a asp-action="Register" asp-controller="Account">Register User</a>
</div>
@*@if (User.Identity.IsAuthenticated)
{
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">@User.Identity.Name <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a asp-action="Logout" asp-controller="Account">Logout</a></li>
</ul>
</li>
</ul>
}*@
</div> </div>
</div> </div>
</div> </div>


+ 1
- 1
src/Services/Identity/eShopOnContainers.Identity/appsettings.json View File

@ -1,6 +1,6 @@
{ {
"ConnectionStrings": { "ConnectionStrings": {
"DefaultConnection": "Server=127.0.0.1,5433;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word"
"DefaultConnection": "Server=127.0.0.1,5433;Database=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word"
}, },
"MvcClient": "http://localhost:5100", "MvcClient": "http://localhost:5100",
"SpaClient": "http://localhost:5104", "SpaClient": "http://localhost:5104",


+ 2
- 2
src/Services/Identity/eShopOnContainers.Identity/docker-compose.yml View File

@ -5,7 +5,7 @@ services:
image: eshop/identity image: eshop/identity
environment: environment:
- SpaClient=http://localhost:5104 - SpaClient=http://localhost:5104
- ConnectionStrings__DefaultConnection=Server=identity.data;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word
- ConnectionStrings__DefaultConnection=Server=identity.data;Database=Microsoft.eShopOnContainers.Services.IdentityDb;User Id=sa;Password=Pass@word
#- MvcClient=http://104.40.62.65:5100 #Remote: VM Needs to have public access at 5105. #- MvcClient=http://104.40.62.65:5100 #Remote: VM Needs to have public access at 5105.
- MvcClient=http://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker. - MvcClient=http://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker.
ports: ports:
@ -13,7 +13,7 @@ services:
depends_on: depends_on:
- identity.data - identity.data
identity.data:
sql.data:
image: microsoft/mssql-server-linux image: microsoft/mssql-server-linux
environment: environment:
- SA_PASSWORD=Pass@word - SA_PASSWORD=Pass@word


+ 48
- 0
src/Services/Ordering/Ordering.API/Application/Commands/NewOrderRequest.cs View File

@ -0,0 +1,48 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Commands
{
using System;
using MediatR;
using Domain;
using System.Collections;
using System.Collections.Generic;
public class NewOrderRequest
:IAsyncRequest<bool>
{
private readonly List<OrderItem> _orderItems;
public string City { get; set; }
public string Street { get; set; }
public string State { get; set; }
public string Country { get; set; }
public string ZipCode { get; set; }
public string CardNumber { get; set; }
public string CardHolderName { get; set; }
public DateTime CardExpiration { get; set; }
public string CardSecurityNumber { get; set; }
public int CardTypeId { get; set; }
public string Buyer { get; set; }
public IEnumerable<OrderItem> OrderItems => _orderItems;
public void AddOrderItem(OrderItem item)
{
_orderItems.Add(item);
}
public NewOrderRequest()
{
_orderItems = new List<OrderItem>();
}
}
}

+ 118
- 0
src/Services/Ordering/Ordering.API/Application/Commands/NewOrderRequestHandler.cs View File

@ -0,0 +1,118 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Commands
{
using Domain.Repositories;
using MediatR;
using System.Linq;
using System;
using System.Threading.Tasks;
using Domain;
public class NewOrderRequestHandler
: IAsyncRequestHandler<NewOrderRequest, bool>
{
private readonly IBuyerRepository _buyerRepository;
private readonly IOrderRepository _orderRepository;
public NewOrderRequestHandler(IBuyerRepository buyerRepository,IOrderRepository orderRepository)
{
if (buyerRepository == null)
{
throw new ArgumentNullException(nameof(buyerRepository));
}
if (orderRepository == null)
{
throw new ArgumentNullException(nameof(orderRepository));
}
_buyerRepository = buyerRepository;
_orderRepository = orderRepository;
}
public async Task<bool> Handle(NewOrderRequest message)
{
//find buyer/payment or add a new one buyer/payment
var buyer = await _buyerRepository.FindAsync(message.Buyer);
if (buyer == null)
{
buyer = CreateBuyer(message);
}
var payment = GetExistingPaymentOrAddANewOne(buyer, message);
await _buyerRepository.UnitOfWork
.SaveChangesAsync();
//create order for buyer and payment method
var order = CreateOrder(buyer.Id, payment.Id, 0);
order.SetAddress( new Address()
{
City = message.City,
State = message.State,
Street = message.Street,
ZipCode = message.ZipCode
});
foreach (var item in message.OrderItems)
{
order.AddOrderItem(item);
}
_orderRepository.Add(order);
var result = await _orderRepository.UnitOfWork
.SaveChangesAsync();
return result > 0;
}
Payment GetExistingPaymentOrAddANewOne(Buyer buyer, NewOrderRequest message)
{
Payment payment = PaymentAlreadyExist(buyer, message);
if (payment == null)
{
payment = CreatePayment(message);
buyer.Payments.Add(payment);
}
return payment;
}
Payment PaymentAlreadyExist(Domain.Buyer buyer, NewOrderRequest message)
{
return buyer.Payments
.SingleOrDefault(p =>
{
return p.CardHolderName == message.CardHolderName
&&
p.CardNumber == message.CardNumber
&&
p.Expiration == message.CardExpiration
&&
p.SecurityNumber == message.CardSecurityNumber;
});
}
Buyer CreateBuyer(NewOrderRequest message)
{
return _buyerRepository.Add(
new Buyer(message.Buyer));
}
Order CreateOrder(int buyerId, int paymentId, int addressId)
{
return new Order(buyerId, paymentId);
}
Payment CreatePayment(NewOrderRequest message)
{
return new Payment(message.CardNumber, message.CardSecurityNumber, message.CardHolderName, message.CardExpiration, message.CardTypeId);
}
}
}

+ 34
- 0
src/Services/Ordering/Ordering.API/Application/Decorators/LogDecorator.cs View File

@ -0,0 +1,34 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Decorators
{
using Extensions.Logging;
using MediatR;
using System.Threading.Tasks;
public class LogDecorator<TRequest, TResponse>
: IAsyncRequestHandler<TRequest, TResponse>
where TRequest : IAsyncRequest<TResponse>
{
private readonly IAsyncRequestHandler<TRequest, TResponse> _inner;
private readonly ILogger<LogDecorator<TRequest, TResponse>> _logger;
public LogDecorator(
IAsyncRequestHandler<TRequest, TResponse> inner,
ILogger<LogDecorator<TRequest, TResponse>> logger)
{
_inner = inner;
_logger = logger;
}
public async Task<TResponse> Handle(TRequest message)
{
_logger.LogInformation($"Executing command {_inner.GetType().FullName}");
var response = await _inner.Handle(message);
_logger.LogInformation($"Succedded executed command {_inner.GetType().FullName}");
return response;
}
}
}

+ 13
- 0
src/Services/Ordering/Ordering.API/Application/Queries/IOrderQueries.cs View File

@ -0,0 +1,13 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Queries
{
using System.Threading.Tasks;
public interface IOrderQueries
{
Task<dynamic> GetOrder(int id);
Task<dynamic> GetOrders();
Task<dynamic> GetCardTypes();
}
}

+ 101
- 0
src/Services/Ordering/Ordering.API/Application/Queries/OrderQueries.cs View File

@ -0,0 +1,101 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.Api.Application.Queries
{
using Dapper;
using Microsoft.Extensions.Configuration;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System;
using System.Dynamic;
using System.Collections.Generic;
public class OrderQueries
:IOrderQueries
{
private string _connectionString = string.Empty;
public OrderQueries(IConfiguration configuration)
{
_connectionString = configuration["ConnectionString"];
}
public async Task<dynamic> GetOrder(int id)
{
using (var connection = new SqlConnection(_connectionString))
{
connection.Open();
var result = await connection.QueryAsync<dynamic>(
@"select o.[Id] as ordernumber,o.OrderDate as date, os.Name as status,
oi.ProductName as productname, oi.Units as units, oi.UnitPrice as unitprice, oi.PictureUrl as pictureurl,
oa.Street as street, oa.City as city, oa.Country as country, oa.State as state, oa.ZipCode as zipcode
FROM ordering.Orders o
LEFT JOIN ordering.Orderitems oi ON o.Id = oi.orderid
LEFT JOIN ordering.orderstatus os on o.StatusId = os.Id
LEFT JOIN ordering.address oa on o.ShippingAddressId = oa.Id
WHERE o.Id=@id"
, new { id }
);
if (result.AsList().Count == 0)
throw new KeyNotFoundException();
return MapOrderItems(result);
}
}
public async Task<dynamic> GetOrders()
{
using (var connection = new SqlConnection(_connectionString))
{
connection.Open();
return await connection.QueryAsync<dynamic>(@"SELECT o.[Id] as ordernumber,o.[OrderDate] as [date],os.[Name] as [status],SUM(oi.units*oi.unitprice) as total
FROM [ordering].[Orders] o
LEFT JOIN[ordering].[orderitems] oi ON o.Id = oi.orderid
LEFT JOIN[ordering].[orderstatus] os on o.StatusId = os.Id
GROUP BY o.[Id], o.[OrderDate], os.[Name]");
}
}
public async Task<dynamic> GetCardTypes()
{
using (var connection = new SqlConnection(_connectionString))
{
connection.Open();
return await connection.QueryAsync<dynamic>("SELECT * FROM ordering.cardtypes");
}
}
private dynamic MapOrderItems(dynamic result)
{
dynamic order = new ExpandoObject();
order.ordernumber = result[0].ordernumber;
order.date = result[0].date;
order.status = result[0].status;
order.street = result[0].street;
order.city = result[0].city;
order.zipcode = result[0].zipcode;
order.country = result[0].country;
order.orderitems = new List<dynamic>();
order.total = 0;
foreach (dynamic item in result)
{
dynamic orderitem = new ExpandoObject();
orderitem.productname = item.productname;
orderitem.units = item.units;
orderitem.unitprice = item.unitprice;
orderitem.pictureurl = item.pictureurl;
order.total += item.units * item.unitprice;
order.orderitems.Add(orderitem);
}
return order;
}
}
}

+ 3
- 3
src/Services/Ordering/Ordering.API/Controllers/OrdersController.cs View File

@ -1,7 +1,7 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
{ {
using Application.Commands;
using Application.Queries;
using Api.Application.Commands;
using Api.Application.Queries;
using AspNetCore.Authorization; using AspNetCore.Authorization;
using MediatR; using MediatR;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -11,7 +11,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
[Route("api/v1/[controller]")] [Route("api/v1/[controller]")]
[Authorize]
//[Authorize]
public class OrdersController : Controller public class OrdersController : Controller
{ {
private readonly IMediator _mediator; private readonly IMediator _mediator;


+ 1
- 1
src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/ApplicationModule.cs View File

@ -2,7 +2,7 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules
{ {
using Application.Queries;
using Api.Application.Queries;
using Autofac; using Autofac;
using Domain.Repositories; using Domain.Repositories;
using Ordering.Infrastructure.Repositories; using Ordering.Infrastructure.Repositories;


+ 2
- 2
src/Services/Ordering/Ordering.API/Infrastructure/AutofacModules/MediatorModule.cs View File

@ -1,7 +1,7 @@
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules
{ {
using Application.Commands;
using Application.Decorators;
using Api.Application.Commands;
using Api.Application.Decorators;
using Autofac; using Autofac;
using Autofac.Core; using Autofac.Core;
using MediatR; using MediatR;


+ 3
- 3
src/Services/Ordering/Ordering.API/project.json View File

@ -19,16 +19,16 @@
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.1", "Microsoft.EntityFrameworkCore.SqlServer": "1.0.1",
"Microsoft.EntityFrameworkCore": "1.0.1", "Microsoft.EntityFrameworkCore": "1.0.1",
"Microsoft.EntityFrameworkCore.Design" : "1.0.0-preview2-final",
"Microsoft.EntityFrameworkCore.Design": "1.0.0-preview2-final",
"Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.1", "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.1",
"Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Diagnostics": "1.0.0",
"Swashbuckle": "6.0.0-beta902", "Swashbuckle": "6.0.0-beta902",
"MediatR": "2.1.0", "MediatR": "2.1.0",
"Ordering.Domain": "1.0.0-*", "Ordering.Domain": "1.0.0-*",
"Ordering.Application": "1.0.0-*",
"Ordering.Infrastructure": "1.0.0-*", "Ordering.Infrastructure": "1.0.0-*",
"System.Reflection": "4.3.0", "System.Reflection": "4.3.0",
"IdentityServer4.AccessTokenValidation": "1.0.1-rc3"
"IdentityServer4.AccessTokenValidation": "1.0.1-rc3",
"Dapper": "1.50.2"
}, },
"tools": { "tools": {
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",


+ 1
- 1
src/Web/WebMVC/Services/OrderingService.cs View File

@ -65,7 +65,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
order.CardNumber = user.CardNumber; order.CardNumber = user.CardNumber;
order.CardHolderName = user.CardHolderName; order.CardHolderName = user.CardHolderName;
//order.CardExpiration = user.Expiration;
order.CardExpiration = new DateTime(1,int.Parse(user.Expiration.Split('/')[0]), int.Parse("20" + user.Expiration.Split('/')[1]));
order.CardSecurityNumber = user.SecurityNumber; order.CardSecurityNumber = user.SecurityNumber;
return order; return order;


+ 1
- 1
src/Web/WebMVC/wwwroot/css/site.min.css
File diff suppressed because it is too large
View File


+ 1
- 1
src/Web/WebSPA/eShopOnContainers.WebSPA/Program.cs View File

@ -18,7 +18,7 @@ namespace eShopConContainers.WebSPA
.UseConfiguration(config) .UseConfiguration(config)
.UseContentRoot(Directory.GetCurrentDirectory()) .UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration() .UseIISIntegration()
//.UseUrls("http://localhost:1250/")
.UseUrls("http://localhost:5104/")
.UseStartup<Startup>() .UseStartup<Startup>()
.Build(); .Build();


Loading…
Cancel
Save