Error executing template "Designs/Swift/eCom/CustomerExperienceCenter/Favorites/FavoriteLists.cshtml"
System.NullReferenceException: Object reference not set to an instance of an object.
   at CompiledRazorTemplates.Dynamic.RazorEngine_5ba7c945399b4afead2ef0e005eb9f76.Execute() in D:\dynamicweb.net\Solutions\Dynamicweb\dynamicwebdemo.dwsales.dynamicweb-cms.com\files\Templates\Designs\Swift\eCom\CustomerExperienceCenter\Favorites\FavoriteLists.cshtml:line 216
   at RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context, TextWriter reader)
   at RazorEngine.Templating.RazorEngineService.RunCompile(ITemplateKey key, TextWriter writer, Type modelType, Object model, DynamicViewBag viewBag)
   at RazorEngine.Templating.RazorEngineServiceExtensions.<>c__DisplayClass16_0.<RunCompile>b__0(TextWriter writer)
   at RazorEngine.Templating.RazorEngineServiceExtensions.WithWriter(Action`1 withWriter)
   at Dynamicweb.Rendering.RazorTemplateRenderingProvider.Render(Template template)
   at Dynamicweb.Rendering.TemplateRenderingService.Render(Template template)
   at Dynamicweb.Rendering.Template.RenderRazorTemplate()

1 @inherits ViewModelTemplate<FavoriteListListViewModel> 2 @using Dynamicweb.Rendering 3 @using Dynamicweb.Ecommerce.Frontend 4 5 @{ 6 var themeRaw = Pageview.CurrentParagraph.Item["Theme"]?.ToString(); 7 string theme = !string.IsNullOrEmpty(themeRaw) ? " h-100 theme " + themeRaw.Replace(" ", "").Trim().ToLower() : ""; 8 } 9 10 @if (theme != "") { 11 <div class="@(theme)"> 12 @RenderContent() 13 </div> 14 } else { 15 @RenderContent() 16 } 17 18 @helper RenderContent() { 19 string listPageLink = Pageview.CurrentParagraph.Item["ProductListPage"] != null ? Pageview.CurrentParagraph.Item["ProductListPage"].ToString() : ""; 20 string currentPageUrl = "/Default.aspx?ID=" + Pageview.Page.ID; 21 int listsCount = Model.TotalFavoriteListsCount; 22 int pageSize = Model.PageSize; 23 24 <header class="d-flex flex-wrap align-items-center gap-3 p-3 border-bottom"> 25 <h1 class="h6 m-0 flex-fill">@Translate("Favorite lists")</h1> 26 @if (Model.FavoriteLists != null) 27 { 28 if(Model.FavoriteLists.Count > 0) { 29 <button type="button" class="btn btn-link p-0 border-0" data-bs-toggle="modal" data-bs-target="#createFavoriteListModal">+ @Translate("Add new favorite list")</button> 30 } 31 } 32 </header> 33 34 if (Model.FavoriteLists == null || Model.FavoriteLists.Count < 1) 35 { 36 <div class="grid"> 37 <div class="g-col-12 g-start-lg-3 g-col-lg-8 d-flex flex-column gap-3 text-center py-3"> 38 <h2 class="h5 m-0">@Translate("It looks like you do not have any favorites yet")</h2> 39 <p class="m-0">@Translate("Save and arrange the best things here until you are ready for them")</p> 40 41 <div class="d-flex flex-column flex-sm-row gap-3 justify-content-center"> 42 @if (!string.IsNullOrEmpty(listPageLink)) { 43 <a href="@listPageLink" class="btn btn-secondary">@Translate("Go exploring")</a> 44 } 45 <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#createFavoriteListModal">@Translate("Create favorite list")</button> 46 </div> 47 </div> 48 </div> 49 } 50 else 51 { 52 string productCountLabel = Model.FavoriteLists.Count > 1 ? Translate("products") : Translate("product"); 53 54 foreach (var theList in Model.FavoriteLists) 55 { 56 string favoriteListLink = currentPageUrl + "&amp;FavoriteListId=" + theList.Id; 57 string listName = !string.IsNullOrEmpty(theList.Name) ? theList.Name : Translate("Favorites"); 58 59 <article class="d-flex flex-column gap-3 p-3 border-bottom"> 60 61 <header class="d-flex flex-row align-items-baseline lh-1"> 62 <h3 class="flex-fill h6 m-0"> 63 <a href="@favoriteListLink" class="text-decoration-none opacity-75">@listName</a> 64 </h3> 65 <span class="small text-end">@theList.ProductList.Products.Count @productCountLabel <span class="d-none d-sm-inline">@Translate("in this list")</span></span> 66 </header> 67 68 <div class="d-md-none grid grid-2"> 69 @if(theList.ProductList.Products.Count > 0) 70 { 71 foreach (var item in theList.ProductList.Products.Take(2)) 72 { 73 string productImage = "/Admin/Public/GetImage.ashx?Image=" + item.DefaultImage.Value + "&Format=webp&Width=350&Height=350"; 74 75 <div class="ratio ratio-1x1"> 76 <a href="@favoriteListLink" class="d-flex justify-content-center align-items-center"> 77 <img 78 src="@productImage" 79 width="350" 80 loading="lazy" 81 decoding="async" 82 class="mw-100 mh-100" 83 alt="@item.Name" /> 84 </a> 85 </div> 86 } 87 } 88 else 89 { 90 <div class="g-col-12 py-5 text-center border"> 91 <a href="@listPageLink">@Translate("This list is empty. Click here to be inspired")</a> 92 </div> 93 } 94 </div> 95 96 <div class="d-none d-md-grid d-print-grid grid grid-2 grid-md-5"> 97 @if(theList.ProductList.Products.Count > 0) 98 { 99 foreach (var item in theList.ProductList.Products.Take(5)) 100 { 101 string productImage = "/Admin/Public/GetImage.ashx?Image=" + @item.DefaultImage.Value + "&Format=webp&Width=350&Height=350"; 102 103 <div class="ratio ratio-1x1"> 104 <a href="@favoriteListLink" class="d-flex justify-content-center align-items-center"> 105 <img 106 src="@productImage" 107 width="350" 108 loading="lazy" 109 decoding="async" 110 class="mw-100 mh-100" 111 alt="@item.Name" /> 112 </a> 113 </div> 114 } 115 } 116 else 117 { 118 <div class="g-col-12 py-6 text-center border"> 119 <a href="@listPageLink">@Translate("This list is empty. Click here to be inspired")</a> 120 </div> 121 } 122 </div> 123 124 <footer class="d-flex flex-row gap-3 align-items-center justify-content-end"> 125 <button 126 type="button" 127 class="btn btn-link p-0 renameFavoriteListModal" 128 data-bs-toggle="modal" 129 data-bs-target="#renameFavoriteListModal" 130 data-list-id="@theList.Id" 131 data-list-name="@listName">@Translate("Rename") 132 </button> 133 <button 134 type="button" 135 class="btn btn-link p-0 deleteFavoriteNameButton" 136 data-bs-toggle="modal" 137 data-bs-target="#deleteFavoriteListModal" 138 data-list-id="@theList.Id" 139 data-list-name="@listName">@Translate("Delete")</button> 140 </footer> 141 </article> 142 } 143 } 144 145 if (listsCount > pageSize) 146 { 147 <div class="p-3"> 148 @RenderPagination(currentPageUrl, Model.PageCount, Model.CurrentPage, Model.PageSize) 149 </div> 150 } 151 } 152 153 <div class="modal fade" tabindex="-1" id="createFavoriteListModal"> 154 <div class="modal-dialog modal-dialog-centered"> 155 <div class="modal-content"> 156 <div class="modal-header"> 157 <h5 class="modal-title">@Translate("Create favorite list")</h5> 158 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 159 </div> 160 <div class="modal-body d-flex flex-column gap-3"> 161 <div> 162 <label for="createFavoriteListInputName" class="form-label">@Translate("Name the favorite list")</label> 163 <input type="text" class="form-control" id="createFavoriteListInputName" placeholder="@Translate("Name")"> 164 </div> 165 <div class="alert alert-danger m-0 d-none" role="alert" id="createFavoriteListError">@Translate("A Favorite List must have a name")</div> 166 </div> 167 <div class="modal-footer"> 168 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">@Translate("Cancel")</button> 169 <button type="button" class="btn btn-primary" id="createFavoriteListButton">@Translate("Create list")</button> 170 </div> 171 </div> 172 </div> 173 </div> 174 175 <div class="modal fade" tabindex="-1" id="renameFavoriteListModal"> 176 <div class="modal-dialog modal-dialog-centered"> 177 <div class="modal-content"> 178 <div class="modal-header"> 179 <h5 class="modal-title">@Translate("Rename favorite list")</h5> 180 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 181 </div> 182 <div class="modal-body"> 183 <div> 184 <label for="renameFavoriteListInputName" class="form-label">@Translate("Rename favorite list"):</label> 185 <input type="text" class="form-control" id="renameFavoriteListInputName" placeholder="@Translate("Name")"> 186 </div> 187 </div> 188 <div class="modal-footer"> 189 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">@Translate("Cancel")</button> 190 <button type="button" class="btn btn-primary" id="renameFavoriteListButton">@Translate("Update list")</button> 191 </div> 192 </div> 193 </div> 194 </div> 195 196 <div class="modal fade" tabindex="-1" id="deleteFavoriteListModal"> 197 <div class="modal-dialog modal-dialog-centered"> 198 <div class="modal-content"> 199 <div class="modal-header"> 200 <h5 class="modal-title">@Translate("Delete favorite list")</h5> 201 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 202 </div> 203 <div class="modal-body"> 204 <p>@Translate("You are about to delete"): <strong id="deleteFavoriteName"></strong>.</p> 205 <p>@Translate("Are you sure you want to delete it?")</p> 206 </div> 207 <div class="modal-footer"> 208 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">@Translate("Cancel")</button> 209 <button type="button" class="btn btn-primary" id="deleteFavoriteListButton">@Translate("Delete list")</button> 210 </div> 211 </div> 212 </div> 213 </div> 214 215 <script> 216 let userId = @Pageview.User.ID; 217 let renameFavoriteListModal = document.querySelector("#renameFavoriteListModal") 218 let deleteFavoriteListModal = document.querySelector("#deleteFavoriteListModal") 219 220 renameFavoriteListModal.addEventListener('show.bs.modal', function (event) { 221 let button = event.relatedTarget 222 let renameFavoriteListId = button.getAttribute('data-list-id'); 223 let renameFromName = button.getAttribute('data-list-name') 224 let renameFavoriteListInputName = document.getElementById('renameFavoriteListInputName'); 225 226 renameFavoriteListInputName.value = renameFromName; 227 228 document.querySelector("#renameFavoriteListButton").addEventListener("click", function () { 229 let favoriteListId = renameFavoriteListId; 230 231 // Rename Favorite List 232 document.location.href = "/?favoritecmd=renamefavoritelist&userId=" + userId + "&favoriteListId=" + favoriteListId + "&name=" + renameFavoriteListInputName.value; 233 }); 234 }) 235 236 deleteFavoriteListModal.addEventListener('show.bs.modal', function (event) { 237 let button = event.relatedTarget; 238 let deleteFavoriteListId = button.getAttribute('data-list-id'); 239 let deleteFavoriteListName = button.getAttribute('data-list-name'); 240 let deleteFavoriteName = document.querySelector("#deleteFavoriteName"); 241 242 // Update label to confirm before deletion 243 deleteFavoriteName.innerHTML = deleteFavoriteListName; 244 245 // Delete Favorite List 246 document.querySelector("#deleteFavoriteListButton").addEventListener("click", function () { 247 let favoriteListId = deleteFavoriteListId; 248 DeleteFavoriteList(userId, favoriteListId); 249 }); 250 }) 251 252 async function DeleteFavoriteList(userId, favoriteListId) { 253 var url = "/?favoritecmd=removefavoritelist&userId=" + userId + "&favoriteListId=" + favoriteListId; 254 255 let response = await fetch(url); 256 if (response.ok) { 257 document.location.href = "/Default.aspx?ID=@(Pageview.Page.ID)"; 258 } 259 } 260 261 // Create new Favorite List 262 document.querySelector("#createFavoriteListButton").addEventListener("click", function () { 263 let createFavoriteListName = document.querySelector("#createFavoriteListInputName").value; 264 265 if (createFavoriteListName != "") { 266 document.location.href = "/?favoritecmd=createfavoritelist&userId=" + userId + "&name=" + createFavoriteListName; 267 } 268 else if (document.querySelector("#createFavoriteListError")) 269 { 270 document.querySelector("#createFavoriteListError").classList.remove("d-none"); 271 } 272 }); 273 </script> 274 275 276 @helper RenderPagination(string currentPageLink, int pageCount, int currentPage, int pageSize) 277 { 278 <ul class="pagination m-0"> 279 @{string pageHrefTemplate = string.Format("<a class=\"page-link\" href=\"{0}&PageNum={{0}}&PageSize={{1}}\">{{0}}</a>", currentPageLink);} 280 @for (int i = 1; i <= pageCount; i++) 281 { 282 var css = i == currentPage 283 ? "page-item active" 284 : "page-item"; 285 <li class="@css"> 286 @string.Format(pageHrefTemplate, i, pageSize) 287 </li> 288 } 289 </ul> 290 } 291