Add Swagger to Basket Api
SQL databases with the same prefix for services Move application tier to api tier in ordering api
This commit is contained in:
parent
31753fc057
commit
10f3e17b55
@ -9,21 +9,22 @@ version: '2'
|
||||
|
||||
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:
|
||||
environment:
|
||||
- CatalogUrl=http://catalog.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.
|
||||
- BasketUrl=http://basket.api:5103
|
||||
ports:
|
||||
@ -32,30 +33,30 @@ services:
|
||||
basket.api:
|
||||
environment:
|
||||
- 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.
|
||||
ports:
|
||||
- "5103:5103"
|
||||
|
||||
catalog.api:
|
||||
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:
|
||||
- "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:
|
||||
environment:
|
||||
- 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.
|
||||
#10.0.75.1:5105 CCE/TODO: try to avoid host entry.
|
||||
ports:
|
||||
|
@ -7,11 +7,13 @@
|
||||
version: '2'
|
||||
|
||||
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:
|
||||
image: eshop/webspa
|
||||
@ -30,10 +32,10 @@ services:
|
||||
depends_on:
|
||||
- sql.data
|
||||
|
||||
# ordering.api:
|
||||
# image: eshop/ordering.api
|
||||
# depends_on:
|
||||
# - sql.data
|
||||
ordering.api:
|
||||
image: eshop/ordering.api
|
||||
depends_on:
|
||||
- sql.data
|
||||
|
||||
identity.service:
|
||||
image: eshop/identity
|
||||
|
19
src/Services/Basket/Basket.API/Controllers/HomeController.cs
Normal file
19
src/Services/Basket/Basket.API/Controllers/HomeController.cs
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
@ -47,6 +47,20 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
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 =>
|
||||
{
|
||||
options.AddPolicy("CorsPolicy",
|
||||
@ -77,7 +91,11 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
RequireHttpsMetadata = false
|
||||
});
|
||||
|
||||
app.UseMvc();
|
||||
app.UseMvcWithDefaultRoute();
|
||||
|
||||
app.UseSwagger()
|
||||
.UseSwaggerUi();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,8 @@
|
||||
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
|
||||
"StackExchange.Redis": "1.1.608",
|
||||
"Newtonsoft.Json": "9.0.1",
|
||||
"IdentityServer4.AccessTokenValidation": "1.0.1-rc3"
|
||||
"IdentityServer4.AccessTokenValidation": "1.0.1-rc3",
|
||||
"Swashbuckle": "6.0.0-beta902"
|
||||
},
|
||||
"tools": {
|
||||
"Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
|
||||
|
@ -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": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
|
@ -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; }
|
||||
}
|
||||
}
|
@ -78,7 +78,7 @@ namespace eShopOnContainers.Identity.Configuration
|
||||
new Secret("secret".Sha256())
|
||||
},
|
||||
ClientUri = $"{clientsUrl["Mvc"]}", // public uri of the client
|
||||
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
|
||||
AllowedGrantTypes = GrantTypes.Hybrid,
|
||||
RedirectUris = new List<string>
|
||||
{
|
||||
$"{clientsUrl["Mvc"]}/signin-oidc",
|
||||
|
@ -85,15 +85,9 @@ namespace IdentityServer4.Quickstart.UI.Controllers
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
var user = await _loginService.FindByUsername(model.Email);
|
||||
// validate username/password against in-memory store
|
||||
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)
|
||||
{
|
||||
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)
|
||||
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>
|
||||
|
@ -2,9 +2,11 @@
|
||||
// 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.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace IdentityServer4.Quickstart.UI.Controllers
|
||||
@ -12,14 +14,19 @@ namespace IdentityServer4.Quickstart.UI.Controllers
|
||||
public class HomeController : Controller
|
||||
{
|
||||
private readonly IIdentityServerInteractionService _interaction;
|
||||
private readonly IOptions<AppSettings> _settings;
|
||||
|
||||
public HomeController(IIdentityServerInteractionService interaction)
|
||||
public HomeController(IIdentityServerInteractionService interaction, IOptions<AppSettings> settings)
|
||||
{
|
||||
_interaction = interaction;
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
public IActionResult Index(string returnUrl)
|
||||
{
|
||||
if (returnUrl != "")
|
||||
return Redirect(_settings.Value.MvcClient);
|
||||
|
||||
return View();
|
||||
}
|
||||
|
||||
|
@ -51,8 +51,8 @@ namespace eShopOnContainers.Identity
|
||||
services.AddIdentity<ApplicationUser, IdentityRole>()
|
||||
.AddEntityFrameworkStores<ApplicationDbContext>()
|
||||
.AddDefaultTokenProviders();
|
||||
|
||||
|
||||
|
||||
services.Configure<AppSettings>(Configuration);
|
||||
|
||||
services.AddMvc();
|
||||
|
||||
|
@ -18,20 +18,6 @@
|
||||
<div class="navbar-brand"></div>
|
||||
</a>
|
||||
</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>
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"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",
|
||||
"SpaClient": "http://localhost:5104",
|
||||
|
@ -5,7 +5,7 @@ services:
|
||||
image: eshop/identity
|
||||
environment:
|
||||
- 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://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker.
|
||||
ports:
|
||||
@ -13,7 +13,7 @@ services:
|
||||
depends_on:
|
||||
- identity.data
|
||||
|
||||
identity.data:
|
||||
sql.data:
|
||||
image: microsoft/mssql-server-linux
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
|
@ -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>();
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
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 MediatR;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@ -11,7 +11,7 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
[Route("api/v1/[controller]")]
|
||||
[Authorize]
|
||||
//[Authorize]
|
||||
public class OrdersController : Controller
|
||||
{
|
||||
private readonly IMediator _mediator;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Infrastructure.AutofacModules
|
||||
{
|
||||
using Application.Queries;
|
||||
using Api.Application.Queries;
|
||||
using Autofac;
|
||||
using Domain.Repositories;
|
||||
using Ordering.Infrastructure.Repositories;
|
||||
|
@ -1,7 +1,7 @@
|
||||
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.Core;
|
||||
using MediatR;
|
||||
|
@ -19,16 +19,16 @@
|
||||
"Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
|
||||
"Microsoft.EntityFrameworkCore.SqlServer": "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.AspNetCore.Diagnostics": "1.0.0",
|
||||
"Swashbuckle": "6.0.0-beta902",
|
||||
"MediatR": "2.1.0",
|
||||
"Ordering.Domain": "1.0.0-*",
|
||||
"Ordering.Application": "1.0.0-*",
|
||||
"Ordering.Infrastructure": "1.0.0-*",
|
||||
"System.Reflection": "4.3.0",
|
||||
"IdentityServer4.AccessTokenValidation": "1.0.1-rc3"
|
||||
"IdentityServer4.AccessTokenValidation": "1.0.1-rc3",
|
||||
"Dapper": "1.50.2"
|
||||
},
|
||||
"tools": {
|
||||
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",
|
||||
|
@ -65,7 +65,7 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
|
||||
order.CardNumber = user.CardNumber;
|
||||
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;
|
||||
|
||||
return order;
|
||||
|
2
src/Web/WebMVC/wwwroot/css/site.min.css
vendored
2
src/Web/WebMVC/wwwroot/css/site.min.css
vendored
File diff suppressed because one or more lines are too long
@ -18,7 +18,7 @@ namespace eShopConContainers.WebSPA
|
||||
.UseConfiguration(config)
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
//.UseUrls("http://localhost:1250/")
|
||||
.UseUrls("http://localhost:5104/")
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user