Error executing template "Designs/Swift/eCom/ProductCatalog/ProductViewDetail.cshtml" System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (258): The wait operation timed out. at System.Data.SqlClient.SqlConnection.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.ProductRepository.GetProductKeysByGroupId(String groupId, Boolean useOrderBy, Boolean includeVariants, String productLanguageId, Boolean doRefactoring, Boolean useAssortments) at Dynamicweb.Ecommerce.Orders.Discounts.Discount.ProcessProductSelections(HashSet`1& productKeys, HashSet`1& includedQueries, HashSet`1& excludedQueries) at Dynamicweb.Ecommerce.Orders.Discounts.Discount.GetRelevantProductKeys() at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.StatelessSetLookup(Discount discount, ConcurrentDictionary`2 lookup) at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.InitializeLookup() at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode) --- End of stack trace from previous location --- at System.Lazy`1.CreateValue() at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.GetDiscounts(DiscountApplyType[] discountTypes, String[] productKeys, User user) at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetDiscountInfo(PriceViewModelSettings settings, Product product) 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__DisplayClass15_2.<BulkCreateView>b__47() 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__DisplayClass15_2.<BulkCreateView>b__49() 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.GetPrice(PriceViewModelSettings settings, IList`1 products, Boolean& pricesHasBeenPrepared, Object lock, Lazy`1 priceInfo) at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass15_2.<BulkCreateView>b__50() 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_7fc6851d594d4d42907168b051151cc5.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:e364817e-2466-4e75-8884-af68bd8aab58 Error Number:−2,State:0,Class:11
1 @inherits ViewModelTemplate<ProductViewModel> @using Dynamicweb.Rendering @using Dynamicweb.Ecommerce.ProductCatalog @using Dynamicweb.Core @{ string metaDescription = string.IsNullOrEmpty(Model.MetaDescription) ? Model.Name : Model.MetaDescription; Pageview.Meta.AddTag($"<meta property=\"og:image\" content=\"{Dynamicweb.Context.Current.Request.Url.Scheme}://{Dynamicweb.Context.Current.Request.Url.Host}{Model.DefaultImage.Value}\">"); Pageview.Meta.AddTag($"<meta property=\"og:image:alt\" content=\"{Model.Name}\">"); Pageview.Meta.AddTag($"<meta property=\"og:description\" content=\"{metaDescription}\">"); Pageview.Meta.AddTag("twitter:image", Model.DefaultImage.Value); Pageview.Meta.AddTag("twitter:image:alt", Model.Name); Pageview.Meta.AddTag("twitter:description", metaDescription); } @{ if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) { Dynamicweb.Context.Current.Items["ProductDetails"] = Model; } else { Dynamicweb.Context.Current.Items.Add("ProductDetails", Model); } bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); if (isLazyLoadingForProductInfoEnabled) { string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); bool hasVariantId = !string.IsNullOrEmpty(Model.VariantId); string variantIdParam = hasVariantId ? $"/{Model.VariantId}" : ""; string priceFilledProperties = $"Price,PriceFormatted{(showPricesWithVat == "false" && !neverShowVat ? ",PriceWithVat,PriceWithVatFormatted" : "")}"; string productInfoFeed = $@"/dwapi/ecommerce/products/{Model.Id}{variantIdParam} ?UserId={Converter.ToString(Pageview.User?.ID)} &LanguageId={Pageview.Area.EcomLanguageId}&CurrencyCode={Pageview.Area.EcomCurrencyId}&CountryCode={Pageview.Area.EcomCountryCode}&ShopId={Pageview.Area.EcomShopId} &FilledProperties=Id,Price,PriceBeforeDiscount,StockLevel,VariantInfo,NeverOutOfstock,Prices &PriceSettings.ShowPricesWithVat={Pageview.Area.EcomPricesWithVat} &PriceSettings.FilledProperties={priceFilledProperties} &getproductinfo=true"; Dynamicweb.Context.Current.Items["ProductInfoFeed"] = productInfoFeed; <script type="module"> swift.LiveProductInfo.init(); </script> } } <script> gtag("event", "view_item", { currency: "@Model.Price.CurrencyCode", value: @Model.Price.ToStringInvariant(), items: [ { item_id: "@Model.Number", item_name: "@Dynamicweb.Core.Encoders.HtmlEncoder.JavaScriptStringEncode(Model.Name)", currency: "@Model.Price.CurrencyCode", price: @Model.Price.ToStringInvariant(), discount: @Model.Discount.ToStringInvariant() } ] }); </script> <script> window.addEventListener('load', function (event) { swift.Video.init(); }); </script>
Error executing template "/Designs/Swift/Paragraph/Swift_ProductDetailsImage_Mennt.cshtml" System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (258): The wait operation timed out. at System.Data.SqlClient.SqlConnection.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.ProductRepository.GetProductKeysByGroupId(String groupId, Boolean useOrderBy, Boolean includeVariants, String productLanguageId, Boolean doRefactoring, Boolean useAssortments) at Dynamicweb.Ecommerce.Orders.Discounts.Discount.ProcessProductSelections(HashSet`1& productKeys, HashSet`1& includedQueries, HashSet`1& excludedQueries) at Dynamicweb.Ecommerce.Orders.Discounts.Discount.GetRelevantProductKeys() at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.StatelessSetLookup(Discount discount, ConcurrentDictionary`2 lookup) at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.InitializeLookup() at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode) --- End of stack trace from previous location --- at System.Lazy`1.CreateValue() at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.GetDiscounts(DiscountApplyType[] discountTypes, String[] productKeys, User user) at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetDiscountInfo(PriceViewModelSettings settings, Product product) 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__DisplayClass15_2.<BulkCreateView>b__47() at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode) --- End of stack trace from previous location --- at System.Lazy`1.CreateValue() at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetPrice(PriceViewModelSettings settings, IList`1 products, Boolean& pricesHasBeenPrepared, Object lock, Lazy`1 priceInfo) at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass15_2.<BulkCreateView>b__52() 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_65927e64715543909709b4e2c85c4b71.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:e364817e-2466-4e75-8884-af68bd8aab58 Error Number:−2,State:0,Class:11
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> @using Dynamicweb.Ecommerce.ProductCatalog @using Dynamicweb.Frontend @using System.IO @using System.Text.RegularExpressions; @functions { public ProductViewModel product { get; set; } = new ProductViewModel(); public string galleryLayout { get; set; } public string[] supportedImageFormats { get; set; } public string[] supportedVideoFormats { get; set; } public string[] supportedDocumentFormats { get; set; } public string[] allSupportedFormats { get; set; } public class RatioSettings { public string Ratio { get; set; } public string CssClass { get; set; } public string CssVariable { get; set; } public string Fill { get; set; } } public RatioSettings GetRatioSettings(string size = "desktop") { var ratioSettings = new RatioSettings(); string ratio = Model.Item.GetRawValueString("ImageAspectRatio", ""); ratio = ratio != "0" ? ratio : ""; string cssClass = ratio != "" && ratio != "fill" ? " ratio" : ""; string cssVariable = ratio != "" && ratio != "fill" ? "--bs-aspect-ratio: " + ratio : ""; cssClass = ratio == "fill" && size == "mobile" ? " ratio" : cssClass; cssVariable = ratio == "fill" && size == "mobile" ? "--bs-aspect-ratio: 66%" : cssVariable; ratioSettings.Ratio = ratio; ratioSettings.CssClass = cssClass; ratioSettings.CssVariable = cssVariable; ratioSettings.Fill = ratio == "fill" ? " h-100" : ""; return ratioSettings; } public string GetArrowsColor() { var invertColor = Model.Item.GetBoolean("InvertModalArrowsColor"); var arrowsColor = invertColor ? " carousel-dark" : string.Empty; return arrowsColor; } public string GetThumbnailPlacement() { return Model.Item.GetRawValueString("ThumbnailPlacement", "bottom"); } public string GetThumbnailRowSettingCss() { switch (GetThumbnailPlacement()) { case "bottom": return "d-flex flex-wrap"; case "left": return "d-flex flex-column order-first"; case "right": return "d-flex flex-column order-last"; default: return "d-flex flex-wrap"; } } public Dictionary<string, object> GetVideoParams(MediaViewModel asset, string size) { string assetName = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : asset.Name; string type = GetVideoType(asset.Value); bool openInModal = Model.Item.GetString("OpenVideoInModal") == "true" ? true : false; bool autoPlay = Model.Item.GetBoolean("VideoAutoPlay"); var videoParams = new Dictionary<string, object>(); videoParams.Add("AssetName", asset.Name); videoParams.Add("AssetVideoType", type); videoParams.Add("AssetDisplayName", asset.DisplayName); videoParams.Add("OpenVideoInModal", openInModal); videoParams.Add("VideoAutoPlay", autoPlay); videoParams.Add("Size", size); videoParams.Add("Id", Model.ID); return videoParams; } public string GetVideoType(string assetValue) { string type = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "youtube" : string.Empty; type = assetValue.IndexOf("vimeo", StringComparison.OrdinalIgnoreCase) >= 0 ? "vimeo" : type; type = string.IsNullOrEmpty(type) ? "selfhosted" : type; return type; } public string GetYoutubeScreenDump(string assetValue, string quality) { var regex = new Regex(@"(?:youtube\.com\/.*[\?&]v=|youtu\.be\/|youtube\.com\/embed\/)([\w-]+)(?:\?.*)?"); Match match = regex.Match(assetValue); string videoId = match.Success ? match.Groups[1].Value : string.Empty; string youtubeThumbnail = $"https://img.youtube.com/vi/{videoId}/{quality}.jpg"; return youtubeThumbnail; } } @{ ProductViewModel product = null; if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) { product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; } else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) { var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); if (productList?.Products is object) { product = productList.Products[0]; } } } @if (product is object) { @* Supported formats *@ supportedImageFormats = new string[] { ".jpg", ".jpeg", ".webp", ".png", ".gif", ".bmp", ".tiff" }; supportedVideoFormats = new string[] { "youtu.be", "youtube", "vimeo", ".mp4", ".webm" }; supportedDocumentFormats = new string[] { ".pdf", ".docx", ".xlsx", ".ppt", "pptx" }; allSupportedFormats = supportedImageFormats.Concat(supportedVideoFormats).Concat(supportedDocumentFormats).ToArray(); @* Collect the assets *@ var selectedAssetCategories = Model.Item.GetList("ImageAssets")?.GetRawValue().OfType<string>(); bool includeImagePatternImages = Model.Item.GetBoolean("ImagePatternImages"); @* Needed image data collection to support both DefaultImage, ImagePatterns and Image Assets *@ string defaultImage = product.DefaultImage != null ? product.DefaultImage.Value : ""; IEnumerable<MediaViewModel> assetsImages = product.AssetCategories.Where(x => selectedAssetCategories.Contains(x.SystemName)).SelectMany(x => x.Assets); @* Respect admin sort order (EcomDetails.DetailSortOrder). When SortOrder is available on MediaViewModel, use it so gallery matches admin. Otherwise preserve backend order (often already SortOrder); avoid forcing "default first" so variant's first image (SortOrder 1) shows first. *@ var sortOrderProp = typeof(MediaViewModel).GetProperty("SortOrder") ?? typeof(MediaViewModel).GetProperty("DetailSortOrder"); if (sortOrderProp != null) { assetsImages = assetsImages.OrderBy(a => (int)(sortOrderProp.GetValue(a) ?? int.MaxValue)); } @* If no SortOrder on view model, keep natural order from AssetCategories (do not force default first, so variant image can be first when backend sends it first). *@ IEnumerable<MediaViewModel> assetsList = new MediaViewModel[] { }; assetsList = assetsList.Union(assetsImages); assetsList = includeImagePatternImages ? assetsList.Union(product.ImagePatternImages) : assetsList; assetsList = includeImagePatternImages && assetsList.Count() == 0 ? assetsList.Append(product.DefaultImage) : assetsList; @* Deduplicate by image path so master + variant don't show the same image twice (preserves order of first occurrence) *@ assetsList = assetsList .GroupBy(a => (a?.Value ?? "").Trim(), StringComparer.OrdinalIgnoreCase) .Select(g => g.First()) .ToList(); bool defaultImageFallback = Model.Item.GetBoolean("DefaultImageFallback"); bool showOnlyPrimaryImage = Model.Item.GetBoolean("ShowOnlyPrimaryImage"); int totalAssets = 0; if (showOnlyPrimaryImage == false) { foreach (MediaViewModel asset in assetsList) { var assetValue = asset.Value; foreach (string format in allSupportedFormats) { if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { totalAssets++; } } } } if ((totalAssets == 0 && product.DefaultImage != null && selectedAssetCategories.Count() == 0) || (showOnlyPrimaryImage == true && product.DefaultImage != null) || totalAssets == 0 && defaultImageFallback) { assetsList = new List<MediaViewModel>() { product.DefaultImage }; totalAssets = 1; } @* Theme settings *@ string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; var badgeParms = new Dictionary<string, object>(); badgeParms.Add("size", "h5"); badgeParms.Add("saleBadgeType", Model.Item.GetRawValue("SaleBadgeType")); badgeParms.Add("saleBadgeCssClassName", Model.Item.GetRawValue("SaleBadgeDesign")); badgeParms.Add("newBadgeCssClassName", Model.Item.GetRawValue("NewBadgeDesign")); badgeParms.Add("newPublicationDays", Model.Item.GetInt32("NewPublicationDays")); badgeParms.Add("campaignBadgesValues", Model.Item.GetList("CampaignBadges")?.GetRawValue().OfType<string>().ToList()); bool saleBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("SaleBadgeDesign")) && Model.Item.GetRawValueString("SaleBadgeDesign") != "none" ? true : false; bool newBadgeEnabled = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("NewBadgeDesign")) && Model.Item.GetRawValueString("NewBadgeDesign") != "none" ? true : false; DateTime createdDate = product.Created.Value; bool showBadges = saleBadgeEnabled && product.Discount.Price != 0 ? true : false; showBadges = (newBadgeEnabled && Model.Item.GetInt32("NewPublicationDays") == 0) || (newBadgeEnabled && (createdDate.AddDays(Model.Item.GetInt32("NewPublicationDays")) > DateTime.Now)) ? true : showBadges; showBadges = !string.IsNullOrEmpty(Model.Item.GetRawValueString("CampaignBadges")) ? true : showBadges; @* Get assets from selected categories or get all assets *@ if (totalAssets != 0) { int assetNumber = 0; int thumbnailNumber = 0; int modalAssetNumber = 0; string thumbnailAxisCss = GetThumbnailPlacement() == "bottom" ? "flex-column" : string.Empty; <div class="gap-3 h-100 @(theme) item_@Model.Item.SystemName.ToLower()"> <div id="SmallScreenImages_@Model.ID" class="carousel@(GetArrowsColor()) col position-relative" data-bs-ride="carousel"> <div class="carousel-inner h-100"> @foreach (MediaViewModel asset in assetsList) { var assetValue = asset.Value; foreach (string format in allSupportedFormats) { if (assetValue.IndexOf(format, StringComparison.OrdinalIgnoreCase) >= 0) { string activeSlide = assetNumber == 0 ? "active" : ""; <div class="carousel-item @activeSlide" data-bs-interval="99999"> @{ string size = "mobile"; string imageTheme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("ImageTheme")) ? " theme " + Model.Item.GetRawValueString("ImageTheme").Replace(" ", "").Trim().ToLower() : ""; <div class="h-100 @(imageTheme)"> @foreach (string imageFormat in supportedImageFormats) { //Images if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) { if (product is object) { string productName = product.Name; string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; string imageLinkPath = Uri.EscapeDataString(imagePath); RatioSettings ratioSettings = GetRatioSettings(size); var parms = new Dictionary<string, object>(); parms.Add("alt", productName + asset.Keywords); parms.Add("itemprop", "image"); parms.Add("columns", Model.GridRowColumnCount); parms.Add("eagerLoadNewImages", Model.Item.GetBoolean("DisableLazyLoading")); parms.Add("doNotUseGetimage", Model.Item.GetBoolean("DisableGetImage")); if (!string.IsNullOrEmpty(asset.DisplayName)) { parms.Add("title", asset.DisplayName); } if (ratioSettings.Ratio == "fill" && galleryLayout != "grid") { parms.Add("cssClass", "w-100 h-100 image-zoom-lg-l-hover"); } else { parms.Add("cssClass", "mw-100 mh-100"); } <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" data-bs-toggle="modal" data-bs-target="#modal_@Model.ID"> <div class="d-flex align-items-center justify-content-center overflow-hidden h-100" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide-to="@assetNumber"> @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms) </div> </a> } } } @*foreach (string videoFormat in supportedVideoFormats) { //Videos if (assetValue.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) { if (Model.Item.GetString("OpenVideoInModal") == "true") { if (product is object) { string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; string productName = product.Name; productName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? "title=\"" + asset.DisplayName + "\"" : ""; RatioSettings ratioSettings = GetRatioSettings(size); string type = GetVideoType(asset.Value); string videoScreendumpPath = type == "youtube" ? GetYoutubeScreenDump(asset.Value, "maxresdefault") : string.Empty; videoScreendumpPath = type == "selfhosted" ? System.Uri.EscapeUriString(asset.Value) : videoScreendumpPath; string videoJsClass = type == "vimeo" ? "js-vimeo-video-thumbnail" : ""; <div class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable); cursor: pointer" data-bs-toggle="modal" data-bs-target="#modal_@Model.ID"> <div class="d-flex align-items-center justify-content-center overflow-hidden h-100" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide-to="@assetNumber"> <div class="icon-5 position-absolute" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> @if (type != "selfhosted") { <img src="@videoScreendumpPath" loading="lazy" decoding="async" alt="@productName" @assetTitle class="@videoJsClass mw-100 mh-100" data-asset-value="@asset.Value" style="object-fit: cover;"> } else { string videoType = Path.GetExtension(asset.Value).ToLower(); <video preload="auto" class="h-100 w-100" style="object-fit: contain;"> <source src="@(videoScreendumpPath)#t=0.001" type="video/@videoType.Replace(".", "")"> </video> } </div> </div> } } else { if (product is object) { var videoParams = GetVideoParams(asset, size); @RenderPartial("Components/VideoPlayer.cshtml", new FileViewModel { Path = asset.Value}, videoParams); } } } }*@ @*foreach (string documentFormat in supportedDocumentFormats) { //Documents if (assetValue.IndexOf(documentFormat, StringComparison.OrdinalIgnoreCase) >= 0) { if (product is object) { string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; string productName = product.Name; string imagePath = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; string imageLinkPath = Uri.EscapeDataString(imagePath); RatioSettings ratioSettings = GetRatioSettings(size); var parms = new Dictionary<string, object>(); parms.Add("alt", productName + asset.Keywords); parms.Add("itemprop", "image"); parms.Add("fullwidth", true); parms.Add("columns", Model.GridRowColumnCount); if (!string.IsNullOrEmpty(asset.DisplayName)) { parms.Add("title", asset.DisplayName); } if (ratioSettings.Ratio == "fill" && galleryLayout != "grid") { parms.Add("cssClass", "w-100 h-100 image-zoom-lg-l-hover"); } else { parms.Add("cssClass", "mw-100 mh-100"); } <a href="@imageLinkPath" class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)" download alt="@Translate("Download")"> <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <div class="icon-5 position-absolute" style="z-index: 1">@ReadFile(iconPath + "download.svg")</div> @if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) { @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms) } </div> </a> } } }*@ </div> } </div> assetNumber++; } } } </div> @if (product.Prices.Count() > 1 && product.Price.Price == product.PriceBeforeDiscount.Price) { <div class="position-absolute top-0 left-0 p-2 p-lg-3"> <span class="badge badge-no-label sale rounded-0">Kampanje</span> </div> } @if (showBadges) { <div class="position-absolute top-0 left-0 p-2 p-lg-3"> @{@RenderPartial("Components/EcommerceBadge.cshtml", product, badgeParms)} </div> } </div> @if (totalAssets > 1) { <div class="mt-3 swiffy-slider slider-item-show4 slider-nav-dark slider-item-show2-sm slider-item-nosnap-touch slider-nav-outside" id="ThumbnailSlider__@Model.ID"> <ul class="slider-container" id="SmallScreenImagesThumbnails_@Model.ID"> @foreach (MediaViewModel asset in assetsList) { var assetValue = asset.Value; string assetName = asset.Name; assetName += !string.IsNullOrEmpty(asset.Keywords) ? " " + asset.Keywords : ""; string assetTitle = !string.IsNullOrEmpty(asset.DisplayName) ? asset.DisplayName : null; string iconPath = "/Files/Templates/Designs/Swift/Assets/icons/"; string imagePath = Dynamicweb.Context.Current.Server.UrlEncode(assetValue); imagePath = assetValue.IndexOf("youtu.be", StringComparison.OrdinalIgnoreCase) >= 0 || assetValue.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) >= 0 ? "https://img.youtube.com/vi/" + assetValue.Substring(assetValue.LastIndexOf('/') + 1) + "/mqdefault.jpg" : imagePath; string imagePathThumb = assetValue.StartsWith("/Files/", StringComparison.OrdinalIgnoreCase) ? imagePath.IndexOf("youtube", StringComparison.OrdinalIgnoreCase) < 0 && imagePath.IndexOf(".mp4", StringComparison.OrdinalIgnoreCase) < 0 ? $"/Admin/Public/GetImage.ashx?image={imagePath}&width=180&format=webp" : imagePath : assetValue; RatioSettings ratioSettings = GetRatioSettings("desktop"); <li class="border outline-none @(ratioSettings.CssClass)" style="@(ratioSettings.CssVariable); cursor: pointer; min-width: 7rem; max-width: 8rem; min-height: 4rem;" data-bs-target="#SmallScreenImages_@Model.ID" data-bs-slide-to="@thumbnailNumber"> @foreach (string imageFormat in supportedImageFormats) { //Images if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) { <img src="@imagePathThumb" alt="@assetName" @assetTitle class="p-0 p-lg-1 w-100 h-100" style="object-fit: contain;"> thumbnailNumber++; } } @*foreach (string videoFormat in supportedVideoFormats) { //Videos if (assetValue.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) { string type = GetVideoType(asset.Value); string videoScreendumpPath = type == "youtube" ? GetYoutubeScreenDump(asset.Value, "mqdefault") : ""; videoScreendumpPath = type == "vimeo" ? string.Empty : videoScreendumpPath; videoScreendumpPath = type == "selfhosted" ? System.Uri.EscapeUriString(asset.Value) : videoScreendumpPath; string videoJsClass = type == "vimeo" ? "js-vimeo-video-thumbnail" : string.Empty; <div class="icon-5 position-absolute" style="z-index: 1">@ReadFile(iconPath + "play-circle.svg")</div> if (type != "selfhosted") { <img src="@videoScreendumpPath" loading="lazy" decoding="async" alt="@assetTitle" @assetTitle class="@videoJsClass mw-100 mh-100" data-asset-value="@asset.Value" style="object-fit: cover;" /> } else { string videoType = Path.GetExtension(asset.Value).ToLower(); <video preload="auto" class="h-100 w-100" style="object-fit: contain;"> <source src="@(videoScreendumpPath)#t=0.001" type="video/@videoType.Replace(".", "")"> </video> } thumbnailNumber++; } }*@ @*foreach (string documentFormat in supportedDocumentFormats) { //Documents if (assetValue.IndexOf(documentFormat, StringComparison.OrdinalIgnoreCase) >= 0) { <a href="@Uri.EscapeDataString(assetValue)" class="ratio ratio-4x3 border outline-none" style="cursor: pointer; min-width: 7rem; max-width: 8rem;" download title="@asset.Value"> @if (asset.Value.IndexOf(".pdf", StringComparison.OrdinalIgnoreCase) >= 0) { <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <div class="icon-3 position-absolute text-light" style="z-index: 1">@ReadFile(iconPath + "download.svg")</div> </div> <img src="@imagePathThumb" alt="@assetName" @assetTitle class="p-0 p-lg-1 mw-100 mh-100" style="object-fit: cover;"> } else { <div class="d-flex align-items-center justify-content-center overflow-hidden h-100"> <div class="icon-3 position-absolute" style="z-index: 1">@ReadFile(iconPath + "file-text.svg")</div> </div> } </a> thumbnailNumber++; } }*@ </li> } </ul> @if (thumbnailNumber > 4) { <button type="button" title="@Translate("Previous slide")" class="slider-nav" style="z-index:2;"> <span class="visually-hidden">@Translate("Previous slide")</span> </button> <button type="button" title="@Translate("Next slide")" class="slider-nav slider-nav-next" style="z-index:2;"> <span class="visually-hidden">@Translate("Next slide")</span> </button> } </div> <script> (function () { var el = document.querySelector('#ThumbnailSlider__@Model.ID'); function init() { if (typeof window.swiffyslider !== 'undefined' && el && !el.classList.contains('slider-initialized')) { window.swiffyslider.initSlider(el); el.classList.add('slider-initialized'); } } init(); if (typeof window.swiffyslider === 'undefined') { var attempts = 0; var t = setInterval(function () { attempts++; if (typeof window.swiffyslider !== 'undefined') { clearInterval(t); init(); } else if (attempts >= 40) { clearInterval(t); } }, 50); } })(); </script> } </div> @* Modal with slides *@ <div class="modal fade swift_products-details-images-modal" id="modal_@Model.ID" tabindex="-1" aria-labelledby="productDetailsGalleryModalTitle_@Model.ID" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered modal-lg"> <div class="modal-content"> <div class="modal-header visually-hidden"> <h5 class="modal-title" id="productDetailsGalleryModalTitle_@Model.ID">@product.Title</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body p-2 p-lg-3 h-100"> <div id="ModalCarousel_@Model.ID" class="carousel@(GetArrowsColor()) h-100" data-bs-ride="carousel"> <div class="carousel-inner h-100 @theme"> @foreach (MediaViewModel asset in assetsList) { var assetValue = !string.IsNullOrEmpty(asset.Value) ? asset.Value : product.DefaultImage.Value; foreach (string supportedFormat in supportedImageFormats.Concat(supportedVideoFormats).ToArray()) { if (assetValue.IndexOf(supportedFormat, StringComparison.OrdinalIgnoreCase) >= 0) { string imagePath = assetValue; string activeSlide = modalAssetNumber == 0 ? "active" : ""; var parms = new Dictionary<string, object>(); parms.Add("cssClass", "d-block mw-100 mh-100 m-auto"); parms.Add("fullwidth", true); parms.Add("columns", Model.GridRowColumnCount); <div class="carousel-item @activeSlide h-100" data-bs-interval="99999"> @foreach (string imageFormat in supportedImageFormats) { //Images if (assetValue.IndexOf(imageFormat, StringComparison.OrdinalIgnoreCase) >= 0) { @RenderPartial("Components/Image.cshtml", new FileViewModel { Path = imagePath }, parms) } } @foreach (string videoFormat in supportedVideoFormats) { //Videos if (assetValue.IndexOf(videoFormat, StringComparison.OrdinalIgnoreCase) >= 0) { var videoParams = GetVideoParams(asset, "modal"); @RenderPartial("Components/VideoPlayer.cshtml", new FileViewModel { Path = asset.Value }, videoParams) } } </div> modalAssetNumber++; } } } <button class="carousel-control-prev carousel-control-area" type="button" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide="prev"> <span class="carousel-control-prev-icon" aria-hidden="true"></span> <span class="visually-hidden">@Translate("Previous")</span> </button> <button class="carousel-control-next carousel-control-area" type="button" data-bs-target="#ModalCarousel_@Model.ID" data-bs-slide="next"> <span class="carousel-control-next-icon" aria-hidden="true"></span> <span class="visually-hidden">@Translate("Next")</span> </button> </div> </div> </div> </div> </div> </div> } else if (Pageview.IsVisualEditorMode) { RatioSettings ratioSettings = GetRatioSettings("desktop"); <div class="h-100 @theme"> <div class="d-block @(ratioSettings.CssClass)@(ratioSettings.Fill)" style="@(ratioSettings.CssVariable)"> <img src="/Files/Images/missing_image.jpg" loading="lazy" decoding="async" class="mh-100 mw-100" style="object-fit: cover;"> </div> </div> } } else if (Pageview.IsVisualEditorMode) { <div class="alert alert-dark m-0">@Translate("No products available")</div> }
Termokamera 640x480
ELIT H6-DUAL APEX 25°+15°- Varenummer:
- 10330064
- EAN:
- 7070810040087
- Termografikamera med dobbel FOV linse for effektivt skifte mellom standard 25° og zoom 15°
-
- Autofokus og manuelt fokus for maksimal kontroll.
- IR og digitalbildet som kan blandes for god visuell indikering.
- Lagre video med 50Hz bildefrekvens.
Error executing template "/Designs/Swift/Paragraph/Swift_ProductPrice_Mennt.cshtml" System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (258): The wait operation timed out. at System.Data.SqlClient.SqlConnection.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.ProductRepository.GetProductKeysByGroupId(String groupId, Boolean useOrderBy, Boolean includeVariants, String productLanguageId, Boolean doRefactoring, Boolean useAssortments) at Dynamicweb.Ecommerce.Orders.Discounts.Discount.ProcessProductSelections(HashSet`1& productKeys, HashSet`1& includedQueries, HashSet`1& excludedQueries) at Dynamicweb.Ecommerce.Orders.Discounts.Discount.GetRelevantProductKeys() at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.StatelessSetLookup(Discount discount, ConcurrentDictionary`2 lookup) at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.InitializeLookup() at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode) --- End of stack trace from previous location --- at System.Lazy`1.CreateValue() at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.GetDiscounts(DiscountApplyType[] discountTypes, String[] productKeys, User user) at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetDiscountInfo(PriceViewModelSettings settings, Product product) 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__DisplayClass15_2.<BulkCreateView>b__47() 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__DisplayClass15_2.<BulkCreateView>b__49() 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.GetPrice(PriceViewModelSettings settings, IList`1 products, Boolean& pricesHasBeenPrepared, Object lock, Lazy`1 priceInfo) at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass15_2.<BulkCreateView>b__50() at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode) --- End of stack trace from previous location --- at System.Lazy`1.CreateValue() at CompiledRazorTemplates.Dynamic.RazorEngine_0cae5015605449808b28bc1577aea43b.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:e364817e-2466-4e75-8884-af68bd8aab58 Error Number:−2,State:0,Class:11
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 isCampaign = product is object && product.Price.Price != product.PriceBeforeDiscount.Price; 27 bool hidePriceCustom = hidePrice && !isCampaign; 28 29 bool productIsDiscontinued = product is object && product.Discontinued; 30 bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); 31 var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; 32 } 33 34 @if (product is object && !hidePriceCustom && !productIsDiscontinued) { 35 bool showInformativePrice = Model.Item.GetBoolean("ShowInformativePrice"); 36 string unitId = !string.IsNullOrEmpty(Dynamicweb.Context.Current.Request.Form.Get("UnitId")) ? Dynamicweb.Context.Current.Request.Form.Get("UnitId") : string.Empty; 37 38 string priceFontSize = Model.Item.GetRawValueString("PriceSize", "fs-2"); 39 string horizontalAlign = Model.Item.GetRawValueString("HorizontalAlignment", ""); 40 string layout = Model.Item.GetRawValueString("Layout", "horizontal"); 41 string textAlign = horizontalAlign == "center" ? "text-center" : string.Empty; 42 textAlign = horizontalAlign == "end" ? "text-end" : textAlign; 43 44 horizontalAlign = horizontalAlign == "center" && layout == "horizontal" ? "justify-content-center" : horizontalAlign; 45 horizontalAlign = horizontalAlign == "end" && layout == "horizontal" ? "justify-content-end" : horizontalAlign; 46 horizontalAlign = horizontalAlign == "center" && layout == "vertical" ? "align-items-center" : horizontalAlign; 47 horizontalAlign = horizontalAlign == "end" && layout == "vertical" ? "align-items-end" : horizontalAlign; 48 49 string flexDirection = layout == "horizontal" ? string.Empty : "flex-column"; 50 string flexGap = layout == "horizontal" ? "gap-3" : string.Empty; 51 string order = layout == "horizontal" ? string.Empty : "order-2"; 52 string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? "theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : ""; 53 theme = GetViewParameter("theme") != null ? GetViewParameterString("theme") : theme; 54 55 string contentPadding = Model.Item.GetRawValueString("ContentPadding", ""); 56 contentPadding = contentPadding == "none" ? "p-0" : contentPadding; 57 contentPadding = contentPadding == "small" ? "p-1 px-md-2 py-md-1" : contentPadding; 58 contentPadding = contentPadding == "large" ? "p-2 px-md-3 py-md-2" : contentPadding; 59 60 string showPricesWithVat = Pageview.Area.EcomPricesWithVat.ToLower(); 61 bool neverShowVat = string.IsNullOrEmpty(showPricesWithVat); 62 63 string priceMin = ""; 64 string priceMax = ""; 65 66 string liveInfoClass = ""; 67 string productInfoFeed = ""; 68 bool isLazyLoadingForProductInfoEnabled = Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsLazyLoadingForProductInfoEnabled"]); 69 if (isLazyLoadingForProductInfoEnabled) 70 { 71 if (Dynamicweb.Context.Current.Items.Contains("ProductInfoFeed")) 72 { 73 productInfoFeed = Dynamicweb.Context.Current.Items["ProductInfoFeed"]?.ToString(); 74 if (!string.IsNullOrEmpty(productInfoFeed)) 75 { 76 productInfoFeed = $"data-product-info-feed=\"{productInfoFeed}\""; 77 } 78 } 79 liveInfoClass = "js-live-info"; 80 } 81 82 83 84 // Velg tallverdi basert på om prisene vises med eller uten mva 85 decimal CurrentNumeric = product.Price.ShowPricesWithVat 86 ? (decimal)product.Price.PriceWithVat 87 : (decimal)product.Price.Price; 88 89 var maxPriceItem = product.Prices 90 .OrderByDescending(p => p.Price.ShowPricesWithVat ? (decimal)p.Price.PriceWithVat : (decimal)p.Price.Price) 91 .FirstOrDefault(); 92 93 // Høyeste pris som tall 94 decimal MaxNumeric = maxPriceItem != null 95 ? (maxPriceItem.Price.ShowPricesWithVat ? (decimal)maxPriceItem.Price.PriceWithVat : (decimal)maxPriceItem.Price.Price) 96 : 0; 97 98 <div class="@textAlign @liveInfoClass item_@Model.Item.SystemName.ToLower()" data-product-id="@product.Id" data-variant-id="@product.VariantId" @productInfoFeed> 99 @if (showInformativePrice && product.PriceInformative.Price != 0) 100 { 101 <div class="opacity-50"> 102 <span>@Translate("RRP") </span> 103 <span class="text-decoration-line-through text-price">@product.PriceInformative.PriceFormatted</span> 104 </div> 105 } 106 <div class="@priceFontSize m-0 fw-bold d-flex flex-wrap @flexDirection @flexGap @horizontalAlign" style="row-gap: 0 !important" itemprop="offers" itemscope itemtype="https://schema.org/Offer"> 107 <span itemprop="priceCurrency" content="@product.Price.CurrencyCode" class="d-none"></span> 108 109 110 @if (showPricesWithVat == "false" && !neverShowVat) 111 { 112 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 113 { 114 <span itemprop="price" content="" class="d-none"></span> 115 <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> 116 } 117 else 118 { 119 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceWithoutVatFormatted : product.PriceBeforeDiscount.PriceWithoutVatFormatted; 120 121 <span itemprop="price" content="@product.Price.PriceWithoutVat.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 122 if (product.Price.Price != product.PriceBeforeDiscount.Price) 123 { 124 <span class="text-decoration-line-through opacity-75 @order">@beforePrice </span> 125 } 126 127 @if (product.Prices.Count() > 1 128 && product.Price.Price == product.PriceBeforeDiscount.Price 129 && maxPriceItem != null 130 && MaxNumeric > CurrentNumeric) 131 { 132 <span class="text-decoration-line-through opacity-75 @order"> 133 @maxPriceItem.Price.PriceFormatted 134 </span> 135 } 136 } 137 } 138 else 139 { 140 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 141 { 142 <span itemprop="price" content="" class="d-none"></span> 143 <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> 144 } 145 else 146 { 147 string beforePrice = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).PriceBeforeDiscount.PriceFormatted : product.PriceBeforeDiscount.PriceFormatted; 148 149 <span itemprop="price" content="@product.Price.Price.ToString("0.00", System.Globalization.CultureInfo.InvariantCulture)" class="d-none"></span> 150 151 if (product.Price.Price != product.PriceBeforeDiscount.Price) 152 { 153 <span class="text-decoration-line-through opacity-75 @order"> 154 <span class="text-price">@beforePrice</span> 155 </span> 156 } 157 } 158 159 160 } 161 162 @if (showPricesWithVat == "false" && !neverShowVat) 163 { 164 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 165 { 166 <span class="text-price js-text-price"> 167 <span class="spinner-border" role="status"></span> 168 </span> 169 } 170 else 171 { 172 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithoutVatFormatted : product.Price.PriceWithoutVatFormatted; 173 174 if (product?.VariantInfo?.VariantInfo != null) 175 { 176 priceMin = product?.VariantInfo?.PriceMin?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithoutVatFormatted : ""; 177 priceMax = product?.VariantInfo?.PriceMax?.PriceWithoutVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithoutVatFormatted : ""; 178 } 179 if (priceMin != priceMax) 180 { 181 price = priceMin + " - " + priceMax; 182 } 183 <div class="d-none"><pre>Product:<code class="language-json">@System.Text.Json.JsonSerializer.Serialize(product)</code></pre></div> 184 185 @if (price == "kr 0,00") 186 { 187 <span class="@theme @contentPadding"> 188 <span class="d-flex align-items-baseline text-price">@Translate("Ring for pris")</span> 189 </span> 190 } 191 else 192 { 193 <span class="@theme @contentPadding w-100"> 194 <span class="d-flex align-items-baseline text-price">@price <span class="fs-7 fw-normal ms-1"> pr. @product.DefaultUnitId.Replace("METER","meter").Replace("STK","stk.").Replace("SET","sett")</span><span class="fs-7 fw-normal">(@Translate("VAT Excl."))</span></span> 195 </span> 196 } 197 } 198 } 199 else 200 { 201 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 202 { 203 <span class="text-price js-text-price"> 204 <span class="spinner-border" role="status"></span> 205 </span> 206 } 207 else 208 { 209 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceFormatted : product.Price.PriceFormatted; 210 211 if (product?.VariantInfo?.VariantInfo != null) 212 { 213 priceMin = product?.VariantInfo?.PriceMin?.PriceFormatted != null ? product.VariantInfo.PriceMin.PriceFormatted : ""; 214 priceMax = product?.VariantInfo?.PriceMax?.PriceFormatted != null ? product.VariantInfo.PriceMax.PriceFormatted : ""; 215 } 216 if (priceMin != priceMax) 217 { 218 price = priceMin + " - " + priceMax; 219 } 220 <span class="@theme @contentPadding"> 221 <span class="text-price">@price</span> 222 </span> 223 } 224 } 225 226 @* Stock state for Schema.org, start *@ 227 @{ 228 Uri url = Dynamicweb.Context.Current.Request.Url; 229 } 230 231 <link itemprop="url" href="@url"> 232 233 @{ 234 bool IsNeverOutOfStock = product.NeverOutOfstock; 235 } 236 237 @if (IsNeverOutOfStock) 238 { 239 <span itemprop="availability" class="d-none">@Translate("Available in stock")</span> 240 } 241 else 242 { 243 if (product.StockLevel > 0) 244 { 245 <span itemprop="availability" class="d-none">InStock</span> 246 } 247 else 248 { 249 <span itemprop="availability" class="d-none">OutOfStock</span> 250 } 251 } 252 @* Stock state for Schema.org, stop *@ 253 254 </div> 255 256 @*if (showPricesWithVat == "false" && !neverShowVat) 257 { 258 if (isLazyLoadingForProductInfoEnabled && !Pageview.IsVisualEditorMode) 259 { 260 <small class="opacity-85 fst-normal js-text-price-with-vat d-none test1" data-suffix="@Translate("Incl. VAT")"></small> 261 } 262 else 263 { 264 string price = !string.IsNullOrEmpty(unitId) ? product.GetPrice(unitId).Price.PriceWithVatFormatted : product.Price.PriceWithVatFormatted; 265 266 if (product?.VariantInfo?.VariantInfo != null) 267 { 268 priceMin = product?.VariantInfo?.PriceMin?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMin.PriceWithVatFormatted : ""; 269 priceMax = product?.VariantInfo?.PriceMax?.PriceWithVatFormatted != null ? product.VariantInfo.PriceMax.PriceWithVatFormatted : ""; 270 } 271 if (priceMin != priceMax) 272 { 273 price = priceMin + " - " + priceMax; 274 } 275 <small class="opacity-85 fst-normal">@price @Translate("Incl. VAT")</small> 276 } 277 }*@ 278 </div> 279 } 280 else if (Pageview.IsVisualEditorMode) 281 { 282 <div class="alert alert-dark m-0" role="alert"> 283 <span>@Translate("No products available")</span> 284 </div> 285 } 286
Error executing template "/Designs/Swift/Paragraph/Swift_Feature_Mennt_ProductDetailPage.cshtml" System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (258): The wait operation timed out. at System.Data.SqlClient.SqlConnection.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.ProductRepository.GetProductKeysByGroupId(String groupId, Boolean useOrderBy, Boolean includeVariants, String productLanguageId, Boolean doRefactoring, Boolean useAssortments) at Dynamicweb.Ecommerce.Orders.Discounts.Discount.ProcessProductSelections(HashSet`1& productKeys, HashSet`1& includedQueries, HashSet`1& excludedQueries) at Dynamicweb.Ecommerce.Orders.Discounts.Discount.GetRelevantProductKeys() at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.StatelessSetLookup(Discount discount, ConcurrentDictionary`2 lookup) at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.InitializeLookup() at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode) --- End of stack trace from previous location --- at System.Lazy`1.CreateValue() at Dynamicweb.Ecommerce.Orders.Discounts.DiscountService.GetDiscounts(DiscountApplyType[] discountTypes, String[] productKeys, User user) at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.GetDiscountInfo(PriceViewModelSettings settings, Product product) 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__DisplayClass15_2.<BulkCreateView>b__47() 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__DisplayClass15_2.<BulkCreateView>b__49() 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.GetPrice(PriceViewModelSettings settings, IList`1 products, Boolean& pricesHasBeenPrepared, Object lock, Lazy`1 priceInfo) at Dynamicweb.Ecommerce.ProductCatalog.ViewEngine.<>c__DisplayClass15_2.<BulkCreateView>b__50() at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode) --- End of stack trace from previous location --- at System.Lazy`1.CreateValue() at CompiledRazorTemplates.Dynamic.RazorEngine_5b8465ca8f214bf4b363054b0ae68219.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:e364817e-2466-4e75-8884-af68bd8aab58 Error Number:−2,State:0,Class:11
1 @inherits Dynamicweb.Rendering.ViewModelTemplate<Dynamicweb.Frontend.ParagraphViewModel> @using System.IO @using Dynamicweb.Ecommerce.ProductCatalog @functions { private string RenderCustomCSS(IEnumerable<string> decorations) { var cssClasses = new List<string>(); foreach (var itemId in decorations) { var item = Dynamicweb.Content.Services.Items.GetItem("Swift_Css", itemId); item.TryGetValue("Class", out object classes); if (classes is null) { continue; } var cssString = (string)classes; if (cssString.StartsWith("[")) { var cssArray = Dynamicweb.Core.Converter.Deserialize<string[]>(cssString); cssClasses.AddRange(cssArray); } else { cssClasses.Add(cssString.Replace(",", " ")); } } return string.Join(" ", cssClasses).Trim(); } } @{ ProductViewModel product = null; if (Dynamicweb.Context.Current.Items.Contains("ProductDetails")) { product = (ProductViewModel)Dynamicweb.Context.Current.Items["ProductDetails"]; } else if (Pageview.Page.Item["DummyProduct"] != null && Pageview.IsVisualEditorMode) { var pageViewModel = Dynamicweb.Frontend.ContentViewModelFactory.CreatePageInfoViewModel(Pageview.Page); ProductListViewModel productList = pageViewModel.Item.GetValue("DummyProduct") != null ? pageViewModel.Item.GetValue("DummyProduct") as ProductListViewModel : new ProductListViewModel(); if (productList?.Products is object) { product = productList.Products[0]; } } string anonymousUsersLimitations = Pageview.AreaSettings.GetRawValueString("AnonymousUsers", ""); bool anonymousUser = Pageview.User == null; bool isErpConnectionDown = !Dynamicweb.Core.Converter.ToBoolean(Dynamicweb.Context.Current.Items["IsWebServiceConnectionAvailable"]); bool hidePrice = anonymousUsersLimitations.Contains("price") && anonymousUser || Pageview.AreaSettings.GetBoolean("ErpDownHidePrices") && isErpConnectionDown; bool isCampaign = product is object && product.Price.Price != product.PriceBeforeDiscount.Price; bool hidePriceCustom = hidePrice && !isCampaign; bool productIsDiscontinued = product is object && product.Discontinued; bool doNotShowPriceIfProductIsDiscontinued = Model.Item.GetBoolean("DoNotShowPriceIfProductIsDiscontinued"); var isDiscontinued = productIsDiscontinued && doNotShowPriceIfProductIsDiscontinued; string layout = Model.Item.GetRawValueString("Layout", "icon-top"); string contentPadding = Model.Item.GetRawValueString("ContentPadding", string.Empty); contentPadding = contentPadding == "none" ? "" : contentPadding; contentPadding = contentPadding == "small" ? "p-3 p-md-3" : contentPadding; contentPadding = contentPadding == "large" ? "p-5 p-md-5" : contentPadding; string theme = !string.IsNullOrWhiteSpace(Model.Item.GetRawValueString("Theme")) ? " theme " + Model.Item.GetRawValueString("Theme").Replace(" ", "").Trim().ToLower() : string.Empty; var decorations = Model.Item?.GetList("CssDecorations")?.GetRawValue().OfType<string>() ?? Enumerable.Empty<string>(); string css = RenderCustomCSS(decorations); string target = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && Model.Item.GetString("Link").Contains("http") ? "target=\"_blank\"" : string.Empty; string rel = Pageview.AreaSettings.GetBoolean("OpenLinksInNewTab") && Model.Item.GetString("Link").Contains("http") ? "rel=\"noopener\"" : string.Empty; string alignment = (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle")) && !string.IsNullOrEmpty(Model.Item.GetString("Text")) ? "align-items-stretch" : "align-items-center"; string iconColor = Model.Item.GetString("iconColor", "text-inherit"); string iconOpacity = Model.Item.GetString("IconOpacity", "opacity-100"); string iconSize = Model.Item.GetRawValueString("IconSize", "2"); string imageSrc = !string.IsNullOrEmpty(Model.Item.GetString("Image")) ? Model.Item.GetFile("Image").Path : string.Empty; string flexGrowClass = string.Empty; switch (layout) { case "icon-left": case "icon-right": flexGrowClass = "flex-grow-0"; break; } string imagePath = imageSrc != string.Empty ? imageSrc : Model.Item.GetRawValueString("Icon", string.Empty); imagePath = Path.GetExtension(imagePath).ToLower() != ".svg" ? "/Admin/Public/GetImage.ashx?image=" + imagePath + "&height=" + iconSize + "&width=" + iconSize + "&Crop=0&format=webp" : imagePath; string imgAltText = Model.Item.GetRawValueString("FeatureAltText", string.Empty); string titleFontSize = Model.Item.GetRawValueString("TitleFontSize", "h4"); string titleColor = Model.Item.GetString("TitleColor", "text-inherit"); string titleOpacity = Model.Item.GetString("TitleOpacity", "opacity-100"); string headingLevel = Model.Item.GetString("HeadingLevel", "h2"); string headingLevelStart = $"<{headingLevel} class=\"{titleFontSize} {titleColor} {titleOpacity} m-0\">"; string headingLevelStop = $"</{headingLevel}>"; string textColor = Model.Item.GetString("TextColor", "text-inherit"); string textOpacity = Model.Item.GetString("TextOpacity", "opacity-100"); } @if (product is object && hidePriceCustom && !productIsDiscontinued) { <div class="h-100 @(contentPadding)@(theme) @(css) item_@Model.Item.SystemName.ToLower()"> <div id="@Model.ID" class="user-select-none" style="scroll-margin-top:var(--header-height,150px)"></div> @if (!string.IsNullOrEmpty(Model.Item.GetString("Link"))) { @:<a href="@Model.Item.GetString("Link")" class="text-decoration-none d-block h-100" @target @rel> } @switch (layout) { case "icon-top": <div class="d-flex flex-column gap-3 text-center mb-0-last-child"> @if (!string.IsNullOrEmpty(Model.Item.GetString("Image")) || !imagePath.ToLower().Contains("none") && imagePath != string.Empty) {<div class="@flexGrowClass"> @if (Path.GetExtension(imagePath).ToLower() == ".svg") { <div class="icon-auto @iconColor @iconOpacity" style="height: @(iconSize)px; width: @(iconSize)px;">@ReadFile(imagePath)</div> } else { <img loading="lazy" src="@imagePath" alt="@imgAltText" title="@Model.Item.GetString("Title")" style="height: @(iconSize)px; width: @(iconSize)px;"> } </div> } @if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle") || !string.IsNullOrEmpty(Model.Item.GetString("Text"))) { <div class="mb-0-last-child"> @if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle")) { @headingLevelStart @Model.Item.GetString("Title") @headingLevelStop } @if (!string.IsNullOrEmpty(Model.Item.GetString("Text"))) { <p class="@textColor @textOpacity m-0">@Model.Item.GetString("Text")</p> } </div> } </div> break; case "icon-left": <div class="d-flex flex-row gap-3 h-100 text-start @alignment"> @if (!string.IsNullOrEmpty(Model.Item.GetString("Image")) || !imagePath.ToLower().Contains("none") && imagePath != string.Empty) {<div class="@flexGrowClass"> @if (Path.GetExtension(imagePath).ToLower() == ".svg") { <div class="icon-auto @iconColor @iconOpacity" style="height: @(iconSize)px; width: @(iconSize)px;">@ReadFile(imagePath)</div> } else { <img loading="lazy" src="@imagePath" alt="@imgAltText" title="@Model.Item.GetString("Title")" style="height: @(iconSize)px; width: @(iconSize)px;"> } </div> } @if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle") || !string.IsNullOrEmpty(Model.Item.GetString("Text"))) { <div class="d-flex flex-column flex-grow-1"> @if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle")) { @headingLevelStart @Model.Item.GetString("Title") @headingLevelStop } @if (!string.IsNullOrEmpty(Model.Item.GetString("Text"))) { <p class="@textColor @textOpacity mt-2">@Model.Item.GetString("Text")</p> } </div> } </div> break; case "icon-right": <div class="d-flex flex-row gap-3 h-100 text-end @alignment"> @if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle") || !string.IsNullOrEmpty(Model.Item.GetString("Text"))) { <div class="d-flex flex-column flex-grow-1"> @if (!string.IsNullOrEmpty(Model.Item.GetString("Title")) && !Model.Item.GetBoolean("HideTitle")) { @headingLevelStart @Model.Item.GetString("Title") @headingLevelStop } @if (!string.IsNullOrEmpty(Model.Item.GetString("Text"))) { <p class="@textColor @textOpacity m-0">@Model.Item.GetString("Text")</p> } </div> } @if (!string.IsNullOrEmpty(Model.Item.GetString("Image")) || !imagePath.ToLower().Contains("none") && imagePath != string.Empty) {<div class="@flexGrowClass"> @if (Path.GetExtension(imagePath).ToLower() == ".svg") { <div class="icon-auto @iconColor @iconOpacity" style="height: @(iconSize)px; width: @(iconSize)px;">@ReadFile(imagePath)</div> } else { <img loading="lazy" src="@imagePath" alt="@imgAltText" title="@Model.Item.GetString("Title")" style="height: @(iconSize)px; width: @(iconSize)px;"> } </div> } </div> break; } @if (!string.IsNullOrEmpty(Model.Item.GetString("Link"))) { @:</a> } </div> }
ELIT H6-DUAL 25°+15° er et oppgradert kamera med dobbel linse som lar bruker raskt og effektivt skifte mellom standard og zoom for å få et bedre bilde av objekter på stor avstand. Markedsledende høy følsomhet på 15mK, et ekstra oppgradert 13 MP digitalkamera for synlig lys og SuperPixel funksjon som gir 4x så høy oppløsning på bildet. Bildet på skjermen kan vises i fire forskjellige modus: Kun IR, kun digitalbilde, IR og digitalbilde blandet(Fusion) eller IR bildet inne i digitalbilder(PiP). Dette høypresisjons termiske kameraet er designet spesielt for industri, elektro og internkontroll. Brukere kan intuitivt se høyoppløselige bilder og temperaturdetaljer på den 4,3" store berøringsskjermen. 50Hz infrarød bildefrekvens for rask og nøyaktig tilgang til flere temperaturdata på bevegelige mål. Ergonomisk designet med 2m falltest og IP54 støv- og sprutsikker instrumentkasse. Det er mulig å legge til 16 forskjellige målepunkter, målelinjer og målearealer direkte på skjermen med maksimum og minimumsverdier. Egen funksjon for panoramabilder, flere bilder settes automatisk sammen for f.eks. å dekke en hel fasade.
Termokamera med overlegende fokusmuligheter: Autofokus på senterpunkt med avtrekkerknapp. Autofokus på punkt i bildet ved å trykke på skjermen. Kontinuerlig autofokus for å følge bevegelig objekter. Manuelt fokus ved å vri på ringen på linsen.
Utskiftbare linser kan kjøpes separat ved behov og enkelt byttes av bruker. Både vidvinkel(45°) og ultrazoom(7°) er tilgjengelig. Samt DUAL 25°+45° om man ønsker å raskt skifte mellom standard og vidvinkel.
Samt linse for høye temperaturer(2000°C) kan legges til ved kjøp.
Programvare for analyse, app og skytjeneste for deling er inkludert.
Tekniske data:
Oppløsning: 640x480, 307000 piksler
Skjerm: 800x480, 4,3" touch
Tetthet: IP54
Brukstid: 4 timer
Synsvinkel: 25°
Temperatuområde: -40°C til 650°C
Nøyaktighet: ±2°C / ±2%
Vekt: 1150g
Utstyr som følger med som standard:
Støtsikker koffert, bærestropp 2stk, USB kabel, dobbel lader, batteri 2 stk, minnekort, strømforsyning og linsedeksel.