Skip to content

Commit 6d0f159

Browse files
Merge pull request #104 from davidsonsousa/develop
Develop
2 parents 84ae1cd + c996d79 commit 6d0f159

22 files changed

+185
-112
lines changed

CmsEngine.Application/Models/ViewModels/ErrorViewModel.cs

+11-6
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@ namespace CmsEngine.Application.ViewModels
22
{
33
public class ErrorViewModel
44
{
5-
public string RequestId { get; set; }
5+
public string Title { get; }
6+
public string Message { get; }
67

7-
public bool ShowRequestId
8+
public ErrorViewModel(string message)
89
{
9-
get
10-
{
11-
return !string.IsNullOrEmpty(RequestId);
12-
}
10+
Title = "Error";
11+
Message = message;
12+
}
13+
14+
public ErrorViewModel(string pageTitle, string message)
15+
{
16+
Title = pageTitle;
17+
Message = message;
1318
}
1419
}
1520
}

CmsEngine.Application/Services/CategoryService.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ public async Task<CategoryEditModel> SetupEditModel(Guid id)
186186
var item = await _unitOfWork.Categories.GetByIdAsync(id);
187187
logger.LogInformation("Category: {0}", item.ToString());
188188

189-
return item.MapToEditModel();
189+
return item?.MapToEditModel();
190190
}
191191
}
192192
}

CmsEngine.Application/Services/PageService.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public async Task<PageViewModel> GetBySlug(string slug)
8989
{
9090
logger.LogInformation($"PageService > GetBySlug({slug})");
9191
var item = await _unitOfWork.Pages.GetBySlug(slug);
92-
return item.MapToViewModel();
92+
return item?.MapToViewModel();
9393
}
9494

9595
public async Task<(IEnumerable<PageTableViewModel> Data, int RecordsTotal, int RecordsFiltered)> GetForDataTable(DataParameters parameters)
@@ -192,7 +192,7 @@ public async Task<PageEditModel> SetupEditModel(Guid id)
192192
logger.LogInformation("PageService > SetupPageEditModel(id: {0})", id);
193193
var item = await _unitOfWork.Pages.GetByIdAsync(id);
194194
logger.LogInformation("Page: {0}", item.ToString());
195-
return item.MapToEditModel();
195+
return item?.MapToEditModel();
196196
}
197197

198198
private async Task PrepareRelatedProperties(Page page)

CmsEngine.Application/Services/PostService.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public async Task<PostViewModel> GetBySlug(string slug)
8181
{
8282
logger.LogInformation($"PostService > GetBySlug({slug})");
8383
var item = await _unitOfWork.Posts.GetBySlug(slug);
84-
return item.MapToViewModel();
84+
return item?.MapToViewModel();
8585
}
8686

8787
public async Task<IEnumerable<PostEditModel>> GetPublishedOrderedByDate(int count = 0)

CmsEngine.Application/Services/Service.cs

+64-53
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Threading.Tasks;
33
using CmsEngine.Application.ViewModels;
44
using CmsEngine.Core.Constants;
5+
using CmsEngine.Core.Exceptions;
56
using CmsEngine.Data;
67
using CmsEngine.Data.Entities;
78
using Microsoft.AspNetCore.Http;
@@ -14,6 +15,8 @@ public class Service : IService
1415
{
1516
private readonly IHttpContextAccessor _httpContextAccessor;
1617
private readonly IMemoryCache _memoryCache;
18+
private readonly string instanceHost;
19+
private readonly string instanceKey;
1720

1821
protected readonly IUnitOfWork unitOfWork;
1922
protected readonly ILogger logger;
@@ -22,7 +25,7 @@ public InstanceViewModel Instance
2225
{
2326
get
2427
{
25-
return GetInstanceAsync().GetAwaiter().GetResult();
28+
return GetInstance();
2629
}
2730
}
2831
public UserViewModel CurrentUser
@@ -39,6 +42,9 @@ public Service(IUnitOfWork uow, IHttpContextAccessor hca, ILoggerFactory loggerF
3942
_httpContextAccessor = hca;
4043
logger = loggerFactory.CreateLogger("Service");
4144
_memoryCache = memoryCache;
45+
46+
instanceHost = _httpContextAccessor.HttpContext.Request.Host.Host;
47+
instanceKey = $"{CmsEngineConstants.CacheKey.Instance}_{instanceHost}";
4248
}
4349

4450
internal async Task<ApplicationUser> GetCurrentUserAsync()
@@ -56,7 +62,15 @@ internal async Task<ApplicationUser> GetCurrentUserAsync()
5662
}
5763
}
5864

