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_59b1f72ee52f438684954f92a5ae7216.Execute() in D:\DW9\Solutions\witt.dk\Files\Templates\Designs\Swift\eCom\CustomerExperienceCenter\Favorites\FavoriteLists.cshtml:line 214
   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 loading="lazy" 80 decoding="async" 81 class="mw-100 mh-100" 82 alt="@item.Name" /> 83 </a> 84 </div> 85 } 86 } 87 else 88 { 89 <div class="g-col-12 py-5 text-center border"> 90 <a href="@listPageLink">@Translate("This list is empty. Click here to be inspired")</a> 91 </div> 92 } 93 </div> 94 95 <div class="d-none d-md-grid d-print-grid grid grid-2 grid-md-5"> 96 @if(theList.ProductList.Products.Count > 0) 97 { 98 foreach (var item in theList.ProductList.Products.Take(5)) 99 { 100 string productImage = "/Admin/Public/GetImage.ashx?Image=" + item.DefaultImage.Value + "&Format=webp&Width=350&Height=350"; 101 102 <div class="ratio ratio-1x1"> 103 <a href="@favoriteListLink" class="d-flex justify-content-center align-items-center"> 104 <img 105 src="@productImage" 106 loading="lazy" 107 decoding="async" 108 class="mw-100 mh-100" 109 alt="@item.Name" /> 110 </a> 111 </div> 112 } 113 } 114 else 115 { 116 <div class="g-col-12 py-6 text-center border"> 117 <a href="@listPageLink">@Translate("This list is empty. Click here to be inspired")</a> 118 </div> 119 } 120 </div> 121 122 <footer class="d-flex flex-row gap-3 align-items-center justify-content-end"> 123 <button 124 type="button" 125 class="btn btn-link p-0 renameFavoriteListModal" 126 data-bs-toggle="modal" 127 data-bs-target="#renameFavoriteListModal" 128 data-list-id="@theList.Id" 129 data-list-name="@listName">@Translate("Rename") 130 </button> 131 <button 132 type="button" 133 class="btn btn-link p-0 deleteFavoriteNameButton" 134 data-bs-toggle="modal" 135 data-bs-target="#deleteFavoriteListModal" 136 data-list-id="@theList.Id" 137 data-list-name="@listName">@Translate("Delete")</button> 138 </footer> 139 </article> 140 } 141 } 142 143 if (listsCount > pageSize) 144 { 145 <div class="p-3"> 146 @RenderPagination(currentPageUrl, Model.PageCount, Model.CurrentPage, Model.PageSize) 147 </div> 148 } 149 } 150 151 <div class="modal fade" tabindex="-1" id="createFavoriteListModal"> 152 <div class="modal-dialog modal-dialog-centered"> 153 <div class="modal-content"> 154 <div class="modal-header"> 155 <h5 class="modal-title">@Translate("Create favorite list")</h5> 156 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 157 </div> 158 <div class="modal-body d-flex flex-column gap-3"> 159 <div> 160 <label for="createFavoriteListInputName" class="form-label">@Translate("Name the favorite list")</label> 161 <input type="text" class="form-control" id="createFavoriteListInputName" placeholder="@Translate("Name")"> 162 </div> 163 <div class="alert alert-danger m-0 d-none" role="alert" id="createFavoriteListError">@Translate("A Favorite List must have a name")</div> 164 </div> 165 <div class="modal-footer"> 166 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">@Translate("Cancel")</button> 167 <button type="button" class="btn btn-primary" id="createFavoriteListButton">@Translate("Create list")</button> 168 </div> 169 </div> 170 </div> 171 </div> 172 173 <div class="modal fade" tabindex="-1" id="renameFavoriteListModal"> 174 <div class="modal-dialog modal-dialog-centered"> 175 <div class="modal-content"> 176 <div class="modal-header"> 177 <h5 class="modal-title">@Translate("Rename favorite list")</h5> 178 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 179 </div> 180 <div class="modal-body"> 181 <div> 182 <label for="renameFavoriteListInputName" class="form-label">@Translate("Rename favorite list"):</label> 183 <input type="text" class="form-control" id="renameFavoriteListInputName" placeholder="@Translate("Name")"> 184 </div> 185 </div> 186 <div class="modal-footer"> 187 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">@Translate("Cancel")</button> 188 <button type="button" class="btn btn-primary" id="renameFavoriteListButton">@Translate("Update list")</button> 189 </div> 190 </div> 191 </div> 192 </div> 193 194 <div class="modal fade" tabindex="-1" id="deleteFavoriteListModal"> 195 <div class="modal-dialog modal-dialog-centered"> 196 <div class="modal-content"> 197 <div class="modal-header"> 198 <h5 class="modal-title">@Translate("Delete favorite list")</h5> 199 <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> 200 </div> 201 <div class="modal-body"> 202 <p>@Translate("You are about to delete"): <strong id="deleteFavoriteName"></strong>.</p> 203 <p>@Translate("Are you sure you want to delete it?")</p> 204 </div> 205 <div class="modal-footer"> 206 <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">@Translate("Cancel")</button> 207 <button type="button" class="btn btn-primary" id="deleteFavoriteListButton">@Translate("Delete list")</button> 208 </div> 209 </div> 210 </div> 211 </div> 212 213 <script> 214 let userId = @Pageview.User.ID; 215 let renameFavoriteListModal = document.querySelector("#renameFavoriteListModal") 216 let deleteFavoriteListModal = document.querySelector("#deleteFavoriteListModal") 217 218 renameFavoriteListModal.addEventListener('show.bs.modal', function (event) { 219 let button = event.relatedTarget 220 let renameFavoriteListId = button.getAttribute('data-list-id'); 221 let renameFromName = button.getAttribute('data-list-name') 222 let renameFavoriteListInputName = document.getElementById('renameFavoriteListInputName'); 223 224 renameFavoriteListInputName.value = renameFromName; 225 226 document.querySelector("#renameFavoriteListButton").addEventListener("click", function () { 227 let favoriteListId = renameFavoriteListId; 228 229 // Rename Favorite List 230 document.location.href = "/?favoritecmd=renamefavoritelist&userId=" + userId + "&favoriteListId=" + favoriteListId + "&name=" + renameFavoriteListInputName.value; 231 }); 232 }) 233 234 deleteFavoriteListModal.addEventListener('show.bs.modal', function (event) { 235 let button = event.relatedTarget; 236 let deleteFavoriteListId = button.getAttribute('data-list-id'); 237 let deleteFavoriteListName = button.getAttribute('data-list-name'); 238 let deleteFavoriteName = document.querySelector("#deleteFavoriteName"); 239 240 // Update label to confirm before deletion 241 deleteFavoriteName.innerHTML = deleteFavoriteListName; 242 243 // Delete Favorite List 244 document.querySelector("#deleteFavoriteListButton").addEventListener("click", function () { 245 let favoriteListId = deleteFavoriteListId; 246 DeleteFavoriteList(userId, favoriteListId); 247 }); 248 }) 249 250 async function DeleteFavoriteList(userId, favoriteListId) { 251 var url = "/?favoritecmd=removefavoritelist&userId=" + userId + "&favoriteListId=" + favoriteListId; 252 253 let response = await fetch(url); 254 if (response.ok) { 255 document.location.href = "/Default.aspx?ID=@(Pageview.Page.ID)"; 256 } 257 } 258 259 // Create new Favorite List 260 document.querySelector("#createFavoriteListButton").addEventListener("click", function () { 261 let createFavoriteListName = document.querySelector("#createFavoriteListInputName").value; 262 263 if (createFavoriteListName != "") { 264 document.location.href = "/?favoritecmd=createfavoritelist&userId=" + userId + "&name=" + createFavoriteListName; 265 } 266 else if (document.querySelector("#createFavoriteListError")) 267 { 268 document.querySelector("#createFavoriteListError").classList.remove("d-none"); 269 } 270 }); 271 </script> 272 273 274 @helper RenderPagination(string currentPageLink, int pageCount, int currentPage, int pageSize) 275 { 276 <ul class="pagination m-0"> 277 @{string pageHrefTemplate = string.Format("<a class=\"page-link\" href=\"{0}&PageNum={{0}}&PageSize={{1}}\">{{0}}</a>", currentPageLink);} 278 @for (int i = 1; i <= pageCount; i++) 279 { 280 var css = i == currentPage 281 ? "page-item active" 282 : "page-item"; 283 <li class="@css"> 284 @string.Format(pageHrefTemplate, i, pageSize) 285 </li> 286 } 287 </ul> 288 } 289