Merge branch 'dev' into eShopOnServiceFabric-Win
This commit is contained in:
commit
480723e351
@ -102,6 +102,7 @@ services:
|
|||||||
- IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
- IdentityUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5105 #Local: You need to open your local dev-machine firewall at range 5100-5105. at range 5100-5105.
|
||||||
- BasketUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5103
|
- BasketUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5103
|
||||||
- MarketingUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5110
|
- MarketingUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5110
|
||||||
|
- LocationsUrl=http://${ESHOP_EXTERNAL_DNS_NAME_OR_IP}:5109
|
||||||
- CatalogUrlHC=http://catalog.api/hc
|
- CatalogUrlHC=http://catalog.api/hc
|
||||||
- OrderingUrlHC=http://ordering.api/hc
|
- OrderingUrlHC=http://ordering.api/hc
|
||||||
- IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
- IdentityUrlHC=http://identity.api/hc #Local: Use ${ESHOP_PROD_EXTERNAL_DNS_NAME_OR_IP}, if using external IP or DNS name from browser.
|
||||||
@ -118,6 +119,7 @@ services:
|
|||||||
- CatalogUrl=http://catalog.api
|
- CatalogUrl=http://catalog.api
|
||||||
- OrderingUrl=http://ordering.api
|
- OrderingUrl=http://ordering.api
|
||||||
- BasketUrl=http://basket.api
|
- BasketUrl=http://basket.api
|
||||||
|
- LocationsUrl=http://locations.api
|
||||||
- IdentityUrl=http://10.0.75.1:5105
|
- IdentityUrl=http://10.0.75.1:5105
|
||||||
- MarketingUrl=http://marketing.api #Local: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser.
|
- MarketingUrl=http://marketing.api #Local: Use 10.0.75.1 in a "Docker for Windows" environment, if using "localhost" from browser.
|
||||||
#Remote: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser.
|
#Remote: Use ${ESHOP_EXTERNAL_DNS_NAME_OR_IP} if using external IP or DNS name from browser.
|
||||||
|
@ -23,18 +23,38 @@
|
|||||||
if (!ctx.Locations.Database.GetCollection<Locations>(nameof(Locations)).AsQueryable().Any())
|
if (!ctx.Locations.Database.GetCollection<Locations>(nameof(Locations)).AsQueryable().Any())
|
||||||
{
|
{
|
||||||
await SetIndexes();
|
await SetIndexes();
|
||||||
await SetUSLocations();
|
await SetNorthAmerica();
|
||||||
|
await SetSouthAmerica();
|
||||||
|
await SetAfrica();
|
||||||
|
await SetEurope();
|
||||||
|
await SetAsia();
|
||||||
|
await SetAustralia();
|
||||||
await SetBarcelonaLocations();
|
await SetBarcelonaLocations();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async Task SetUSLocations()
|
static async Task SetNorthAmerica()
|
||||||
{
|
{
|
||||||
var us = new Locations()
|
var us = new Locations()
|
||||||
{
|
{
|
||||||
|
Code = "NA",
|
||||||
|
Description = "North America",
|
||||||
|
LocationId = 1
|
||||||
|
};
|
||||||
|
us.SetLocation(-103.219329, 48.803281);
|
||||||
|
us.SetArea(GetNorthAmericaPoligon());
|
||||||
|
await ctx.Locations.InsertOneAsync(us);
|
||||||
|
await SetUSLocations(us.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task SetUSLocations(string parentId)
|
||||||
|
{
|
||||||
|
var us = new Locations()
|
||||||
|
{
|
||||||
|
Parent_Id = parentId,
|
||||||
Code = "US",
|
Code = "US",
|
||||||
Description = "United States",
|
Description = "United States",
|
||||||
LocationId = 1
|
LocationId = 2
|
||||||
};
|
};
|
||||||
us.SetLocation(-101.357386, 41.650455);
|
us.SetLocation(-101.357386, 41.650455);
|
||||||
us.SetArea(GetUSPoligon());
|
us.SetArea(GetUSPoligon());
|
||||||
@ -49,7 +69,7 @@
|
|||||||
Parent_Id = parentId,
|
Parent_Id = parentId,
|
||||||
Code = "WHT",
|
Code = "WHT",
|
||||||
Description = "Washington",
|
Description = "Washington",
|
||||||
LocationId = 2
|
LocationId = 3
|
||||||
};
|
};
|
||||||
wht.SetLocation(-119.542781, 47.223652);
|
wht.SetLocation(-119.542781, 47.223652);
|
||||||
wht.SetArea(GetWashingtonPoligon());
|
wht.SetArea(GetWashingtonPoligon());
|
||||||
@ -65,7 +85,7 @@
|
|||||||
Parent_Id = parentId,
|
Parent_Id = parentId,
|
||||||
Code = "SEAT",
|
Code = "SEAT",
|
||||||
Description = "Seattle",
|
Description = "Seattle",
|
||||||
LocationId = 3
|
LocationId = 4
|
||||||
};
|
};
|
||||||
stl.SetArea(GetSeattlePoligon());
|
stl.SetArea(GetSeattlePoligon());
|
||||||
stl.SetLocation(-122.330747, 47.603111);
|
stl.SetLocation(-122.330747, 47.603111);
|
||||||
@ -79,7 +99,7 @@
|
|||||||
Parent_Id = parentId,
|
Parent_Id = parentId,
|
||||||
Code = "REDM",
|
Code = "REDM",
|
||||||
Description = "Redmond",
|
Description = "Redmond",
|
||||||
LocationId = 4
|
LocationId = 5
|
||||||
};
|
};
|
||||||
rdm.SetLocation(-122.122887, 47.674961);
|
rdm.SetLocation(-122.122887, 47.674961);
|
||||||
rdm.SetArea(GetRedmondPoligon());
|
rdm.SetArea(GetRedmondPoligon());
|
||||||
@ -92,13 +112,77 @@
|
|||||||
{
|
{
|
||||||
Code = "BCN",
|
Code = "BCN",
|
||||||
Description = "Barcelona",
|
Description = "Barcelona",
|
||||||
LocationId = 5
|
LocationId = 6
|
||||||
};
|
};
|
||||||
bcn.SetLocation(2.156453, 41.395226);
|
bcn.SetLocation(2.156453, 41.395226);
|
||||||
bcn.SetArea(GetBarcelonaPoligon());
|
bcn.SetArea(GetBarcelonaPoligon());
|
||||||
await ctx.Locations.InsertOneAsync(bcn);
|
await ctx.Locations.InsertOneAsync(bcn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async Task SetSouthAmerica()
|
||||||
|
{
|
||||||
|
var sa = new Locations()
|
||||||
|
{
|
||||||
|
Code = "SA",
|
||||||
|
Description = "South America",
|
||||||
|
LocationId = 7
|
||||||
|
};
|
||||||
|
sa.SetLocation(-60.328704, -16.809748);
|
||||||
|
sa.SetArea(GetSouthAmericaPoligon());
|
||||||
|
await ctx.Locations.InsertOneAsync(sa);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task SetAfrica()
|
||||||
|
{
|
||||||
|
var afc = new Locations()
|
||||||
|
{
|
||||||
|
Code = "AFC",
|
||||||
|
Description = "Africa",
|
||||||
|
LocationId = 8
|
||||||
|
};
|
||||||
|
afc.SetLocation(19.475383, 13.063667);
|
||||||
|
afc.SetArea(GetAfricaPoligon());
|
||||||
|
await ctx.Locations.InsertOneAsync(afc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task SetEurope()
|
||||||
|
{
|
||||||
|
var eu = new Locations()
|
||||||
|
{
|
||||||
|
Code = "EU",
|
||||||
|
Description = "Europe",
|
||||||
|
LocationId = 9
|
||||||
|
};
|
||||||
|
eu.SetLocation(13.147258, 49.947844);
|
||||||
|
eu.SetArea(GetEuropePoligon());
|
||||||
|
await ctx.Locations.InsertOneAsync(eu);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task SetAsia()
|
||||||
|
{
|
||||||
|
var asa = new Locations()
|
||||||
|
{
|
||||||
|
Code = "AS",
|
||||||
|
Description = "Asia",
|
||||||
|
LocationId = 10
|
||||||
|
};
|
||||||
|
asa.SetLocation(97.522257, 56.069107);
|
||||||
|
asa.SetArea(GetAsiaPoligon());
|
||||||
|
await ctx.Locations.InsertOneAsync(asa);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async Task SetAustralia()
|
||||||
|
{
|
||||||
|
var aus = new Locations()
|
||||||
|
{
|
||||||
|
Code = "AUS",
|
||||||
|
Description = "Australia",
|
||||||
|
LocationId = 11
|
||||||
|
};
|
||||||
|
aus.SetLocation(133.733195, -25.010726);
|
||||||
|
aus.SetArea(GetAustraliaPoligon());
|
||||||
|
await ctx.Locations.InsertOneAsync(aus);
|
||||||
|
}
|
||||||
|
|
||||||
static async Task SetIndexes()
|
static async Task SetIndexes()
|
||||||
{
|
{
|
||||||
@ -108,6 +192,99 @@
|
|||||||
await ctx.Locations.Indexes.CreateOneAsync(keys);
|
await ctx.Locations.Indexes.CreateOneAsync(keys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<GeoJson2DGeographicCoordinates> GetNorthAmericaPoligon()
|
||||||
|
{
|
||||||
|
return new List<GeoJson2DGeographicCoordinates>()
|
||||||
|
{
|
||||||
|
new GeoJson2DGeographicCoordinates(-168.07786, 68.80277),
|
||||||
|
new GeoJson2DGeographicCoordinates(-119.60378, 32.7561),
|
||||||
|
new GeoJson2DGeographicCoordinates(-116.01966, 28.94642),
|
||||||
|
new GeoJson2DGeographicCoordinates(-98.52265, 14.49378),
|
||||||
|
new GeoJson2DGeographicCoordinates(-71.18188, 34.96278),
|
||||||
|
new GeoJson2DGeographicCoordinates(-51.97606, 48.24377),
|
||||||
|
new GeoJson2DGeographicCoordinates(-75.39806, 72.93141),
|
||||||
|
new GeoJson2DGeographicCoordinates(-168.07786, 68.80277)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<GeoJson2DGeographicCoordinates> GetSouthAmericaPoligon()
|
||||||
|
{
|
||||||
|
return new List<GeoJson2DGeographicCoordinates>()
|
||||||
|
{
|
||||||
|
new GeoJson2DGeographicCoordinates(-91.43724, 13.29007),
|
||||||
|
new GeoJson2DGeographicCoordinates(-87.96315, -27.15081),
|
||||||
|
new GeoJson2DGeographicCoordinates(-78.75404, -50.71852),
|
||||||
|
new GeoJson2DGeographicCoordinates(-59.14765, -58.50773),
|
||||||
|
new GeoJson2DGeographicCoordinates(-50.08813, -42.22419),
|
||||||
|
new GeoJson2DGeographicCoordinates(-37.21044, -22.56725),
|
||||||
|
new GeoJson2DGeographicCoordinates(-36.61675, -0.38594),
|
||||||
|
new GeoJson2DGeographicCoordinates(-44.46056, -16.6746),
|
||||||
|
new GeoJson2DGeographicCoordinates(-91.43724, 13.29007),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<GeoJson2DGeographicCoordinates> GetAfricaPoligon()
|
||||||
|
{
|
||||||
|
return new List<GeoJson2DGeographicCoordinates>()
|
||||||
|
{
|
||||||
|
new GeoJson2DGeographicCoordinates(-12.68724, 34.05892),
|
||||||
|
new GeoJson2DGeographicCoordinates(-18.33301, 20.77313),
|
||||||
|
new GeoJson2DGeographicCoordinates(-14.13503, 6.21292),
|
||||||
|
new GeoJson2DGeographicCoordinates(1.40221, -14.23693),
|
||||||
|
new GeoJson2DGeographicCoordinates(22.41485, -35.55408),
|
||||||
|
new GeoJson2DGeographicCoordinates(51.86499, -25.39831),
|
||||||
|
new GeoJson2DGeographicCoordinates(53.49269, 4.59405),
|
||||||
|
new GeoJson2DGeographicCoordinates(35.102, 26.14685),
|
||||||
|
new GeoJson2DGeographicCoordinates(21.63319, 33.75767),
|
||||||
|
new GeoJson2DGeographicCoordinates(6.58235, 37.05665),
|
||||||
|
new GeoJson2DGeographicCoordinates(-12.68724, 34.05892),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<GeoJson2DGeographicCoordinates> GetEuropePoligon()
|
||||||
|
{
|
||||||
|
return new List<GeoJson2DGeographicCoordinates>()
|
||||||
|
{
|
||||||
|
new GeoJson2DGeographicCoordinates(-11.73143, 35.27646),
|
||||||
|
new GeoJson2DGeographicCoordinates(-10.84462, 35.25123),
|
||||||
|
new GeoJson2DGeographicCoordinates(-10.09927, 35.26833),
|
||||||
|
new GeoJson2DGeographicCoordinates(49.00838, 36.56984),
|
||||||
|
new GeoJson2DGeographicCoordinates(36.63837, 71.69807),
|
||||||
|
new GeoJson2DGeographicCoordinates(-10.88788, 61.13851),
|
||||||
|
new GeoJson2DGeographicCoordinates(-11.73143, 35.27646),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<GeoJson2DGeographicCoordinates> GetAsiaPoligon()
|
||||||
|
{
|
||||||
|
return new List<GeoJson2DGeographicCoordinates>()
|
||||||
|
{
|
||||||
|
new GeoJson2DGeographicCoordinates(31.1592, 45.91629),
|
||||||
|
new GeoJson2DGeographicCoordinates(32.046, 45.89479),
|
||||||
|
new GeoJson2DGeographicCoordinates(62.32261, -4.45013),
|
||||||
|
new GeoJson2DGeographicCoordinates(154.47713, 35.14525),
|
||||||
|
new GeoJson2DGeographicCoordinates(-166.70788, 68.62211),
|
||||||
|
new GeoJson2DGeographicCoordinates(70.38837, 75.89335),
|
||||||
|
new GeoJson2DGeographicCoordinates(32.00274, 67.23428),
|
||||||
|
new GeoJson2DGeographicCoordinates(31.1592, 45.91629),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<GeoJson2DGeographicCoordinates> GetAustraliaPoligon()
|
||||||
|
{
|
||||||
|
return new List<GeoJson2DGeographicCoordinates>()
|
||||||
|
{
|
||||||
|
new GeoJson2DGeographicCoordinates(100.76857, -45.74117),
|
||||||
|
new GeoJson2DGeographicCoordinates(101.65538, -45.76273),
|
||||||
|
new GeoJson2DGeographicCoordinates(167.08823, -50.66317),
|
||||||
|
new GeoJson2DGeographicCoordinates(174.16463, -34.62579),
|
||||||
|
new GeoJson2DGeographicCoordinates(160.94837, -5.01004),
|
||||||
|
new GeoJson2DGeographicCoordinates(139.29462, -7.86376),
|
||||||
|
new GeoJson2DGeographicCoordinates(101.61212, -11.44654),
|
||||||
|
new GeoJson2DGeographicCoordinates(100.76857, -45.74117),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static List<GeoJson2DGeographicCoordinates> GetUSPoligon()
|
static List<GeoJson2DGeographicCoordinates> GetUSPoligon()
|
||||||
{
|
{
|
||||||
return new List<GeoJson2DGeographicCoordinates>()
|
return new List<GeoJson2DGeographicCoordinates>()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using Autofac;
|
using Autofac;
|
||||||
using Autofac.Extensions.DependencyInjection;
|
using Autofac.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
@ -169,13 +170,17 @@ namespace Microsoft.eShopOnContainers.Services.Locations.API
|
|||||||
// prevent from mapping "sub" claim to nameidentifier.
|
// prevent from mapping "sub" claim to nameidentifier.
|
||||||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
|
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
|
||||||
|
|
||||||
services.AddAuthentication()
|
services.AddAuthentication(options =>
|
||||||
.AddJwtBearer(options =>
|
{
|
||||||
{
|
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
options.Authority = Configuration.GetValue<string>("IdentityUrl");
|
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
options.Audience = "locations";
|
})
|
||||||
options.RequireHttpsMetadata = false;
|
.AddJwtBearer(options =>
|
||||||
});
|
{
|
||||||
|
options.Authority = Configuration.GetValue<string>("IdentityUrl");
|
||||||
|
options.Audience = "locations";
|
||||||
|
options.RequireHttpsMetadata = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void ConfigureAuth(IApplicationBuilder app)
|
protected virtual void ConfigureAuth(IApplicationBuilder app)
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
using Infrastructure.Services;
|
using Infrastructure.Services;
|
||||||
using IntegrationEvents.Events;
|
using IntegrationEvents.Events;
|
||||||
using Marketing.API.IntegrationEvents.Handlers;
|
using Marketing.API.IntegrationEvents.Handlers;
|
||||||
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||||
using RabbitMQ.Client;
|
using RabbitMQ.Client;
|
||||||
using Swashbuckle.AspNetCore.Swagger;
|
using Swashbuckle.AspNetCore.Swagger;
|
||||||
@ -199,8 +200,12 @@
|
|||||||
// prevent from mapping "sub" claim to nameidentifier.
|
// prevent from mapping "sub" claim to nameidentifier.
|
||||||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
|
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
|
||||||
|
|
||||||
services.AddAuthentication()
|
services.AddAuthentication(options=>
|
||||||
.AddJwtBearer(options =>
|
{
|
||||||
|
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
|
||||||
|
}).AddJwtBearer(options =>
|
||||||
{
|
{
|
||||||
options.Authority = Configuration.GetValue<string>("IdentityUrl");
|
options.Authority = Configuration.GetValue<string>("IdentityUrl");
|
||||||
options.Audience = "marketing";
|
options.Audience = "marketing";
|
||||||
|
@ -12,6 +12,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
|||||||
public string OrderingUrl { get; set; }
|
public string OrderingUrl { get; set; }
|
||||||
public string BasketUrl { get; set; }
|
public string BasketUrl { get; set; }
|
||||||
public string MarketingUrl { get; set; }
|
public string MarketingUrl { get; set; }
|
||||||
|
public string LocationsUrl { get; set; }
|
||||||
public bool ActivateCampaignDetailFunction { get; set; }
|
public bool ActivateCampaignDetailFunction { get; set; }
|
||||||
public Logging Logging { get; set; }
|
public Logging Logging { get; set; }
|
||||||
public bool UseCustomizationData { get; set; }
|
public bool UseCustomizationData { get; set; }
|
||||||
|
@ -1,28 +1,29 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Query.Internal;
|
|
||||||
using WebMVC.ViewModels;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||||
{
|
{
|
||||||
using AspNetCore.Authorization;
|
using AspNetCore.Authorization;
|
||||||
using AspNetCore.Mvc;
|
using AspNetCore.Mvc;
|
||||||
using Services;
|
using global::WebMVC.Models;
|
||||||
using ViewModels;
|
using global::WebMVC.Services;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System;
|
|
||||||
using ViewModels.Pagination;
|
|
||||||
using global::WebMVC.ViewModels;
|
using global::WebMVC.ViewModels;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using Services;
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using ViewModels;
|
||||||
|
using ViewModels.Pagination;
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
public class CampaignsController : Controller
|
public class CampaignsController : Controller
|
||||||
{
|
{
|
||||||
private readonly ICampaignService _campaignService;
|
private readonly ICampaignService _campaignService;
|
||||||
|
private readonly ILocationService _locationService;
|
||||||
private readonly AppSettings _settings;
|
private readonly AppSettings _settings;
|
||||||
|
|
||||||
public CampaignsController(ICampaignService campaignService, IOptionsSnapshot<AppSettings> settings)
|
public CampaignsController(ICampaignService campaignService, ILocationService locationService, IOptionsSnapshot<AppSettings> settings)
|
||||||
{
|
{
|
||||||
_campaignService = campaignService;
|
_campaignService = campaignService;
|
||||||
_settings = settings.Value;
|
_settings = settings.Value;
|
||||||
|
_locationService = locationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> Index(int page = 0, int pageSize = 10)
|
public async Task<IActionResult> Index(int page = 0, int pageSize = 10)
|
||||||
@ -76,5 +77,23 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
|||||||
|
|
||||||
return View(campaign);
|
return View(campaign);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IActionResult> CreateNewUserLocation(CampaignViewModel model)
|
||||||
|
{
|
||||||
|
if (ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var location = new LocationDTO()
|
||||||
|
{
|
||||||
|
Longitude = model.Lon,
|
||||||
|
Latitude = model.Lat
|
||||||
|
};
|
||||||
|
await _locationService.CreateOrUpdateUserLocation(location);
|
||||||
|
|
||||||
|
return RedirectToAction(nameof(Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
return View(nameof(Index), model);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -94,5 +94,13 @@ namespace WebMVC.Infrastructure
|
|||||||
return $"{baseUri}{id}";
|
return $"{baseUri}{id}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Locations
|
||||||
|
{
|
||||||
|
public static string CreateOrUpdateUserLocation(string baseUri)
|
||||||
|
{
|
||||||
|
return baseUri;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
13
src/Web/WebMVC/Models/LocationDTO.cs
Normal file
13
src/Web/WebMVC/Models/LocationDTO.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WebMVC.Models
|
||||||
|
{
|
||||||
|
public class LocationDTO
|
||||||
|
{
|
||||||
|
public double Longitude { get; set; }
|
||||||
|
public double Latitude { get; set; }
|
||||||
|
}
|
||||||
|
}
|
10
src/Web/WebMVC/Services/ILocationService.cs
Normal file
10
src/Web/WebMVC/Services/ILocationService.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using WebMVC.Models;
|
||||||
|
|
||||||
|
namespace WebMVC.Services
|
||||||
|
{
|
||||||
|
public interface ILocationService
|
||||||
|
{
|
||||||
|
Task CreateOrUpdateUserLocation(LocationDTO location);
|
||||||
|
}
|
||||||
|
}
|
49
src/Web/WebMVC/Services/LocationService.cs
Normal file
49
src/Web/WebMVC/Services/LocationService.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.eShopOnContainers.BuildingBlocks.Resilience.Http;
|
||||||
|
using Microsoft.eShopOnContainers.WebMVC;
|
||||||
|
using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using WebMVC.Infrastructure;
|
||||||
|
using WebMVC.Models;
|
||||||
|
|
||||||
|
namespace WebMVC.Services
|
||||||
|
{
|
||||||
|
public class LocationService : ILocationService
|
||||||
|
{
|
||||||
|
private readonly IOptionsSnapshot<AppSettings> _settings;
|
||||||
|
private readonly IHttpClient _apiClient;
|
||||||
|
private readonly ILogger<CampaignService> _logger;
|
||||||
|
private readonly string _remoteServiceBaseUrl;
|
||||||
|
private readonly IHttpContextAccessor _httpContextAccesor;
|
||||||
|
|
||||||
|
public LocationService(IOptionsSnapshot<AppSettings> settings, IHttpClient httpClient,
|
||||||
|
ILogger<CampaignService> logger, IHttpContextAccessor httpContextAccesor)
|
||||||
|
{
|
||||||
|
_settings = settings;
|
||||||
|
_apiClient = httpClient;
|
||||||
|
_logger = logger;
|
||||||
|
|
||||||
|
_remoteServiceBaseUrl = $"{_settings.Value.LocationsUrl}/api/v1/locations/";
|
||||||
|
_httpContextAccesor = httpContextAccesor ?? throw new ArgumentNullException(nameof(httpContextAccesor));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task CreateOrUpdateUserLocation(LocationDTO location)
|
||||||
|
{
|
||||||
|
var createOrUpdateUserLocationUri = API.Locations.CreateOrUpdateUserLocation(_remoteServiceBaseUrl);
|
||||||
|
|
||||||
|
var authorizationToken = await GetUserTokenAsync();
|
||||||
|
var response = await _apiClient.PostAsync(createOrUpdateUserLocationUri, location, authorizationToken);
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<string> GetUserTokenAsync()
|
||||||
|
{
|
||||||
|
var context = _httpContextAccesor.HttpContext;
|
||||||
|
return await context.GetTokenAsync("access_token");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@ using Microsoft.Extensions.Logging;
|
|||||||
using System;
|
using System;
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using WebMVC.Infrastructure;
|
using WebMVC.Infrastructure;
|
||||||
|
using WebMVC.Services;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.WebMVC
|
namespace Microsoft.eShopOnContainers.WebMVC
|
||||||
{
|
{
|
||||||
@ -64,6 +65,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
|||||||
services.AddTransient<IOrderingService, OrderingService>();
|
services.AddTransient<IOrderingService, OrderingService>();
|
||||||
services.AddTransient<IBasketService, BasketService>();
|
services.AddTransient<IBasketService, BasketService>();
|
||||||
services.AddTransient<ICampaignService, CampaignService>();
|
services.AddTransient<ICampaignService, CampaignService>();
|
||||||
|
services.AddTransient<ILocationService, LocationService>();
|
||||||
services.AddTransient<IIdentityParser<ApplicationUser>, IdentityParser>();
|
services.AddTransient<IIdentityParser<ApplicationUser>, IdentityParser>();
|
||||||
|
|
||||||
if (Configuration.GetValue<string>("UseResilientHttp") == bool.TrueString)
|
if (Configuration.GetValue<string>("UseResilientHttp") == bool.TrueString)
|
||||||
|
22
src/Web/WebMVC/ViewModels/Annotations/LatitudeCoordinate.cs
Normal file
22
src/Web/WebMVC/ViewModels/Annotations/LatitudeCoordinate.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace WebMVC.ViewModels.Annotations
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
|
||||||
|
public class LatitudeCoordinate : ValidationAttribute
|
||||||
|
{
|
||||||
|
protected override ValidationResult
|
||||||
|
IsValid(object value, ValidationContext validationContext)
|
||||||
|
{
|
||||||
|
double coordinate;
|
||||||
|
if (!double.TryParse(value.ToString(), out coordinate) || (coordinate < -90 || coordinate > 90))
|
||||||
|
{
|
||||||
|
return new ValidationResult
|
||||||
|
("Latitude must be between -90 and 90 degrees inclusive.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidationResult.Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
src/Web/WebMVC/ViewModels/Annotations/LongitudeCoordinate.cs
Normal file
22
src/Web/WebMVC/ViewModels/Annotations/LongitudeCoordinate.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace WebMVC.ViewModels.Annotations
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
|
||||||
|
public class LongitudeCoordinate : ValidationAttribute
|
||||||
|
{
|
||||||
|
protected override ValidationResult
|
||||||
|
IsValid(object value, ValidationContext validationContext)
|
||||||
|
{
|
||||||
|
double coordinate;
|
||||||
|
if (!double.TryParse(value.ToString(), out coordinate) || (coordinate < -180 || coordinate > 180))
|
||||||
|
{
|
||||||
|
return new ValidationResult
|
||||||
|
("Longitude must be between -180 and 180 degrees inclusive.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidationResult.Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,10 +3,18 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
using Microsoft.eShopOnContainers.WebMVC.ViewModels;
|
||||||
using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination;
|
using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination;
|
||||||
|
using WebMVC.ViewModels.Annotations;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
public class CampaignViewModel
|
public class CampaignViewModel
|
||||||
{
|
{
|
||||||
public IEnumerable<CampaignItem> CampaignItems { get; set; }
|
public IEnumerable<CampaignItem> CampaignItems { get; set; }
|
||||||
public PaginationInfo PaginationInfo { get; set; }
|
public PaginationInfo PaginationInfo { get; set; }
|
||||||
|
|
||||||
|
[LongitudeCoordinate, Required]
|
||||||
|
public double Lon { get; set; } = -122.315752;
|
||||||
|
[LatitudeCoordinate, Required]
|
||||||
|
public double Lat { get; set; } = 47.604610;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,23 +13,59 @@
|
|||||||
new Header() { Controller = "Catalog", Text = "Back to catalog" } })
|
new Header() { Controller = "Catalog", Text = "Back to catalog" } })
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@if(Model != null && Model.CampaignItems.Any())
|
<br />
|
||||||
{
|
<div class="row">
|
||||||
<div class="card-group esh-campaigns-items row">
|
|
||||||
@foreach (var catalogItem in Model.CampaignItems)
|
@if (!ViewData.ModelState.IsValid)
|
||||||
{
|
{
|
||||||
<div class="esh-campaigns-item col-md-4">
|
<div class="alert alert-warning">
|
||||||
@Html.Partial("_campaign", catalogItem)
|
@Html.ValidationSummary(false)
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="esh-campaigns-items" style="font-weight: 300;">
|
||||||
|
UPDATE USER LOCATION
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form class="form-inline" asp-action="CreateNewUserLocation" method="post">
|
||||||
|
<label class="sr-only" for="longitudeInput">Name</label>
|
||||||
|
<div class="input-group mb-2 mr-sm-2 mb-sm-0">
|
||||||
|
<div class="input-group-addon">Lon</div>
|
||||||
|
<input type="text" class="form-control mb-2 mr-sm-2 mb-sm-0" id="longitudeInput" asp-for="Lon" placeholder="Longitude">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group mb-2 mr-sm-2 mb-sm-0">
|
||||||
|
<div class="input-group-addon">Lat</div>
|
||||||
|
<input type="text" class="form-control mb-2 mr-sm-2 mb-sm-0" id="latitudeInput" asp-for="Lat" placeholder="Latitude">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group mb-2 mr-sm-2 mb-sm-0 col-md-2">
|
||||||
|
<input type="submit" value="Update" class="btn esh-campaigns-form-button" />
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
@if (Model != null && Model.CampaignItems !=null && Model.CampaignItems.Any())
|
||||||
|
{
|
||||||
|
<div class="card-group esh-campaigns-items row">
|
||||||
|
@foreach (var catalogItem in Model.CampaignItems)
|
||||||
|
{
|
||||||
|
<div class="esh-campaigns-item col-md-4">
|
||||||
|
@Html.Partial("_campaign", catalogItem)
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@Html.Partial("_pagination", Model.PaginationInfo)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="esh-campaigns-items row">
|
||||||
|
THERE ARE NO CAMPAIGNS
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
|
||||||
|
|
||||||
@Html.Partial("_pagination", Model.PaginationInfo)
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<div class="esh-campaigns-items row">
|
|
||||||
THERE ARE NO CAMPAIGNS
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,6 +72,17 @@
|
|||||||
transition: all 0.35s;
|
transition: all 0.35s;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.esh-campaigns-form-button {
|
||||||
|
background-color: #83D01B;
|
||||||
|
border: none;
|
||||||
|
color: #FFFFFF;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1rem;
|
||||||
|
transition: all 0.35s;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
.esh-campaigns-button.is-disabled {
|
.esh-campaigns-button.is-disabled {
|
||||||
opacity: .5;
|
opacity: .5;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user