59-
private async Task<InstanceViewModel> GetInstanceAsync()
65+
protected void SaveInstanceToCache(object instance)
66+
{
67+
var timeSpan = TimeSpan.FromDays(7); //TODO: Perhaps set this in the config file. Or DB
68+
logger.LogInformation("Adding '{0}' to cache with expiration date to {1}", instanceKey, DateTime.Now.AddMilliseconds(timeSpan.TotalMilliseconds).ToString());
69+
var cacheEntryOptions = new MemoryCacheEntryOptions().SetSlidingExpiration(timeSpan);
70+
_memoryCache.Set(instanceKey, instance, cacheEntryOptions);
71+
}
72+
73+
private InstanceViewModel GetInstance()
6074
{
6175
logger.LogInformation("GetInstanceAsync()");
6276

@@ -65,65 +79,62 @@ private async Task<InstanceViewModel> GetInstanceAsync()
6579

6680
try
6781
{
68-
logger.LogInformation("Loading Instance from cache");
69-
if (!_memoryCache.TryGetValue(CmsEngineConstants.CacheKey.Instance, out instance))
82+
logger.LogInformation("Loading '{0}' from cache", instanceKey);
83+
if (!_memoryCache.TryGetValue(instanceKey, out instance))
7084
{
71-
logger.LogInformation("Empty cache for Instance. Loading instance from DB");
72-
website = await unitOfWork.Websites.GetWebsiteInstanceByHost(_httpContextAccessor.HttpContext.Request.Host.Host);
85+
logger.LogInformation("Empty cache for '{0}'. Loading instance from DB", instanceKey);
86+
website = unitOfWork.Websites.GetWebsiteInstanceByHost(instanceHost);
7387

74-
if (website != null)
88+
if (website == null)
7589
{
76-
instance = new InstanceViewModel
77-
{
78-
Id = website.Id,
79-
Name = website.Name,
80-
Description = website.Description,
81-
Tagline = website.Tagline,
82-
HeaderImage = website.HeaderImage,
83-
Culture = website.Culture,
84-
UrlFormat = website.UrlFormat,
85-
DateFormat = website.DateFormat,
86-
SiteUrl = website.SiteUrl,
87-
ArticleLimit = website.ArticleLimit,
88-
PageTitle = website.Name,
89-
ContactDetails = new ContactDetailsViewModel
90-
{
91-
Address = website.Address,
92-
Phone = website.Phone,
93-
Email = website.Email,
94-
},
95-
ApiDetails = new ApiDetailsViewModel
96-
{
97-
FacebookAppId = website.FacebookAppId,
98-
FacebookApiVersion = website.FacebookApiVersion,
99-
DisqusShortName = website.DisqusShortName
100-
},
101-
SocialMedia = new SocialMediaViewModel
102-
{
103-
Facebook = website.Facebook,
104-
Twitter = website.Twitter,
105-
Instagram = website.Instagram,
106-
LinkedIn = website.LinkedIn
107-
},
108-
Google = new GoogleViewModel
109-
{
110-
GoogleAnalytics = website.GoogleAnalytics,
111-
GoogleRecaptchaSiteKey = website.GoogleRecaptchaSiteKey,
112-
GoogleRecaptchaSecretKey = website.GoogleRecaptchaSecretKey
113-
}
114-
};
115-
116-
var timeSpan = TimeSpan.FromDays(7); //TODO: Perhaps set this in the config file. Or DB
117-
118-
logger.LogInformation("Adding Instance to cache with expiration date to {0}", DateTime.Now.AddMilliseconds(timeSpan.TotalMilliseconds).ToString());
119-
var cacheEntryOptions = new MemoryCacheEntryOptions().SetSlidingExpiration(timeSpan);
120-
_memoryCache.Set(CmsEngineConstants.CacheKey.Instance, instance, cacheEntryOptions);
90+
throw new NotFoundException($"Instance for '{instanceHost}' not found");
12191
}
92+
93+
instance = new InstanceViewModel
94+
{
95+
Id = website.Id,
96+
Name = website.Name,
97+
Description = website.Description,
98+
Tagline = website.Tagline,
99+
HeaderImage = website.HeaderImage,
100+
Culture = website.Culture,
101+
UrlFormat = website.UrlFormat,
102+
DateFormat = website.DateFormat,
103+
SiteUrl = website.SiteUrl,
104+
ArticleLimit = website.ArticleLimit,
105+
PageTitle = website.Name,
106+
ContactDetails = new ContactDetailsViewModel
107+
{
108+
Address = website.Address,
109+
Phone = website.Phone,
110+
Email = website.Email,
111+
},
112+
ApiDetails = new ApiDetailsViewModel
113+
{
114+
FacebookAppId = website.FacebookAppId,
115+
FacebookApiVersion = website.FacebookApiVersion,
116+
DisqusShortName = website.DisqusShortName
117+
},
118+
SocialMedia = new SocialMediaViewModel
119+
{
120+
Facebook = website.Facebook,
121+
Twitter = website.Twitter,
122+
Instagram = website.Instagram,
123+
LinkedIn = website.LinkedIn
124+
},
125+
Google = new GoogleViewModel
126+
{
127+
GoogleAnalytics = website.GoogleAnalytics,
128+
GoogleRecaptchaSiteKey = website.GoogleRecaptchaSiteKey,
129+
GoogleRecaptchaSecretKey = website.GoogleRecaptchaSecretKey
130+
}
131+
};
132+
133+
SaveInstanceToCache(instance);
122134
}
123135
}
124136
catch (Exception ex)
125137
{
126-
logger.LogError(ex, "Error when trying to load Instance");
127138
throw ex;
128139
}
129140

CmsEngine.Application/Services/TagService.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ public async Task<TagEditModel> SetupEditModel(Guid id)
170170
logger.LogInformation("CmsService > SetupTagEditModel(id: {0})", id);
171171
var item = await _unitOfWork.Tags.GetByIdAsync(id);
172172
logger.LogInformation("Tag: {0}", item.ToString());
173-
return item.MapToEditModel();
173+
return item?.MapToEditModel();
174174
}
175175
}
176176
}

