Error executing template "Designs/Swift/Paragraph/Custom_Swift_ProductDetailsImage.cshtml"
System.Data.SqlClient.SqlException (0x80131904): SHUTDOWN is in progress.
Login failed for user 'oodisplay'.
Cannot continue the execution because the session is in the kill state.
A severe error occurred on the current command.  The results, if any, should be discarded.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior)
   at Dynamicweb.Data.Database.CreateDataReader(IDbCommand command, CommandBehavior behavior)
   at Dynamicweb.Data.Database.CreateDataReader(CommandBuilder commandBuilder, IDbConnection connection, IDbTransaction transaction, CommandBehavior behavior, Int32 commandTimeout)
   at Dynamicweb.Data.Database.CreateDataReader(CommandBuilder commandBuilder, IDbConnection connection, IDbTransaction transaction, Int32 commandTimeout)
   at Dynamicweb.Ecommerce.Products.DetailRepository.GetInheritedDetailsBulk(List`1 productIds, String detailType, Boolean onlyDefault)
   at Dynamicweb.Ecommerce.Products.DetailService.GetDetailsBulk(IEnumerable`1 productKeys, String detailType, Boolean excludeDefaultImage)
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetDetailsByGroupId(Product product, Lazy`1 details)
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.CreateView(AssetCategoryViewModelSettings settings, Product product, Lazy`1 details)
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_87b1fa5d6e604422a854943b13736118.ExecuteAsync()
   at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
