Exception in template (Designs\Dwsimple\eCom/Productlist/ProductList.cshtml): System.InvalidCastException: Unable to cast object of type 'System.DBNull' to type 'System.String'.
   at CompiledRazorTemplates.Dynamic.cbefefbfaefbdc.<>c__DisplayClassb.b__3(TextWriter __razor_helper_writer)
   at RazorEngine.Templating.TemplateWriter.WriteTo(TextWriter writer)
   at RazorEngine.Templating.TemplateBase.Write(TemplateWriter helper)
   at CompiledRazorTemplates.Dynamic.cbefefbfaefbdc.Execute()
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context)
   at RazorEngine.Templating.TemplateService.Run(ITemplate template, DynamicViewBag viewBag)
   at RazorEngine.Templating.TemplateService.Parse(String razorTemplate, Object model, DynamicViewBag viewBag, String cacheName)
   at RazorEngine.Razor.Parse[T](String razorTemplate, T model, DynamicViewBag viewBag, String cacheName)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()
@using Dynamicweb.Ecommerce.Products; @using System.Text.RegularExpressions @using System.Web @functions{ public class WrapMethods { //Gets the contrasting color public static string getContrastYIQ(string hexcolor) { if (hexcolor != "") { hexcolor = Regex.Replace(hexcolor, "[^0-9a-zA-Z]+", ""); int r = Convert.ToByte(hexcolor.Substring(0, 2), 16); int g = Convert.ToByte(hexcolor.Substring(2, 2), 16); int b = Convert.ToByte(hexcolor.Substring(4, 2), 16); int yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000; if (yiq >= 128) { return "black"; } else { return "white"; } } else { return "black"; } } //Truncate text public static string Truncate (string value, int count, bool strip=true) { if (strip == true){ value = StripHtmlTagByCharArray(value); } if (value.Length > count) { value = value.Substring(0, count - 1) + "..."; } return value; } //Strip text from HTML public static string StripHtmlTagByCharArray(string htmlString) { char[] array = new char[htmlString.Length]; int arrayIndex = 0; bool inside = false; for (int i = 0; i < htmlString.Length; i++) { char let = htmlString[i]; if (let == '<') { inside = true; continue; } if (let == '>') { inside = false; continue; } if (!inside) { array[arrayIndex] = let; arrayIndex++; } } return new string(array, 0, arrayIndex); } //Make the correct count of columns public static string ColumnMaker(int Col, string ScreenSize) { string Columns = ""; switch (Col) { case 1: Columns = "col-"+ScreenSize+"-12"; break; case 2: Columns = "col-"+ScreenSize+"-6"; break; case 3: Columns = "col-"+ScreenSize+"-4"; break; case 4: Columns = "col-"+ScreenSize+"-3"; break; default: Columns = "col-"+ScreenSize+"-3"; break; } return Columns; } private string Custom(string firstoption, string secondoption) { if (firstoption == "custom") { return secondoption; } else { return firstoption; } } } } @helper GetProductList(dynamic Loop, int ColMD=3, int ColSM=3, int ColXS=1) { int Count = 0; string ColumnsMD = WrapMethods.ColumnMaker(ColMD, "md"); string ColumnsSM = WrapMethods.ColumnMaker(ColSM, "sm"); string ColumnsXS = WrapMethods.ColumnMaker(ColXS, "xs"); <!--ProductListRender.cshtml--> foreach (LoopItem product in Loop) { string Image = product.GetString("Ecom:Product.ImageSmall.Clean"); string GroupLink = product.GetString("Ecom:Product.LinkGroup.Clean"); string Name = WrapMethods.Truncate(product.GetString("Ecom:Product.Name"), 50); // WrapMethods.Truncate(product.GetString("Ecom:Product.Name"), 200) string Description = product.GetString("Ecom:Product.ShortDescription"); string Discount = product.GetString("Ecom:Product.Discount.Price.PriceFormatted"); string Price = product.GetString("Ecom:Product.Price"); string Currency = product.GetString("Ecom:Product.Price.Currency.Code"); string pageid = product.GetString("Ecom:Product.PrimaryOrCurrentPageID"); string groupid = product.GetString("Ecom:Group.ID"); string productid = product.GetString("Ecom:Product.ID"); string primaryid = product.GetString("Ecom:Product.PrimaryGroupID"); string primaryfirstid = product.GetString("Ecom:Product.PrimaryOrFirstGroupID"); bool SLPreventWebSale=product.GetBoolean("Ecom:Product:Field.SLPreventWebSale"); string RelatedFastners = product.GetString("Ecom:Product:Field.RelatedFasteners"); string FastnersPerPart = product.GetString("Ecom:Product:Field.FastenersPerPart"); IEnumerable<string[]> arrRelatedFasteners = RelatedFastners.Split(',').Select(sa => sa.Split('.')); ILookup<string[], uint> arrFastenersPerPart = FastnersPerPart.Split(',').Select(sa => sa.Split('.')).Select((str, idx) => new { str, idx }).ToLookup(x => x.str, x => (uint)x.idx); string formFields = product.GetString("Ecom:Product.Form.Clean"); <div class="@ColumnsMD @ColumnsSM @ColumnsXS" name="productlist"> <div class="wp-block product" name="boxproduct"> <div class="" name="listproductright"> <a href="@GroupLink" title="@Name"> <figure style="" name="productfigure"> @if(Image.Length > 28) { <img alt="@Name" src="/Admin/Public/Getimage.ashx?width=300&height=300&compression=85&Crop=5&image=@Image" class="img-responsive img-center"> } else { <img alt="@Name" src="/Admin/Public/Getimage.ashx?width=300&height=300&compression=85&Crop=5&image=/Files/Images/Ecom/missing_image.gif" class="img-responsive img-center"> } </figure> </a> </div> <div class="" name="extracolumn"> <h2 class="product-title"><a href="@GroupLink">@Name</a></h2> <div style="" name="shortproductdescription"> <p>@WrapMethods.Truncate(product.GetString("Ecom:Product.ShortDescription"), 200)</p> </div> <div style="display: none !important" name="longproductdescription"> <p class="pull-left" style="text-align: left !important">@WrapMethods.Truncate(product.GetString("Ecom:Product.ShortDescription"), 200)</p> </div> <p><b>@Translate("Product number", "Product number"):</b> <span property="identifier">@productid</span></p> <!--<p>ProductListRender.cshtml</p>--> <div style="" name="productassociatedgroups"> @*@if(Ecom:Group:Field.ToFitGroup=True) { <p>This Group is 'To Fit Group'</p> <p>Groups here - GetValue("Ecom:Group:Field.ToFitGroup")</p> }*@ </div> <!--@foreach (LoopItem i in GetLoop("AssociatedGroups")) { <div style="" name="productasscociatedgroups"> <p class="pull-left" style="text-align: left !important">@Description</p> </div> }--> </div> <div class="wp-block-footer" name="listproductleft"> <form name="@productid" id="@productid" method="post" action="/Default.aspx"> @formFields @*<p>View Related fasteners @RelatedFastners</p> <p>View Fasteners per part @FastnersPerPart</p>*@ @if (Dynamicweb.Input.FormatBoolean(GetGlobalValue("Global:Extranet.UserName")) || product.GetBoolean("Ecom:Product:Field.SLGuestPricing")) { if (Discount != Price) { <span class="price with-discount pull-left" style="font-size: 16px !important" name="productprice"><strong>@Discount</strong> <i class="ex-vat">(ex. VAT)</i></span> <span name="productpricebr"></span> <p class="price discount" name="productoldprice">Was: <i>@Price</i></p> if(!@SLPreventWebSale) { <button type="submit" name="submit" onclick="UpdateCart();" class="btn btn-dw-cart pull-right"><strong>@Translate("Add", "Add")</strong></button> <input type="number" min="1" name="Quantity" value="1" class="pull-right" style="width:40px; text-align:center; margin-right:15px !important; height:24px;"> <span>&nbsp;&nbsp;</span> } else { <div class="collection out-stock"> <p><span>Please Call</span></p> </div> } } else { if (Dynamicweb.Input.FormatBoolean(GetGlobalValue("Global:Extranet.UserName")) || product.GetBoolean("Ecom:Product:Field.SLGuestPricing")) { <span class="price pull-left" style="font-size: 16px !important" name="productprice"><strong>@Price <i class="ex-vat">(ex. VAT)</i></strong></span> if(!@SLPreventWebSale) { <button type="submit" name="submit" onclick="UpdateCart();" class="btn btn-dw-cart pull-right"><strong>@Translate("Add", "Add")</strong></button> <input type="number" min="1" name="Quantity" value="1" class="pull-right" style="width:40px; text-align:center; margin-right:15px !important; height:24px;"> <span>&nbsp;&nbsp;</span> } else { <div class="collection out-stock"> <p><span>Please Call</span></p> </div> } } } } else { <p>Please <a href="#" data-toggle="modal" data-target="#login" class="dw-login">login</a> to see product pricing and to buy online! 1</p> } </form> @*<div class="pull-right" name="productmorebr"> <a href="@GroupLink" class="btn btn-sm btn-dw-primary"><span>@Translate("Read more", "Read more")</span></a> </div>*@ </div> @if (Discount != Price) { <span class="ribbon base">@Translate("Special Offer!", "Special Offer!")</span> } <!--@product.GetString("Ecom:Product:Field.RelatedFasteners"); --> @if (!string.IsNullOrWhiteSpace(FastnersPerPart) && arrRelatedFasteners.Count() > 1) { <div class="fastners"> <a href="#" data-toggle="modal" data-target="#Fastners_@productid"><p>View related fasteners</p><img src="/Files/Images/icon-plus.png"></a> </div> <div class="modal fade" id="Fastners_@productid" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog modal-sm"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> <h4 class="modal-title" id="myModalLabel">Fasteners for @Name</h4> </div> @foreach(var fastener in arrRelatedFasteners.ToArray()) { if(fastener.Count() > 1){ string grpId = fastener[0]; string prodId = fastener[1]; string groupName = string.Empty; string productId = string.Empty; string price = string.Empty; string partsToFit = string.Empty; string partToFitName = string.Empty; string pkQuantity = string.Empty; Dynamicweb.Ecommerce.Products.Group group = Dynamicweb.Ecommerce.Services.ProductGroups.GetGroup(grpId); if (group !=null) { Product fastnerProduct = Dynamicweb.Ecommerce.Services.Products.GetProductById(prodId, string.Empty, true); if (fastnerProduct != null) { groupName = group.Name; productId = fastnerProduct.Id; price = fastnerProduct.Price.PriceWithoutVATFormatted; partToFitName = fastnerProduct.Name; pkQuantity = (string)Dynamicweb.Ecommerce.Services.Products.GetProductFieldValue(fastnerProduct, "PackQuantity"); } if(!string.IsNullOrEmpty(FastnersPerPart)) { partsToFit = arrFastenersPerPart.Count() > 0 ? arrFastenersPerPart.Where(l => l.Key[0] == grpId).Select(l => l.Key[1]).FirstOrDefault() : String.Empty; } } <form role="form" name="@productId" id="@productId" method="post" action="/Default.aspx"> <div class="modal-body"> <input type="hidden" name="CartCmd" id="CartCmd" value="add"> <input type="hidden" name="ProductID" id="ProductID" value="@productId"> <input type="hidden" name="UnitID" id="UnitID" value="Unit_EACH"> <input type="hidden" name="wishListID" id="wishListID" value="0"> <span class="groupname pull-left">@groupName<br />@partToFitName (Pack Qty: @pkQuantity)</span> <span class="productid pull-left">@productId</span> <span class="partsToFit pull-left">@partsToFit</span> @if (Dynamicweb.Input.FormatBoolean(GetGlobalValue("Global:Extranet.UserName")) || product.GetBoolean("Ecom:Product:Field.SLGuestPricing")) { <span class="price pull-left" name="productprice"><strong>@price</strong></span> <button type="submit" name="submit" onclick="UpdateCart();" class="btn btn-dw-cart pull-right"><strong>@Translate("Add", "Add")</strong></button> <input type="number" min="1" name="Quantity" value="1" class="pull-right" style="width:30px; text-align:center; margin-right:10px !important; height:10px;"> } else { <p style="padding-left: 40px; padding-top: 1px; display:block;float:left;">Please <a href="#" data-toggle="modal" data-target="#login" class="dw-login">login</a> to see product pricing and to buy online! 2</p> } </div> </form> }} </div> </div> </div> } </div> </div> Count++; if (Count == ColMD) { <div class="row"></div> Count = 0; } } } @helper GetSubgroups(){ <!-- ProductListRender GetSubGroups --> foreach(var subgroup in GetLoop("Subgroups")){ string Image = subgroup.GetValue("Ecom:Group.SmallImage").ToString(); <div class="col-md-4 col-sm-4 col-xs-12" name="productlist"> <div class="wp-block product" name="boxproduct"> <h2 class="product-title"> <a href="@subgroup.GetValue("Ecom:Group.Link.Clean")">@subgroup.GetValue("Ecom:Group.Name")</a> </h2> <div name="listproductright"> <a title="@subgroup.GetValue("Ecom:Group.Name")" href="@subgroup.GetValue("Ecom:Group.Link.Clean")"> <figure name="productfigure" style="border-bottom: 1px solid rgb(224, 237, 237);"> @if(Image.Length > 28) { <img alt="" src="/Admin/Public/Getimage.ashx?width=300&height=300&compression=85&Crop=5&image=@subgroup.GetValue("Ecom:Group.SmallImage")" class="img-responsive img-center" alt="@subgroup.GetValue("Ecom:Group.Name")"> } else { <img alt="" src="/Admin/Public/Getimage.ashx?width=300&height=300&compression=85&Crop=5&image=/Files/Images/Ecom/missing_image.gif" class="img-responsive img-center" alt="@subgroup.GetValue("Ecom:Group.Name")"> } </figure> </a> </div> <div class="btn btn-dw-cart pull-right products-button"> <a href="@subgroup.GetValue("Ecom:Group.Link.Clean")"><strong>@Translate("showparts", "Show parts")</strong></a> </div> </div> </div> } } @{ var grouplink = "/Default.aspx?ID=" + GetValue("Ecom:ProductList:Page.ID") + "&GroupID=" + GetValue("Ecom:ProductList:Page.GroupID"); } <script> function getCookie(name){ var pattern = RegExp(name + "=.[^;]*") matched = document.cookie.match(pattern) if (matched) { var cookie = matched[0].split('=') return cookie[1] } return false } </script> <div class="col-md-12 col-sm-12 col-xs-12"> <div class="row"> <div class="col-md-12 col-sm-12 col-xs-12"> @if (!string.IsNullOrWhiteSpace(GetString("Server:Request.ecomquery"))) { <h3 class="dw-section-title"><span>Searchresult for '@GetString("Server:Request.ecomquery")'</span></h3> } @if (string.IsNullOrWhiteSpace(GetString("Server:Request.ecomquery"))) { <h3 class="dw-section-title dw-section-title-small"> <span> @if (!string.IsNullOrWhiteSpace(GetString("Ecom:ProductList:Page.GroupName"))) { @GetString("Ecom:ProductList:Page.GroupName"); } else { <text>@Translate("All products", "All products")</text> } </span> </h3> } </div> <div class="col-md-4 col-sm-4 col-xs-4 hidden-xs"> <div class="hidden-xs"> <span class="text-center" style="color: #AAAAAA !important; font-size: 14px !important">@Translate("Showing page", "Showing page") @GetValue("Ecom:ProductList.CurrentPage") @Translate("of", "of") @GetValue("Ecom:ProductList.TotalPages") (@GetValue("Ecom:ProductList.PageProdCnt") @Translate("products", "products"))</span> </div> </div> <div class="col-md-4 col-sm-4 col-xs-4 pull-right"> <div class="btn-group pull-right hidden-xs" style="" id="viewbtns"> <button type="button" class="btn btn-xs btn-three" onclick="ListView()"><span class="glyphicon glyphicon-th-list"></span></button> <button type="button" class="btn btn-xs btn-three" onclick="BoxView()"><span class="glyphicon glyphicon-th"></span></button> </div> <div class="pull-right"> <div class="btn-group"> <button type="button" class="btn btn-xs btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> @Translate("Sort by", "Sort by") <span class="caret"></span> </button> <ul class="dropdown-menu" role="menu"> <li><a onclick="SortProductsBy('Name')">@Translate("Default", "Default")</a></li> <li class="divider"></li> <li><a onclick="SortProductsBy('Name&SortOrder=Asc')" class="pill-left">@Translate("Name A-Z", "Name A-Z") </a></li> <li><a onclick="SortProductsBy('Name&SortOrder=Desc')" class="pill-left">@Translate("Name Z-A", "Name Z-A") </a></li> <li><a onclick="SortProductsBy('Price&SortOrder=Asc')" class="pill-left">@Translate("Price low-high", "Price low-high") </a></li> <li><a onclick="SortProductsBy('Price&SortOrder=Desc')" class="pill-left">@Translate("Price high-low", "Price high-low") </a></li> </ul> </div> <text>&nbsp;&nbsp;</text> </div> </div> </div> <div class="row">&nbsp;</div> <div class="row"> @GetProductList(GetLoop("Products"), 3) <!-- The columns are controled by the listview javascript --> </div> <hr> <span class="shop-page-info pull-left hidden-sm hidden-xs" style="color: #AAAAAA !important; font-size:14px !important">@Translate("Showing page", "Showing page") @GetValue("Ecom:ProductList.CurrentPage") @Translate("of", "of") @GetValue("Ecom:ProductList.TotalPages") (@GetValue("Ecom:ProductList.PageProdCnt") @Translate("products", "products"))</span> <ul class="pagination pull-right"> @if (!string.IsNullOrWhiteSpace(GetString("Ecom:ProductList.PrevPage.Clean"))) { <li><a rel="prev" href="@GetString("Ecom:ProductList.PrevPage.Clean")">&laquo;</a></li> } @if (!string.IsNullOrWhiteSpace(GetString("Ecom:ProductList.NextPage.Clean"))) { <li><a rel="next" href="@GetString("Ecom:ProductList.NextPage.Clean")">&raquo;</a></li> } </ul> </div> <div class="row"><div class="col-md-12 col-sm-12 col-xs-12">&nbsp</div></div> <script> function listviewCookietest() { if (getCookie("productviewtype")) { if (getCookie("productviewtype") == "box"){ BoxView(); } else { ListView(); } } } window.onresize = function () { testscreensize(); } function testscreensize(){ if ($(this).width() < 768) { BoxView(); } else { listviewCookietest(); } } function BoxView() { var arr = new Array(); arr = document.getElementsByName("productlist"); for(var i = 0; i < arr.length; i++) { document.getElementsByName("productlist").item(i).className = "col-md-4 col-sm-4 col-xs-12"; document.getElementsByName("listproductright").item(i).className = ""; document.getElementsByName("extracolumn").item(i).className = ""; document.getElementsByName("boxproduct").item(i).className = "wp-block product"; document.getElementsByName("listproductleft").item(i).className = "wp-block-footer"; document.getElementsByName("shortproductdescription").item(i).style = ""; document.getElementsByName("longproductdescription").item(i).style = "display: none !important; text-align: left !important"; document.getElementsByName("productfigure").item(i).style = "border-bottom: 1px solid #E0EDED"; } document.cookie = "productviewtype=box"; } function ListView() { var arr = new Array(); arr = document.getElementsByName("productlist"); for(var i = 0; i < arr.length; i++) { document.getElementsByName("productlist").item(i).className = "col-md-12 col-sm-12 col-xs-12"; document.getElementsByName("listproductright").item(i).className = "col-md-4 col-sm-4 col-xs-12"; document.getElementsByName("extracolumn").item(i).className = "col-md-8 col-sm-8 col-xs-12"; document.getElementsByName("boxproduct").item(i).className = "wp-block product"; document.getElementsByName("listproductleft").item(i).className = "col-md-8 col-sm-8 col-xs-12"; document.getElementsByName("shortproductdescription").item(i).style = "display: none !important"; document.getElementsByName("longproductdescription").item(i).style = "text-align: left !important"; document.getElementsByName("productfigure").item(i).style = "border-bottom: none"; } document.cookie = "productviewtype=list"; } function SortProductsBy(sortcode) { var Page = "@grouplink"; document.cookie = "sortby=" + sortcode; document.location.href = Page + "&SortBy=" + sortcode; } function UpdateCart() { document.getElementById('minipagecart').className = " dw-minicart-update"; document.getElementById('minipagecart-button').className = "btn btn-sm dw-minicart-update"; } </script> @if (Pageview.Area.Item["EcommerceProductListForm"].ToString() == "box"){ <script> if (!getCookie("productviewtype")) { BoxView(); } else { listviewCookietest(); } </script> } else { <script> if (!getCookie("productviewtype")) { ListView(); } else { listviewCookietest(); } </script> }