CmsEngine.Application/Services/WebsiteService.cs

+2-8
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
using CmsEngine.Application.Extensions.Mapper;
99
using CmsEngine.Application.ViewModels.DataTableViewModels;
1010
using CmsEngine.Core;
11-
using CmsEngine.Core.Constants;
1211
using CmsEngine.Data;
1312
using CmsEngine.Data.Entities;
1413
using Microsoft.AspNetCore.Http;
@@ -144,12 +143,7 @@ public async Task<ReturnValue> Save(WebsiteEditModel websiteEditModel)
144143

145144
await _unitOfWork.Save();
146145

147-
// Update Instance cache
148-
var timeSpan = TimeSpan.FromDays(7); //TODO: Perhaps set this in the config file. Or DB
149-
logger.LogInformation("Updating Instance with expiration date to {0}", DateTime.Now.AddMilliseconds(timeSpan.TotalMilliseconds).ToString());
150-
var cacheEntryOptions = new MemoryCacheEntryOptions().SetSlidingExpiration(timeSpan);
151-
_memoryCache.Set(CmsEngineConstants.CacheKey.Instance, websiteEditModel, cacheEntryOptions);
152-
146+
SaveInstanceToCache(websiteEditModel);
153147
logger.LogInformation("Website saved");
154148
}
155149
catch (Exception ex)
@@ -172,7 +166,7 @@ public async Task<WebsiteEditModel> SetupEditModel(Guid id)
172166
logger.LogInformation("CmsService > SetupEditModel(id: {0})", id);
173167
var item = await _unitOfWork.Websites.GetByIdAsync(id);
174168
logger.LogInformation("Website: {0}", item.ToString());
175-
return item.MapToEditModel();
169+
return item?.MapToEditModel();
176170
}
177171
}
178172
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
3+
namespace CmsEngine.Core.Exceptions
4+
{
5+
public class NotFoundException : Exception
6+
{
7+
public NotFoundException(string message) : base(message)
8+
{
9+
}
10+
11+
public NotFoundException(string message, Exception innerException) : base(message, innerException)
12+
{
13+
}
14+
}
15+
}

CmsEngine.Data/Repositories/CategoryRepository.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public CategoryRepository(CmsEngineContext context) : base(context)
1515

1616
public async Task<Category> GetCategoryBySlug(string slug)
1717
{
18-
return await Get(q => q.Slug == slug).SingleAsync();
18+
return await Get(q => q.Slug == slug).SingleOrDefaultAsync();
1919
}
2020

2121
public async Task<IEnumerable<Category>> GetCategoriesWithPostCountOrderedByName()
@@ -34,7 +34,7 @@ public async Task<IEnumerable<Category>> GetCategoriesWithPostCountOrderedByName
3434

3535
public async Task<Category> GetCategoryBySlugWithPosts(string slug)
3636
{
37-
return await Get(q => q.Slug == slug).Include(c => c.PostCategories).SingleAsync();
37+
return await Get(q => q.Slug == slug).Include(c => c.PostCategories).SingleOrDefaultAsync();
3838
}
3939

4040
public async Task<IEnumerable<Category>> GetCategoriesWithPostOrderedByName()