ClientConnectionId:38e71dc0-23c0-4aed-b65e-396ec8f889a4
Error Number:6005,State:1,Class:14

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using Dynamicweb.Frontend 4 @using System.IO 5 @using System.Text.RegularExpressions; 6 7 @functions { 8 public ProductViewModel product { get; set; } = new ProductViewModel(); 9 public string galleryLayout { get; set; } 10 public string[] supportedImageFormats { get; set; } 11 public string[] supportedVideoFormats { get; set; } 12 public string[] supportedDocumentFormats { get; set; } 13 public string[] allSupportedFormats { get; set; } 14 15 public class RatioSettings 16 { 17 public string Ratio { get; set; } 18 public string CssClass { get; set; } 19 public string CssVariable { get; set; } 20 public string Fill { get; set; } 21 } 22 23 public RatioSettings GetRatioSettings(string size = "desktop") 24 { 25 var ratioSettings = new RatioSettings(); 26 27 string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); 28 ratio = ratio != "0" ? ratio : ""; 29 string cssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; 30 string cssVariable = ratio != "" && ratio != "fill" ? "--bs-aspect-ratio: " + ratio : ""; 31 cssClass = ratio == "fill" && size == "mobile" ? " ratio" : cssClass; 32 cssVariable = ratio == "fill" && size == "mobile" ? "--bs-aspect-ratio: 66%" : cssVariable; 33 34 ratioSettings.Ratio = ratio; 35 ratioSettings.CssClass = cssClass; 36 ratioSettings.CssVariable = cssVariable; 37 ratioSettings.Fill = ratio == "fill" ? " h-100" : ""; 38 39 return ratioSettings; 40 } 41 42 public string GetArrowsColor() 43 { 44 var invertColor = Model.Item.GetBoolean("InvertModalArrowsColor"); 45 var arrowsColor = invertColor ? " carousel-dark" : string.Empty; 46 return arrowsColor; 47 } 48 49 public string GetThumbnailPlacement() 50 { 51 return Model.Item.GetRawValueString("ThumbnailPlacement", "bottom"); 52 } 53 54 public string GetThumbnailRowSettingCss() 55 { 56 switch (GetThumbnailPlacement()) 57 { 58 case "bottom": 59 return "d-flex flex-wrap"; 60 case "left": 61 return "d-flex flex-column order-first"; 62 case "right": 63 return "d-flex flex-column order-last"; 64 default: 65 return "d-flex flex-wrap"; 66 } 67 } 68 69 public Dictionary<string, object> GetVideoParams(MediaViewModel asset, string size) 70 { 71 string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Name; 72 string type = GetVideoType(asset.Value); 73 bool openInModal = Model.Item.GetString("OpenVideoInModal") == "true" ? true : false; 74 bool autoPlay = Model.Item.GetBoolean("VideoAutoPlay"); 75 76 var videoParams = new Dictionary<string, object>(); 77 videoParams.Add("AssetName", asset.Name); 78 videoParams.Add("AssetVideoType", type); 79 videoParams.Add("AssetDisplayName", asset.DisplayName); 80 videoParams.Add("OpenVideoInModal", openInModal); 81 videoParams.Add("VideoAutoPlay", autoPlay); 82 videoParams.Add("Size", size); 83 videoParams.Add("Id", Model.ID); 84 return videoParams; 85 86 } 87 88 public string GetVideoType(string assetValue) 89 { 90 string type = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "youtube" : string.Empty; 91 type = assetValue.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "vimeo" : type; 92 type = string.IsNullOrEmpty(type) ? "selfhosted" : type; 93 94 return type; 95 } 96 97 public string GetYoutubeScreenDump(string assetValue, string quality) 98 { 99 var regex = new Regex(@"(?:youtube\.com\/.*[\?&]v=|youtu\.be\/|youtube\.com\/embed\/)([\w-]+)(?:\?.*)?"); 100 Match match = regex.Match(assetValue); 101 string videoId = match.Success ? match.Groups[1].Value : string.Empty; 102 string youtubeThumbnail = $"https://img.youtube.com/vi/{videoId}/{quality}.jpg"; 103 return youtubeThumbnail; 104 } 105 106 public List<string> GetProductMedia(ProductViewModel product, string[] MediaIds, string ImageFileType) 107 { 108 var ProductMediaList = new List<string>(); 109 110 string[] JpegOnly = ["Image061", "Image062", "Image063", "Image064", "Image065", "Image066"]; 111 112 foreach (var MediaId in MediaIds) 113 { 114 var MediaValue = product.ProductFields.GetValueOrDefault(MediaId); 115 116 if(MediaId == "Icons") 117 { 118 var IconsList = ($"{MediaValue?.Value}").Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList(); 119 foreach (var IconItem in IconsList) 120 { 121 ProductMediaList.Add(IconItem); 122 } 123 } else 124 { 125 if (MediaValue != null && MediaValue.Value != null) 126 { 127 var MediaValueString = MediaValue.Value.ToString(); 128 if (!string.IsNullOrWhiteSpace(MediaValueString)) 129 { 130 if (JpegOnly.Contains(MediaId)) 131 { 132 ProductMediaList.Add($"{MediaValue.Value}.jpg"); 133 } 134 else if (MediaValueString.Contains("://")) 135 { 136 ProductMediaList.Add(MediaValueString); 137 } else if (MediaId == "Image130Gif") 138 { 139 ProductMediaList.Add($"{MediaValue.Value}.gif"); 140 } 141 else 142 { 143 ProductMediaList.Add($"{MediaValue.Value}{ImageFileType}"); 144 145 } 146 } 147 } 148 } 149 150 151 } 152 153 return ProductMediaList; 154 } 155 156 private Dictionary<string, string> GetIconsWithLargeImages(string[] MediaIds) 157 { 158 var ResultList = new Dictionary<string, string>(); 159 if(MediaIds.Count() == 0) 160 { 161 return ResultList; 162 } 163 List<string> CleanIds = new(); 164 // Make sure all Ids are GUID 165 foreach (var MediaId in MediaIds) 166 { 167 var MediaIdIsGuid = Guid.TryParse(MediaId, out Guid MediaIdGuid); 168 if(MediaIdIsGuid) 169 { 170 CleanIds.Add(MediaId); 171 } 172 } 173 // Array 174 string MediaList = string.Join(", ", CleanIds.Select(n => $"'{n}'")); 175 string MediaListSort = string.Join(",", CleanIds.Select(n => $"{n}")); 176 // Query 177 var sqlQuery = $"SELECT Id, Slide FROM Oase_Icons WHERE Id IN ({MediaList}) AND LanguageID = '{Pageview.Area.EcomLanguageId}' ORDER BY CHARINDEX(Id,'{MediaListSort}')"; 178 var rawData = Dynamicweb.Data.Database.CreateDataReader(sqlQuery); 179 while (rawData.Read()) 180 { 181 var iconId = rawData["Id"].ToString(); 182 var iconImage = rawData["Slide"].ToString(); 183 if(ResultList.ContainsKey(iconId) == false) 184 { 185 ResultList.Add(iconId, iconImage); 186 } 187 } 188 return ResultList; 189 } 190 191 private class ListItemProperty 192 { 193 public int Id { get; set; } 194 public string? Property { get; set; } 195 } 196 } 197 198 @{ 199 ProductViewModel product = null; 200 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 201 { 202 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 203 } 204 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 205 { 206 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 207 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 208 209 if (productList?.Products is object) 210 { 211 product = productList.Products[0]; 212 } 213 } 214 215 string PlayCircleIcon = "/Files/Templates/Designs/Swift/Assets/icons/play-circle.svg"; 216 217 string LightboxClass = Pageview.Item.SystemName == "Swift_CatalogPage" ? "lysboks" : "glightbox"; 218 } 219 220 @if (product is object) 221 { 222 @* Supported formats *@ 223 supportedImageFormats = new string[] { ".jpg", ".jpeg", ".webp", ".png", ".gif", ".bmp", ".tiff" }; 224 supportedVideoFormats = new string[] { "youtu.be", "youtube", "vimeo", ".mp4", ".webm" }; 225 supportedDocumentFormats = new string[] { ".pdf", ".docx", ".xlsx", ".ppt", "pptx" }; 226 allSupportedFormats = supportedImageFormats.Concat(supportedVideoFormats).Concat(supportedDocumentFormats).ToArray(); 227 228 @* Collect the assets *@ 229 var selectedAssetCategories = Model.Item.GetList("ImageAssets")?.GetRawValue().OfType<string>(); 230 bool includeImagePatternImages = Model.Item.GetBoolean("ImagePatternImages"); 231 232 @* Needed image data collection to support both DefaultImage, ImagePatterns and Image Assets *@ 233 string defaultImage = product.DefaultImage != null ? product.DefaultImage.Value : ""; 234 IEnumerable<MediaViewModel> assetsImages = product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets); 235 assetsImages = assetsImages.OrderByDescending(x => x.Value.Equals(defaultImage)); 236 IEnumerable<MediaViewModel> assetsList = new MediaViewModel[] { }; 237 assetsList = assetsList.Union(assetsImages); 238 assetsList = includeImagePatternImages ? assetsList.Union(product.ImagePatternImages) : assetsList; 239 assetsList = includeImagePatternImages && assetsList.Count() == 0 ? assetsList.Append(product.DefaultImage) : assetsList; 240 241 //var ProductMediaList = new List<string>(); 242 var ImageFileType = Model.Item.GetString("MediaFileType", ".jpg"); 243 var ImageBackgroundColor = Model.Item.GetString("BackgroundColor", "#f6f6f6"); 244 245 string[] MediaSourceList = []; 246 try 247 { 248 var MediaSourceListId = Model.Item.GetInt32("MediaSourceList"); 249 var MediaSourceListSelected = Dynamicweb.Content.Items.ItemList.GetItemListById(MediaSourceListId).Relations; 250 var MediaSourceListString = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ListItemProperty>>(Newtonsoft.Json.JsonConvert.SerializeObject(MediaSourceListSelected)); 251 MediaSourceList = MediaSourceListString.Select(a => a.Property).ToArray(); 252 } catch {} 253 254 var ProductMediaList = GetProductMedia(product, MediaSourceList, ImageFileType); 255 256 var ProductIconsList = new Dictionary<string, string>(); 257 if (MediaSourceList.Count() == 1 && MediaSourceList.First() == "Icons") 258 { 259 ProductIconsList = GetIconsWithLargeImages(ProductMediaList?.ToArray()); 260 } 261 262 bool defaultImageFallback = Model.Item.GetBoolean("DefaultImageFallback"); 263 bool showOnlyPrimaryImage = Model.Item.GetBoolean("ShowOnlyPrimaryImage"); 264 265 // Options 266 var ShowBadges = Model.Item.GetBoolean("ShowBadges"); 267 var ShowCollectionLogo = Model.Item.GetBoolean("ShowCollectionLogo"); 268 var ShowBrandLogo = Model.Item.GetBoolean("ShowBrandLogo"); 269 var ShowBestseller = Model.Item.GetBoolean("ShowBestseller"); 270 271 // Option settings 272 var BadgePosition = Model.Item.GetString("BadgePosition", "topleft"); 273 var CollectionLogoPosition = Model.Item.GetString("CollectionLogoPosition", "topleft"); 274 var BestsellerPosition = Model.Item.GetString("BestsellerPosition", "topleft"); 275 276 // Position lookup 277 var PositionDict = new Dictionary<string, string>() 278 { 279 { "topleft", "top-0"}, 280 { "topright", "top-0 end-0"}, 281 { "bottomleft", "bottom-0"}, 282 { "bottomright", "bottom-0 end-0"}, 283 }; 284 285 string BadgeBackground = Model.Item.GetRawValueString("BadgeBackground", "transparent"); 286 string BadgeTextColor = Model.Item.GetRawValueString("BadgeTextColor", "#ffffff"); 287 string BadgeFontWeight = Model.Item.GetRawValueString("FontWeight", "fw-normal"); 288 string BadgeFontStyle = Model.Item.GetRawValueString("FontStyle", "fst-normal"); 289 string BadgeFontSize = Model.Item.GetRawValueString("FontSize", ""); 290 string? ProductBestseller = product.ProductFields.GetValueOrDefault("Bestseller")?.Value.ToString(); 291 string? ProductSplash = product.ProductFields.GetValueOrDefault("OutletcampingSplash")?.Value.ToString(); 292 293 string BestsellerBackground = Model.Item.GetRawValueString("BestsellerBackground", "transparent"); 294 string BestsellerTextColor = Model.Item.GetRawValueString("BestsellerTextColor", "#ffffff"); 295 296 string imageWidth = Model.Item.GetString("ImageWidth"); 297 string imageMaxHeight = Model.Item.GetString("ImageMaxHeight"); 298 299 string layout = Model.Item.GetRawValueString("Layout"); 300 301 int totalAssets = ProductMediaList.Count; 302 totalAssets += ProductIconsList.Count; 303 304 @* Theme settings *@ 305 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 306 307 var ParagraphTitle = Model.Item.GetString("Title"); 308 309 @* Get assets from selected categories or get all assets *@ 310 if (totalAssets != 0) 311 { 312 int assetNumber = 0; 313 int thumbnailNumber = 0; 314 int modalAssetNumber = 0; 315 string thumbnailAxisCss = GetThumbnailPlacement() == "bottom" ? "flex-column" : string.Empty; 316 317 int modelId = Model.ID; 318 string size = "mobile"; 319 320 if (string.IsNullOrWhiteSpace(ParagraphTitle) == false || ProductMediaList.Count == 0) 321 { 322 <h6 class="paragraph-title">@ParagraphTitle</h6> 323 } 324 325 if(layout == "grid") 326 { 327 if(ProductIconsList.Count > 0) 328 { 329 <div class="d-flex flex-wrap gap-2 align-items-start justify-content-start"> 330 @foreach (var ProductIcon in ProductIconsList) 331 { 332 string smallImagePath = $"/Admin/Public/GetImage.ashx?image=/files/images/products/{ProductIcon.Key}{ImageFileType}&width=1200&format=webp"; 333 string largeImagePath = $"/Admin/Public/GetImage.ashx?image=/files/images/products/{ProductIcon.Value}{ImageFileType}&width=1200&format=webp"; 334 <a href="@largeImagePath" class="@(LightboxClass)" data-gallery="[email protected]"> 335 <img src="@smallImagePath" class="ratio-1x1" style="width:60px;" alt="image" /> 336 </a> 337 } 338 </div> 339 } else 340 { 341 string containerGap = string.IsNullOrWhiteSpace(imageWidth) ? $"gap-2" : ""; 342 <div class="d-flex flex-wrap @(containerGap) align-items-start justify-content-start"> 343 @foreach (var ProductMediaItem in ProductMediaList) 344 { 345 string imageStyle = !string.IsNullOrWhiteSpace(imageWidth) ? $"width:{imageWidth}%" : ""; 346 string imageClass = !string.IsNullOrWhiteSpace(imageWidth) ? $"w-100 {imageWidth} p-2" : ""; 347 string imagePathL = $"/Admin/Public/GetImage.ashx?image=/files/images/products/{ProductMediaItem}&width=1200&format=webp"; 348 string imageItemStyle = !string.IsNullOrWhiteSpace(imageMaxHeight) ? $"max-height:{imageMaxHeight}px!important;" : ""; 349 <a href="@imagePathL" class="@(LightboxClass) @imageClass" data-gallery="[email protected]"> 350 <img src="@imagePathL" class="mw-100" style="@(imageItemStyle)" alt="image" /> 351 </a> 352 } 353 </div> 354 } 355 } 356 if (layout == "column") 357 { 358 <div class="d-flex flex-column flex-wrap align-items-start justify-content-start"> 359 @foreach (var ProductMediaItem in ProductMediaList) 360 { 361 string imagePathL = $"/Admin/Public/GetImage.ashx?image=/files/images/products/{ProductMediaItem}&width=1200&format=webp"; 362 <img src="@imagePathL" class="w-100" alt="image" /> 363 } 364 </div> 365 } 366 if (string.IsNullOrWhiteSpace(layout) || layout == "slider") 367 { 368 <div class="container w-100 overflow-hidden position-relative p-0 @(theme)" style="aspect-ratio:16/9;"> 369 @if (ShowCollectionLogo) 370 { 371 var PositionClass = PositionDict[CollectionLogoPosition]; 372 if (ShowBrandLogo) 373 { 374 var ProductBrandName = product?.ProductFields.GetValueOrDefault("BrandName")?.Value.ToString()?.ToLower(); 375 var ProductCollectionLogo = ProductBrandName switch 376 { 377 "outwell" => "/Files/Images/Logos/ow-logo.png", 378 "robens" => "/Files/Images/Logos/robens.png", 379 "easycamp" => "/Files/Images/Logos/easycamp.png", 380 "easy camp" => "/Files/Images/Logos/easycamp.png", 381 "xhelter" => "/Files/Images/Logos/xhelter_logo.png", 382 _ => "" 383 }; 384 <img src="@ProductCollectionLogo" class="position-absolute @(PositionClass) m-2 m-lg-3 d-none d-lg-block" style="height:40px;z-index:2;" alt="image" /> 385 } else 386 { 387 var ProductCollectionLogo = product?.ProductFields.GetValueOrDefault("CollectionLogo"); 388 if (!string.IsNullOrWhiteSpace(ProductCollectionLogo?.Value.ToString())) 389 { 390 string imagePathL = $"/Admin/Public/GetImage.ashx?image=/files/images/products/{ProductCollectionLogo}.png&width=400&format=webp"; 391 <img src="@imagePathL" class="position-absolute @(PositionClass) m-2 m-lg-3 d-none d-lg-block collection-logo" style="height:30px;z-index:2;" alt="image" /> 392 <img src="@imagePathL" class="position-absolute @(PositionClass) m-2 m-lg-3 d-block d-lg-none collection-logo" style="height:15px;z-index:2;" alt="image" /> 393 } 394 } 395 } 396 397 @if (ShowBadges) 398 { 399 if (!string.IsNullOrWhiteSpace(ProductSplash) && ProductSplash != "CONT.") 400 { 401 var PositionClass = PositionDict[BadgePosition]; 402 <div class="position-absolute @(PositionClass) fs-6 fs-lg-5 lh-1 m-1" style="z-index:2;"> 403 @if (string.IsNullOrWhiteSpace(ProductSplash) == false) 404 { 405 BadgeFontSize = BadgeFontSize.Replace("fs-", "fs-lg-"); 406 <span class="badge rounded-0 fs-7 @(BadgeFontSize) @(BadgeFontWeight) @(BadgeFontStyle)" style="background-color:@(BadgeBackground);color:@(BadgeTextColor);">@ProductSplash</span> 407 } 408 </div> 409 } 410 411 } 412 413 @if (ShowBestseller) 414 { 415 if (!string.IsNullOrWhiteSpace(ProductBestseller)) 416 { 417 var PositionClass = PositionDict[BestsellerPosition]; 418 <div class="position-absolute @(PositionClass) fs-6 fs-lg-5 lh-1 m-2 m-lg-3" style="z-index:2;"> 419 @if (ProductBestseller == "1") 420 { 421 var BadgePadding = BestsellerBackground == "transparent" ? "p-0" : ""; 422 <span class="badge rounded-0 fw-normal @(BadgePadding)" style="background-color:@(BestsellerBackground);color:@(BestsellerTextColor);"> 423 @Translate("Bestseller") 424 </span> 425 } 426 </div> 427 } 428 } 429 <div class="product-swiper swiper w-100 h-100 border" id="[email protected]"> 430 <!-- Additional required wrapper --> 431 <div class="swiper-wrapper"> 432 <!-- Slides --> 433 @foreach (var ProductMediaItem in ProductMediaList) 434 { 435 if(ProductMediaItem.Contains("youtu")) 436 { 437 <div class="swiper-slide h-100"> 438 <a href="@ProductMediaItem" class="@(LightboxClass) w-100" data-gallery="[email protected]"> 439 <img src="@GetYoutubeScreenDump(ProductMediaItem, "maxresdefault")" class="w-100" alt="product video" /> 440 <div class="overlay-full display-1 text-white"> 441 <span class="icon-7">@ReadFile(PlayCircleIcon)</span> 442 </div> 443 </a> 444 </div> 445 } 446 else if (ProductMediaItem.Contains("matterport.com")) 447 { 448 string imagePathL = $"/Admin/Public/GetImage.ashx?image={product?.DefaultImage?.Value}&width=1200&quality=100&format=webp"; 449 <div class="swiper-slide h-100 position-relative"> 450 <a href="@(ProductMediaItem)&play=1" class="@(LightboxClass) w-100" data-width="100vw" data-height="100vh" data-gallery="[email protected]"> 451 <img src="@imagePathL" class="w-100" alt="image" /> 452 <div class="overlay-full display-1 text-white"> 453 <span class="icon-7 mt-4">@ReadFile(PlayCircleIcon) <small class="fs-4 mt-lg-3">360&deg;</small></span> 454 </div> 455 </a> 456 </div> 457 } 458 else if (ProductMediaItem.Contains("360company.dk")) 459 { 460 string imagePathL = $"/Admin/Public/GetImage.ashx?image={product?.DefaultImage?.Value}&width=1200&quality=100&format=webp"; 461 <div class="swiper-slide h-100 position-relative"> 462 <a href="@(ProductMediaItem)&play=1" class="@(LightboxClass) w-100" data-width="100vw" data-height="100vh" data-gallery="[email protected]"> 463 <img src="@imagePathL" class="w-100" alt="image" /> 464 <div class="overlay-full display-1 text-white"> 465 <span class="icon-7 mt-4">@ReadFile(PlayCircleIcon) <small class="fs-4 mt-lg-3">360&deg;</small></span> 466 </div> 467 </a> 468 </div> 469 } 470 else 471 { 472 string smallImagePath = $"/Admin/Public/GetImage.ashx?image=/files/images/products/{ProductMediaItem}&width=1200&quality=90&format=webp"; 473 string largeImagePath = $"/Admin/Public/GetImage.ashx?image=/files/images/products/{ProductMediaItem}&width=1920&quality=100&format=webp"; 474 475 string PngImageBackground = $"background-image:url('{largeImagePath}');background-position:center;background-size:contain;background-repeat:no-repeat;"; 476 477 bool ImageIsPng = ProductMediaItem.EndsWith(".png"); 478 bool ImageIsGif = ProductMediaItem.EndsWith(".gif"); 479 if (ImageIsPng) 480 { 481 PngImageBackground = $"background-color:{ImageBackgroundColor};"; 482 } 483 if(ImageIsGif) 484 { 485 smallImagePath = $"/files/images/products/{ProductMediaItem}"; 486 largeImagePath = $"/files/images/products/{ProductMediaItem}"; 487 } 488 <div class="swiper-slide" style="@PngImageBackground"> 489 <a href="@largeImagePath" class="@(LightboxClass) w-100" data-gallery="[email protected]"> 490 <div class="w-100 h-100 ratio ratio-16x9"> 491 @if (ImageIsPng) 492 { 493 var IsFirstImage = ProductMediaList.IndexOf(ProductMediaItem) == 0; 494 <img src="@smallImagePath" fetchpriority="@(IsFirstImage ? "high" : "low")" class="img-fluid h-100" alt="image" /> 495 } 496 @if (ImageIsGif) 497 { 498 var IsFirstImage = ProductMediaList.IndexOf(ProductMediaItem) == 0; 499 <div class="w-100 h-100 bg-white text-center"> 500 <img src="@smallImagePath" fetchpriority="@(IsFirstImage ? "high" : "low")" class="img-fluid h-100" alt="image" /> 501 </div> 502 } 503 </div> 504 </a> 505 </div> 506 } 507 } 508 </div> 509 <!-- If we need pagination --> 510 <div class="swiper-pagination d-none" id="swiper_@(Model.Item.ParagraphID)-pagination"></div> 511 512 <!-- If we need navigation buttons --> 513 <div class="swiper-button-prev d-none d-md-flex" id="swiper_@(Model.Item.ParagraphID)-prev"></div> 514 <div class="swiper-button-next d-none d-md-flex" id="swiper_@(Model.Item.ParagraphID)-next"></div> 515 </div> 516 </div> 517 518 <div class="container w-100 overflow-hidden p-0 pb-3 @(theme)" style="max-height:100px;"> 519 <div thumbsSlider="" class="product-swiper swiper w-100 h-100 swiper-thumbnail my-2" id="[email protected]" style="max-width:90vw;"> 520 <div class="swiper-wrapper"> 521 <!-- Slides --> 522 @foreach (var ProductMediaItem in ProductMediaList) 523 { 524 if(ProductMediaItem.Contains("youtu")) 525 { 526 <div class="swiper-slide border" style="height:auto;cursor:pointer;"> 527 <div class="d-flex flex-column h-100"> 528 <img src="@GetYoutubeScreenDump(ProductMediaItem, "maxresdefault")" class="w-100 h-100" alt="product video" fetchpriority="low" /> 529 <div class="overlay-full fs-5 text-white"> 530 <span class="icon-3">@ReadFile(PlayCircleIcon)</span> 531 </div> 532 </div> 533 </div> 534 } 535 else if (ProductMediaItem.Contains("matterport.com")) 536 { 537 string imagePathL = $"/Admin/Public/GetImage.ashx?image={product?.DefaultImage?.Value}&width=1200&quality=100&format=webp"; 538 <div class="swiper-slide border position-relative" style="height:auto;cursor:pointer;"> 539 <div class="d-flex flex-column h-100"> 540 <img src="@imagePathL" class="w-100 h-100" alt="image" fetchpriority="low" /> 541 <div class="overlay-full fs-5 text-white">360&deg;</div> 542 </div> 543 </div> 544 } 545 else if (ProductMediaItem.Contains("360company.dk")) 546 { 547 string imagePathL = $"/Admin/Public/GetImage.ashx?image={product?.DefaultImage?.Value}&width=1200&quality=100&format=webp"; 548 <div class="swiper-slide border position-relative" style="height:auto;cursor:pointer;"> 549 <div class="d-flex flex-column h-100"> 550 <img src="@imagePathL" class="w-100 h-100" alt="image" fetchpriority="low" /> 551 <div class="overlay-full fs-5 text-white">360&deg;</div> 552 </div> 553 </div> 554 } 555 else 556 { 557 string PngImageBackground = ""; 558 if (ProductMediaItem.EndsWith(".png")) 559 { 560 PngImageBackground = $"background-color:{ImageBackgroundColor};"; 561 } 562 string imagePathL = $"/Admin/Public/GetImage.ashx?image=/files/images/products/{ProductMediaItem}&width=1200&quality=90&format=webp"; 563 <div class="swiper-slide border" style="height:auto;cursor:pointer;@(PngImageBackground)"> 564 <div class="d-flex flex-column h-100 ratio ratio-16x9" style="background-image:url('@imagePathL');background-position:center;background-size:contain;background-repeat:no-repeat;"> 565 </div> 566 </div> 567 } 568 } 569 </div> 570 <!-- If we need navigation buttons --> 571 <div class="swiper-button-prev d-none d-md-flex" id="thumbs_@(Model.Item.ParagraphID)-prev" style="width:2rem!important;height:2rem!important;"></div> 572 <div class="swiper-button-next d-none d-md-flex" id="thumbs_@(Model.Item.ParagraphID)-next" style="width:2rem!important;height:2rem!important;"></div> 573 </div> 574 </div> 575 576 <link rel="stylesheet" href="/Files/Templates/Designs/Swift/Assets/css/swiper-bundle.min.css" /> 577 <script src="/Files/Templates/Designs/Swift/Assets/js/swiper-bundle.min.js"></script> 578 <script> 579 document.querySelectorAll('.swiper').forEach(slider => { 580 581 if(slider.classList.contains("swiper-initialized") || slider.classList.contains("swiper-thumbnail")) { 582 return null; 583 } 584 585 var thumbs = null; 586 var thumbsNode = document.querySelector("#thumbs_@(Model.Item.ParagraphID)"); 587 if(thumbsNode != null) 588 { 589 thumbs = new Swiper(`#thumbs_@(Model.Item.ParagraphID)`, { 590 spaceBetween: 10, 591 slidesPerView: 4.2, 592 freeMode: false, 593 watchSlidesProgress: true, 594 breakpoints: { 595 // when window width is >= 640px 596 640: { 597 slidesPerView: 7, 598 } 599 }, 600 // Navigation arrows 601 navigation: { 602 nextEl: `#thumbs_@(Model.Item.ParagraphID)-next`, 603 prevEl: `#thumbs_@(Model.Item.ParagraphID)-prev`, 604 }, 605 }); 606 } 607 608 return new Swiper(`#${slider.id}`, { 609 // Optional parameters 610 direction: 'horizontal', 611 loop: false, 612 spaceBetween: 10, 613 slidesPerView: 'auto', 614 615 thumbs: { 616 swiper:thumbs, 617 }, 618 619 // If we need pagination 620 pagination: { 621 el: `#${slider.id}-pagination`, 622 }, 623 624 // Navigation arrows 625 navigation: { 626 nextEl: `#${slider.id}-next`, 627 prevEl: `#${slider.id}-prev`, 628 }, 629 630 // And if we need scrollbar 631 scrollbar: { 632 el: `#${slider.id}-scrollbar`, 633 }, 634 }); 635 }); 636 </script> 637 } 638 } 639 else if (Pageview.IsVisualEditorMode) 640 { 641 RatioSettings ratioSettings = GetRatioSettings("desktop"); 642 643 <div class="h-100 @theme"> 644 <div class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)"> 645 <img src="/Files/Images/missing_image.jpg" loading="lazy" decoding="async" class="mh-100 mw-100" style="object-fit: cover;"> 646 </div> 647 </div> 648 } 649 } 650 else if (Pageview.IsVisualEditorMode) 651 { 652 <div class="alert alert-dark m-0">@Translate("No products available")</div> 653 } 654 655 656 657

Carnelian DC 500

Krachtige oplaadbare lantaarn met dimbaar licht (10–100 %), draaghandvat en ophangfunctie. Wordt geleverd met USB-C-laadkabel voor betrouwbare verlichting.
Error executing template "Designs/Swift/Paragraph/Swift_ProductPrice.cshtml"
System.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the login process. (provider: SSL Provider, error: 0 - An existing connection was forcibly closed by the remote host.)
 ---> System.ComponentModel.Win32Exception (10054): An existing connection was forcibly closed by the remote host.
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.Open()
   at Dynamicweb.Data.DatabaseConnectionProvider.CreateConnection(Boolean open)
   at Dynamicweb.Data.Database.CreateConnection()
   at Dynamicweb.Data.Database.CreateDataReader(CommandBuilder commandBuilder, IDbConnection connection, IDbTransaction transaction, Int32 commandTimeout)
   at Dynamicweb.Ecommerce.Products.ProductRepository.GetProductsBySql(CommandBuilder query, Boolean doRefactoring, Boolean bulkFill, Boolean useAssortments)
   at Dynamicweb.Ecommerce.Products.ProductRepository.GetAllVariantProducts(IEnumerable`1 productIds, String productLanguageId)
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetBulkVariants(IEnumerable`1 productIds, String languageId)
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass9_1.<BulkCreateView>b__6()
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at CompiledRazorTemplates.Dynamic.RazorEngine_7d90283a55994268856c503693ceb802.ExecuteAsync()
   at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
ClientConnectionId:8a753fce-c3a2-41fc-b7b8-64e8fbbf7650
Error Number:10054,State:0,Class:20

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 4 @{ 5 ProductViewModel product = null; 6 if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) 7 { 8 product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; 9 } 10 else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) 11 { 12 var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); 13 ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); 14 15 if (productList?.Products is object) 16 { 17 product = productList.Products[0]; 18 } 19 } 20 21 string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); 22 bool anonymousUser = Pageview.User == null; 23 bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); 24 bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; 25 26 bool productIsDiscontinued = product is object && product.Discontinued; 27 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 28 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 29 30 var ShowAsOffer = Model.Item.GetBoolean("ShowAsOffer"); 31 var PriceOfferScope = ShowAsOffer ? "itemprop=\"offers\" itemscope itemtype=\"https://schema.org/Offer\"" : ""; 32 var ShowSavePercent = Model.Item.GetBoolean("ShowSavePercent"); 33 var ShowViabill = Model.Item.GetBoolean("ShowViabill"); 34 } 35 36 @if (product is object && !hidePrice && !isDiscontinued) { 37 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 38 bool showPriceBefore = Model.Item.GetBoolean("ShowPriceBefore"); 39 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 40 41 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-2"); 42 priceFontSize = priceFontSize == "fs-6" ? "fs-8 fs-lg-6" : priceFontSize; 43 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 44 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 45 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 46 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 47 var textFontWight = Model.Item.GetRawValueString("FontWeight", "fw-normal"); 48 49 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 50 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 51 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 52 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 53 54 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 55 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 56 string order = layout == "horizontal" ? string.Empty : "order-2"; 57 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? "theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 58 theme = GetViewParameter("theme") != null ? GetViewParameterString("theme") : theme; 59 60 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 61 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 62 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 63 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 64 65 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 66 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 67 68 string priceMin = ""; 69 string priceMax = ""; 70 71 string liveInfoClass = ""; 72 string productInfoFeed = ""; 73 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 74 if (isLazyLoadingForProductInfoEnabled) 75 { 76 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 77 { 78 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 79 if (!string.IsNullOrEmpty(productInfoFeed)) 80 { 81 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 82 } 83 } 84 liveInfoClass = "js-live-info"; 85 } 86 87 var ProductPriceBefore = product.ProductFields.GetValueOrDefault("PriceBefore")?.Value.ToString(); 88 var ProductWEEE = product.ProductFields.GetValueOrDefault("UnitWEEEcontributionFR")?.Value.ToString(); 89 90 <div class="@textAlign @liveInfoClass [email protected]()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 91 @if (showInformativePrice && !string.IsNullOrWhiteSpace(ProductPriceBefore)) 92 { 93 var PriceBeforeEqualToPrice = product.Price.Price.ToString() == ProductPriceBefore; 94 if (PriceBeforeEqualToPrice == false) 95 { 96 var parsePriceBefore = Decimal.TryParse(ProductPriceBefore, Pageview.Area.CultureInfo, out decimal parsePriceBeforeDecimal); 97 if (parsePriceBeforeDecimal > 0) 98 { 99 <div class="opacity-50 fs-8"> 100 <span>@Translate("RRP") </span> 101 <span class="text-price"> 102 @if (parsePriceBefore) 103 { 104 @String.Format(Pageview.Area.CultureInfo, "{0:N2}", parsePriceBeforeDecimal) 105 } 106 else 107 { 108 @ProductPriceBefore 109 } 110 </span> 111 </div> 112 } 113 } 114 } 115 116 @if (showPriceBefore && !string.IsNullOrWhiteSpace(ProductPriceBefore)) 117 { 118 var PriceBeforeEqualToPrice = product.Price.Price.ToString() == ProductPriceBefore; 119 if (PriceBeforeEqualToPrice == false) 120 { 121 var parsePriceBefore = Decimal.TryParse(ProductPriceBefore, Pageview.Area.CultureInfo, out decimal parsePriceBeforeDecimal); 122 if (parsePriceBeforeDecimal > 0) 123 { 124 <div class="opacity-50 fs-8"> 125 <span>@Translate("Before") </span> 126 <span class="text-price"> 127 @if (parsePriceBefore) 128 { 129 @String.Format(Pageview.Area.CultureInfo, "{0:N2}", parsePriceBeforeDecimal) 130 } 131 else 132 { 133 @ProductPriceBefore 134 } 135 </span> 136 </div> 137 } 138 } 139 } 140 141 @if (ShowAsOffer) 142 { 143 <meta itemprop="name" content="@product?.Name" /> 144 <meta itemprop="disambiguatingDescription" content="@product?.ShortDescription" /> 145 <meta itemprop="gtin13" content="@product?.EAN" /> 146 <meta itemprop="image" content="@(product?.DefaultImage?.Value)" /> 147 <meta itemprop="brand" content="@product?.ProductFields.GetValueOrDefault("BrandName")?.Value" /> 148 } 149 150 <div class="@priceFontSize m-0 d-flex flex-wrap @flexDirection @flexGap @horizontalAlign @textFontWight" style="row-gap: 0 !important" @PriceOfferScope> 151 @if(ShowAsOffer) 152 { 153 <meta itemprop="priceCurrency" content="@product.Price.CurrencyCode" /> 154 <meta itemprop="price" content="@product.Price.Price.ToString().Replace(",", ".")"> 155 <link itemprop="url" href="@Pageview.SearchFriendlyUrl"> 156 @if (product.StockLevel > 0) 157 { 158 <link itemprop="availability" href="https://schema.org/InStock"> 159 } 160 else 161 { 162 var AvailableAgainDate = (DateTime?)product.ProductFields.GetValueOrDefault("AvailableAgain")?.Value; 163 var IsAvailableAgain = AvailableAgainDate != null && (AvailableAgainDate > DateTime.Parse("1901-01-01")); 164 if (product.StockLevel <= 0 && IsAvailableAgain) 165 { 166 <link itemprop="availability" href="https://schema.org/PreOrder"> 167 } 168 else 169 { 170 <link itemprop="availability" href="https://schema.org/OutOfStock"> 171 } 172 } 173 } 174 @if (showPricesWithVat == "false" && !neverShowVat) 175 { 176 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 177 { 178 <span class="text-decoration-line-through js-text-decoration-line-through opacity-75 me-3 text-price js-text-price d-none" data-show-if="LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price"></span> 179 } 180 else 181 { 182 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 183 184 if (product.Price.Price != product.PriceBeforeDiscount.Price) 185 { 186 <span class="text-decoration-line-through opacity-75 @order">@beforePrice</span> 187 } 188 } 189 } 190 else 191 { 192 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 193 { 194 <span class="text-decoration-line-through js-text-decoration-line-through opacity-75 me-3 text-price js-text-price d-none" data-show-if="LiveProductInfo.product.Price.Price != LiveProductInfo.product.PriceBeforeDiscount.Price"></span> 195 } 196 else 197 { 198 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 199 200 if (product.Price.Price != product.PriceBeforeDiscount.Price) 201 { 202 <span class="text-decoration-line-through opacity-75 @order"> 203 <span class="text-price">@beforePrice</span> 204 </span> 205 } 206 } 207 } 208 209 @if (showPricesWithVat == "false" && !neverShowVat) 210 { 211 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 212 { 213 <span class="text-price js-text-price"> 214 <span class="spinner-border" role="status"></span> 215 </span> 216 } 217 else 218 { 219 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 220 221 if (product?.VariantInfo?.VariantInfo != null) 222 { 223 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 224 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 225 } 226 if (priceMin != priceMax) 227 { 228 price = priceMin + " - " + priceMax; 229 } 230 <span class="@theme @contentPadding"> 231 <span class="text-price">@price</span> 232 </span> 233 } 234 } 235 else 236 { 237 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 238 { 239 <span class="text-price js-text-price"> 240 <span class="spinner-border" role="status"></span> 241 </span> 242 } 243 else 244 { 245 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 246 string? savePercent = product?.ProductFields.GetValueOrDefault("Savepct")?.Value?.ToString(); 247 248 if (product?.VariantInfo?.VariantInfo != null) 249 { 250 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 251 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 252 } 253 if (priceMin != priceMax) 254 { 255 price = priceMin + " - " + priceMax; 256 } 257 <span class="@theme @contentPadding d-flex flex-column"> 258 @if (ShowSavePercent && !string.IsNullOrWhiteSpace(savePercent)) 259 { 260 <span class="text-danger lh-1 fs-8 fs-lg-6">@Translate("SavePercent") @savePercent %</span> 261 } 262 <span class="text-price">@price</span> 263 </span> 264 } 265 } 266 267 </div> 268 269 @if (showPricesWithVat == "false" && !neverShowVat) 270 { 271 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 272 { 273 <small class="opacity-85 fst-normal js-text-price-with-vat d-none" data-suffix="@Translate("Incl. VAT")"></small> 274 } 275 else 276 { 277 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 278 279 if (product?.VariantInfo?.VariantInfo != null) 280 { 281 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 282 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 283 } 284 if (priceMin != priceMax) 285 { 286 price = priceMin + " - " + priceMax; 287 } 288 <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> 289 } 290 } 291 @if (ShowViabill) 292 { 293 <div class="viabill-pricetag" 294 data-view="product" 295 data-price="@product?.Price.PriceFormattedNoSymbol" 296 data-currency="@product?.Price.CurrencyCode"> 297 </div> 298 <script> 299 (function(){ 300 var o=document.createElement('script'); 301 o.type='text/javascript'; 302 o.async=true; 303 o.src='https://pricetag.viabill.com/script/5kjDlkPvm6I%3D'; 304 var s=document.getElementsByTagName('script')[0]; 305 s.parentNode.insertBefore(o,s); 306 })(); 307 </script> 308 } 309 310 @if (!string.IsNullOrWhiteSpace(ProductWEEE)) 311 { 312 if (ProductWEEE == "1") 313 { 314 <p class="small">Dont éco-participation (Ecomaison)</p> 315 } 316 if (ProductWEEE == "2") 317 { 318 <p class="small">Dont éco-participation DEEE (Ecosystem)</p> 319 } 320 } 321 </div> 322 } 323 else if (Pageview.IsVisualEditorMode) 324 { 325 <div class="alert alert-dark m-0" role="alert"> 326 <span>@Translate("No products available")</span> 327 </div> 328 } 329
  Uitverkocht
Icon for payment method
Icon for payment method
Icon for payment method

De Outwell Carnelian DC 500 biedt handige en flexibele verlichting voor al je outdooractiviteiten. Compact maar krachtig, met draaghandvat en ophangfunctie voor veelzijdig gebruik. De geïntegreerde dimmer past de helderheid aan van 10–100 % door de knop ingedrukt te houden. Inclusief USB-C-laadkabel voor betrouwbare stroom – een onmisbare lamp voor zorgeloze verlichting.

Materiaal
ABS, rubber, aluminium, TPR
Afmeting
9.5 x 9.5 x 18.5 (BxDxH)
Batterijen
2200 mAh Li batterij
Source
SMD LED, 500 Lumens, 2700 Kelvin
Capaciteit
500 lumens
Kleur
Blue Shadow
Gewicht
440 g
EAN
5709388157706
Number
651333

  • Draaghengsel
  • Ophanghaak
  • Lichtdimmer 10 - 100%
  • Houd de knop ingedrukt om het licht te dimmen
  • USB-laadkabel meegeleverd
  • Oplaadbaar, met USB-C-ingang

Error executing template "Designs/Swift/Components/Specifications/Images.cshtml"
System.Data.SqlClient.SqlException (0x80131904): A connection was successfully established with the server, but then an error occurred during the login process. (provider: SSL Provider, error: 0 - An existing connection was forcibly closed by the remote host.)
 ---> System.ComponentModel.Win32Exception (10054): An existing connection was forcibly closed by the remote host.
   at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.Open()
   at Dynamicweb.Data.DatabaseConnectionProvider.CreateConnection(Boolean open)
   at Dynamicweb.Data.Database.CreateConnection()
   at Dynamicweb.Data.Database.CreateDataReader(String sql, IDbConnection connection, IDbTransaction transaction, Int32 commandTimeout, Dictionary`2 sqlParams)
   at Dynamicweb.Data.Database.CreateDataReader(String sql)
   at CompiledRazorTemplates.Dynamic.RazorEngine_9f4c11a503fb4105bc92b8758be6fb1c.GetIconsWithLargeImages(String[] MediaIds)
   at CompiledRazorTemplates.Dynamic.RazorEngine_9f4c11a503fb4105bc92b8758be6fb1c.ExecuteAsync()
   at RazorEngine.Templating.TemplateBase.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineCore.RunTemplate(ICompiledTemplate template, TextWriter writer, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.DynamicWrapperService.Run(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass23_0.<Run>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at RazorEngine.Templating.RazorEngineServiceExtensions.Run(IRazorEngineService service, String name, Type modelType, Object model, DynamicViewBag viewBag)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
ClientConnectionId:8a753fce-c3a2-41fc-b7b8-64e8fbbf7650
Error Number:10054,State:0,Class:20

1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> 2 @using Dynamicweb.Ecommerce.ProductCatalog 3 @using System.Collections.Generic 4 @functions { 5 private Dictionary<string, string> GetIconsWithLargeImages(string[] MediaIds) 6 { 7 var ResultList = new Dictionary<string, string>(); 8 if(MediaIds.Count() == 0) 9 { 10 return ResultList; 11 } 12 List<string> CleanIds = new(); 13 // Make sure all Ids are GUID 14 foreach (var MediaId in MediaIds) 15 { 16 var MediaIdIsGuid = Guid.TryParse(MediaId, out Guid MediaIdGuid); 17 if(MediaIdIsGuid) 18 { 19 CleanIds.Add(MediaId); 20 } 21 } 22 // Array 23 string MediaList = string.Join(", ", CleanIds.Select(n => $"'{n}'")); 24 string MediaListSort = string.Join(",", CleanIds.Select(n => $"{n}")); 25 // Query 26 var sqlQuery = $"SELECT Id, Slide FROM Oase_Icons WHERE Id IN ({MediaList}) AND LanguageID = '{Pageview.Area.EcomLanguageId}' ORDER BY CHARINDEX(Id,'{MediaListSort}')"; 27 var rawData = Dynamicweb.Data.Database.CreateDataReader(sqlQuery); 28 while (rawData.Read()) 29 { 30 var iconId = rawData["Id"].ToString(); 31 var iconImage = rawData["Slide"].ToString(); 32 if(ResultList.ContainsKey(iconId) == false) 33 { 34 ResultList.Add(iconId, iconImage); 35 } 36 } 37 return ResultList; 38 } 39 } 40 @{ 41 var groups = GetViewParameter("Groups") as List<FieldGroupViewModel>; 42 string size = GetViewParameterString("Size"); 43 bool hideGroupHeaders = GetViewParameterBoolean("HideGroupHeaders"); 44 bool hideTitle = GetViewParameterBoolean("HideTitle"); 45 46 string title = Model.Item.GetString("Title"); 47 string ImageWidth = Model.Item.GetString("ImageWidth"); 48 string IconWidth = Model.Item.GetString("IconWidth"); 49 bool hideLabels = Model.Item.GetBoolean("HideFieldLabels"); 50 string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "display-4"); 51 string tableSizeCss = size == "full" ? "" : " table-sm"; 52 53 if (!hideTitle) 54 { 55 <h2 class="g-col-12 @titleFontSize">@title</h2> 56 } 57 58 <div class="g-col-12 table-responsive"> 59 @foreach (var group in groups) 60 { 61 62 if (!hideGroupHeaders) 63 { 64 <h4 class="g-col-12 h4 mb-0">@group.Name</h4> 65 } 66 67 if(group.SystemName == "FeatureIcons") 68 { 69 var IconsString = string.Join(",", group.Fields); 70 var IconsList = IconsString.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList(); 71 var ProductIconsList = GetIconsWithLargeImages(IconsList.ToArray()); 72 73 <div class="d-flex flex-wrap gap-2 align-items-start justify-content-start my-3"> 74 @foreach (var ProductIcon in ProductIconsList) 75 { 76 string smallImagePath = $"/Admin/Public/GetImage.ashx?image=/files/images/products/{ProductIcon.Key}.jpg&width=1200&format=webp"; 77 string largeImagePath = $"/Admin/Public/GetImage.ashx?image=/files/images/products/{ProductIcon.Value}.jpg&width=1200&format=webp"; 78 <a href="@largeImagePath" class="glightbox" data-gallery="[email protected]"> 79 <img src="@smallImagePath" class="ratio-1x1" style="width:60px;" alt="image" /> 80 </a> 81 } 82 </div> 83 } 84 85 if (group.SystemName == "Dimensions") 86 { 87 <dl class="d-flex flex-wrap"> 88 @foreach (var field in group.Fields) 89 { 90 string imagePathL = $"/Admin/Public/GetImage.ashx?image=/files/images/products/{field.Value}.jpg&width=1200&format=webp"; 91 if (field.SystemName == "Image130Gif") 92 { 93 imagePathL = $"/files/images/products/{field.Value}.gif"; 94 } 95 <dd class="mb-0 text-break ratio-4x3" style="width:@(ImageWidth)%"> 96 <a href="@imagePathL" class="glightbox w-100" data-gallery="[email protected]"> 97 <img class="img-fluid ratio-4x3" src="@imagePathL" /> 98 </a> 99 </dd> 100 } 101 </dl> 102 } 103 104 if(group.SystemName == "Video360") 105 { 106 var iframeSource = group.Fields.FirstOrDefault()?.Value?.ToString(); 107 if (!string.IsNullOrWhiteSpace(iframeSource)) 108 { 109 <div class="ratio ratio-16x9"> 110 <iframe src="@iframeSource" class="w-100 h-100"></iframe> 111 </div> 112 } 113 } 114 } 115 </div> 116 117 } 118 119

Outwell NL