CmsEngine.Data/Repositories/IWebsiteRepository.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace CmsEngine.Data.Repositories
66
{
77
public interface IWebsiteRepository : IReadRepository<Website>, IDataModificationRepository<Website>, IDataModificationRangeRepository<Website>
88
{
9-
Task<Website> GetWebsiteInstanceByHost(string host);
9+
Website GetWebsiteInstanceByHost(string host);
1010
Task<IEnumerable<Website>> GetForDataTable();
1111
}
1212
}

CmsEngine.Data/Repositories/PageRepository.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public async Task<Page> GetBySlug(string slug)
4646
Email = au.Email
4747
})
4848
})
49-
.SingleAsync();
49+
.SingleOrDefaultAsync();
5050
}
5151

5252
public async Task<IEnumerable<Page>> GetForDataTable()
@@ -72,7 +72,7 @@ public async Task<IEnumerable<Page>> GetForDataTable()
7272
public async Task<Page> GetForSavingById(Guid id)
7373
{
7474
return await Get(q => q.VanityId == id).Include(p => p.PageApplicationUsers)
75-
.SingleAsync();
75+
.SingleOrDefaultAsync();
7676
}
7777

7878
public void RemoveRelatedItems(Page page)

CmsEngine.Data/Repositories/PostRepository.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public async Task<Post> GetBySlug(string slug)
5252
Email = au.Email
5353
})
5454
})
55-
.SingleAsync();
55+
.SingleOrDefaultAsync();
5656
}
5757

5858
public async Task<(IEnumerable<Post> Items, int Count)> GetPublishedByCategoryForPagination(string categorySlug, int page, int articleLimit)
@@ -261,7 +261,7 @@ public async Task<Post> GetForSavingById(Guid id)
261261
return await Get(q => q.VanityId == id).Include(p => p.PostCategories)
262262
.Include(p => p.PostTags)
263263
.Include(p => p.PostApplicationUsers)
264-
.SingleAsync();
264+
.SingleOrDefaultAsync();
265265
}
266266

267267
public async Task<Post> GetForEditingById(Guid id)
@@ -270,7 +270,7 @@ public async Task<Post> GetForEditingById(Guid id)
270270
.ThenInclude(pc => pc.Category)
271271
.Include(p => p.PostTags)
272272
.ThenInclude(pt => pt.Tag)
273-
.SingleAsync();
273+
.SingleOrDefaultAsync();
274274
}
275275

276276
public void RemoveRelatedItems(Post post)

CmsEngine.Data/Repositories/Repository.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ public async Task<IEnumerable<TEntity>> GetReadOnlyAsync(Expression<Func<TEntity
5757

5858
public async Task<TEntity> GetByIdAsync(int id)
5959
{
60-
return await Get(q => q.Id == id).SingleAsync();
60+
return await Get(q => q.Id == id).SingleOrDefaultAsync();
6161
}
6262

6363
public async Task<TEntity> GetByIdAsync(Guid id)
6464
{
65-
return await Get(q => q.VanityId == id).SingleAsync();
65+
return await Get(q => q.VanityId == id).SingleOrDefaultAsync();
6666
}
6767

6868
public async Task<IEnumerable<TEntity>> GetByMultipleIdsAsync(int[] ids)

CmsEngine.Data/Repositories/TagRepository.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ public TagRepository(CmsEngineContext context) : base(context)
1414

1515
public async Task<Tag> GetTagBySlug(string slug)
1616
{
17-
return await Get(q => q.Slug == slug).SingleAsync();
17+
return await Get(q => q.Slug == slug).SingleOrDefaultAsync();
1818
}
1919

2020
public async Task<Tag> GetTagBySlugWithPosts(string slug)
2121
{
22-
return await Get(q => q.Slug == slug).Include(t => t.PostTags).SingleAsync();
22+
return await Get(q => q.Slug == slug).Include(t => t.PostTags).SingleOrDefaultAsync();
2323
}
2424

2525
public async Task<IEnumerable<Tag>> GetTagsWithPosts()

CmsEngine.Data/Repositories/WebsiteRepository.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@ public async Task<IEnumerable<Website>> GetForDataTable()
2828
}).ToListAsync();
2929
}
3030

31-
public async Task<Website> GetWebsiteInstanceByHost(string host)
31+
public Website GetWebsiteInstanceByHost(string host)
3232
{
33-
return await Get(q => q.SiteUrl == host)
34-
.SingleAsync();
33+
return Get(q => q.SiteUrl == host).SingleOrDefault();
3534
}
3635
}
3736
}

0 commit comments

Comments
 (0)