();
+ db.Database.EnsureCreated();
+ DataLayerInitialise.SeedDatabase(db);
+}
+
+// Configure the HTTP request pipeline
+if (!app.Environment.IsDevelopment())
+{
+ app.UseExceptionHandler("/Home/Error");
+ app.UseHsts();
+}
+
+app.UseHttpsRedirection();
+app.UseStaticFiles();
+app.UseRouting();
+app.UseAuthorization();
+
+app.MapControllerRoute(
+ name: "default",
+ pattern: "{controller=Home}/{action=Index}/{id?}");
+
+app.Run();
diff --git a/SampleWebApp/Properties/AssemblyInfo.cs b/SampleWebApp/Properties/AssemblyInfo.cs
deleted file mode 100644
index 5605e92..0000000
--- a/SampleWebApp/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-#region licence
-// The MIT License (MIT)
-//
-// Filename: AssemblyInfo.cs
-// Date Created: 2014/05/20
-//
-// Copyright (c) 2014 Jon Smith (www.selectiveanalytics.com & www.thereformedprogrammer.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-#endregion
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("SampleWebApp")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("SampleWebApp")]
-[assembly: AssemblyCopyright("Copyright © 2014")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("fa016029-8cb0-4ef3-a0e0-c94ac71c1177")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Revision and Build Numbers
-// by using the '*' as shown below:
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/SampleWebApp/Properties/Settings.Designer.cs b/SampleWebApp/Properties/Settings.Designer.cs
deleted file mode 100644
index 3781ad7..0000000
--- a/SampleWebApp/Properties/Settings.Designer.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated by a tool.
-// Runtime Version:4.0.30319.18444
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace SampleWebApp.Properties {
-
-
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
- internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
-
- private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
-
- public static Settings Default {
- get {
- return defaultInstance;
- }
- }
-
- [global::System.Configuration.ApplicationScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("LocalHost")]
- public string HostTypeString {
- get {
- return ((string)(this["HostTypeString"]));
- }
- }
-
- [global::System.Configuration.ApplicationScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("jonsmith_")]
- public string DatabaseLoginPrefix {
- get {
- return ((string)(this["DatabaseLoginPrefix"]));
- }
- }
- }
-}
diff --git a/SampleWebApp/Properties/Settings.settings b/SampleWebApp/Properties/Settings.settings
deleted file mode 100644
index cd30221..0000000
--- a/SampleWebApp/Properties/Settings.settings
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
- LocalHost
-
-
- jonsmith_
-
-
-
\ No newline at end of file
diff --git a/SampleWebApp/SampleWebApp.csproj b/SampleWebApp/SampleWebApp.csproj
index eca4d77..277b6a9 100644
--- a/SampleWebApp/SampleWebApp.csproj
+++ b/SampleWebApp/SampleWebApp.csproj
@@ -1,485 +1,22 @@
-
-
-
+
+
- Debug
- AnyCPU
-
-
- 2.0
- {CFFEE5E0-3B99-46E0-9A82-2E74621C17C5}
- {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
- Library
- Properties
+ net8.0
SampleWebApp
SampleWebApp
- v4.5.1
- false
- true
-
-
-
-
-
-
-
- true
- full
- false
- bin\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\
- TRACE
- prompt
- 4
+ enable
+ disable
+
-
- False
- ..\packages\Autofac.3.5.0\lib\net40\Autofac.dll
-
-
- False
- ..\packages\Autofac.Mvc5.3.3.1\lib\net45\Autofac.Integration.Mvc.dll
-
-
- ..\packages\AutoMapper.4.2.1\lib\net45\AutoMapper.dll
- True
-
-
- ..\packages\DelegateDecompiler.0.18.0\lib\net40-Client\DelegateDecompiler.dll
- True
-
-
- ..\packages\DelegateDecompiler.EntityFramework.0.18.0\lib\net45\DelegateDecompiler.EntityFramework.dll
- True
-
-
- ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll
- True
-
-
- ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll
- True
-
-
- ..\packages\GenericLibsBase.1.0.1\lib\GenericLibsBase.dll
- True
-
-
- ..\packages\GenericServices.1.0.9\lib\GenericServices.dll
- True
-
-
- ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll
-
-
- False
- ..\packages\Microsoft.AspNet.Identity.Core.2.1.0\lib\net45\Microsoft.AspNet.Identity.Core.dll
-
-
- False
- ..\packages\Microsoft.AspNet.Identity.EntityFramework.2.1.0\lib\net45\Microsoft.AspNet.Identity.EntityFramework.dll
-
-
- False
- ..\packages\Microsoft.AspNet.Identity.Owin.2.1.0\lib\net45\Microsoft.AspNet.Identity.Owin.dll
-
-
- ..\packages\Microsoft.AspNet.SignalR.Core.2.0.3\lib\net45\Microsoft.AspNet.SignalR.Core.dll
-
-
- ..\packages\Microsoft.AspNet.SignalR.SystemWeb.2.0.3\lib\net45\Microsoft.AspNet.SignalR.SystemWeb.dll
- True
-
-
-
- False
- ..\packages\Microsoft.Owin.3.0.0\lib\net45\Microsoft.Owin.dll
-
-
- False
- ..\packages\Microsoft.Owin.Security.3.0.0\lib\net45\Microsoft.Owin.Security.dll
-
-
- False
- ..\packages\Microsoft.Owin.Security.Cookies.3.0.0\lib\net45\Microsoft.Owin.Security.Cookies.dll
-
-
- False
- ..\packages\Microsoft.Owin.Security.Facebook.3.0.0\lib\net45\Microsoft.Owin.Security.Facebook.dll
-
-
- False
- ..\packages\Microsoft.Owin.Security.Google.3.0.0\lib\net45\Microsoft.Owin.Security.Google.dll
-
-
- False
- ..\packages\Microsoft.Owin.Security.MicrosoftAccount.3.0.0\lib\net45\Microsoft.Owin.Security.MicrosoftAccount.dll
-
-
- False
- ..\packages\Microsoft.Owin.Security.OAuth.3.0.0\lib\net45\Microsoft.Owin.Security.OAuth.dll
-
-
- ..\packages\Mono.Reflection.1.0.0.0\lib\Mono.Reflection.dll
-
-
- False
- ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
-
-
-
-
-
-
-
-
-
-
-
- False
- ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll
-
-
- False
- ..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll
-
-
- False
- ..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll
-
-
- False
- ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll
-
-
- False
- ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll
-
-
- False
- ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll
-
-
-
-
-
-
-
-
-
-
-
- True
- ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll
-
-
-
-
-
-
- ..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll
-
-
- True
- ..\packages\WebGrease.1.5.2\lib\WebGrease.dll
-
-
- True
- ..\packages\Antlr.3.4.1.9004\lib\Antlr3.Runtime.dll
-
+
+
+
-
- ..\packages\Owin.1.0\lib\net40\Owin.dll
-
-
- ..\packages\Microsoft.Owin.Host.SystemWeb.2.1.0\lib\net45\Microsoft.Owin.Host.SystemWeb.dll
-
-
- ..\packages\Microsoft.Owin.Security.Twitter.2.1.0\lib\net45\Microsoft.Owin.Security.Twitter.dll
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
- Global.asax
-
-
-
-
-
-
-
-
-
-
- True
- True
- Settings.settings
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- SettingsSingleFileGenerator
- Settings.Designer.cs
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Designer
-
-
- Web.config
-
-
- Web.config
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Web.config
-
-
- Web.config
-
-
-
-
-
-
-
-
-
-
-
-
- {264e1878-12de-4099-b8d7-cc53a73fea49}
- DataLayer
-
-
- {d2813927-0f38-43c3-b47c-ae8f00d50cae}
- ServiceLayer
-
-
-
- 10.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
- bin\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
-
-
- bin\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
-
-
- bin\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
-
-
-
-
-
-
-
-
-
-
-
- True
- True
- 50623
- /
- http://localhost:50623/
- False
- False
-
-
- False
-
-
-
-
-
-
\ No newline at end of file
+
+
diff --git a/SampleWebApp/Views/Home/Internals.cshtml b/SampleWebApp/Views/Home/Internals.cshtml
index fcf3365..62f7ab8 100644
--- a/SampleWebApp/Views/Home/Internals.cshtml
+++ b/SampleWebApp/Views/Home/Internals.cshtml
@@ -1,4 +1,4 @@
-@model SampleWebApp.Models.InternalsInfo
+@model SampleWebApp.Models.InternalsInfo
InternalsInfo
@@ -20,14 +20,6 @@
@Html.DisplayFor(model => model.AvailableThreads)
-
- @Html.DisplayNameFor(model => model.AvailableMbytes)
-
-
-
- @Html.DisplayFor(model => model.AvailableMbytes)
-
-
@Html.DisplayNameFor(model => model.HeapMemoryUsedKbytes)
@@ -38,5 +30,5 @@
- @Html.ActionLink("Back to List", "Index")
+ Back to List
diff --git a/SampleWebApp/Views/Posts/Create.cshtml b/SampleWebApp/Views/Posts/Create.cshtml
index ca33689..22e5e44 100644
--- a/SampleWebApp/Views/Posts/Create.cshtml
+++ b/SampleWebApp/Views/Posts/Create.cshtml
@@ -1,4 +1,4 @@
-@model ServiceLayer.PostServices.DetailPostDto
+@model ServiceLayer.PostServices.DetailPostDto
@{
ViewBag.Title = "Create";
@@ -6,59 +6,70 @@
Create
-
-@using (Html.BeginForm())
-{
+
-@Html.Partial("PostValidation")
-
-@section Scripts {
- @Scripts.Render("~/bundles/jqueryval")
-}
+@await Html.PartialAsync("PostValidation")
diff --git a/SampleWebApp/Views/Posts/Edit.cshtml b/SampleWebApp/Views/Posts/Edit.cshtml
index 49d666f..f2de66f 100644
--- a/SampleWebApp/Views/Posts/Edit.cshtml
+++ b/SampleWebApp/Views/Posts/Edit.cshtml
@@ -1,4 +1,4 @@
-@model ServiceLayer.PostServices.DetailPostDto
+@model ServiceLayer.PostServices.DetailPostDto
@{
ViewBag.Title = "Edit";
@@ -6,46 +6,59 @@
Edit
-
-@using (Html.BeginForm())
-{
+
-@Html.Partial("PostValidation")
-
-
-@section Scripts {
- @Scripts.Render("~/bundles/jqueryval")
-}
+@await Html.PartialAsync("PostValidation")
diff --git a/SampleWebApp/Views/PostsAsync/Create.cshtml b/SampleWebApp/Views/PostsAsync/Create.cshtml
index d22f305..eebd6c6 100644
--- a/SampleWebApp/Views/PostsAsync/Create.cshtml
+++ b/SampleWebApp/Views/PostsAsync/Create.cshtml
@@ -1,4 +1,4 @@
-@model ServiceLayer.PostServices.DetailPostDtoAsync
+@model ServiceLayer.PostServices.DetailPostDtoAsync
@{
ViewBag.Title = "Create";
@@ -6,59 +6,70 @@
Create (Async)
-
-@using (Html.BeginForm())
-{
+
-@Html.Partial("PostValidation")
-
-@section Scripts {
- @Scripts.Render("~/bundles/jqueryval")
-}
+@await Html.PartialAsync("PostValidation")
diff --git a/SampleWebApp/Views/PostsAsync/Edit.cshtml b/SampleWebApp/Views/PostsAsync/Edit.cshtml
index 75b1706..c35e028 100644
--- a/SampleWebApp/Views/PostsAsync/Edit.cshtml
+++ b/SampleWebApp/Views/PostsAsync/Edit.cshtml
@@ -1,4 +1,4 @@
-@model ServiceLayer.PostServices.DetailPostDtoAsync
+@model ServiceLayer.PostServices.DetailPostDtoAsync
@{
ViewBag.Title = "Edit";
@@ -6,45 +6,59 @@
Edit (Async)
-@using (Html.BeginForm())
-{
+
-@Html.Partial("PostValidation")
-
-@section Scripts {
- @Scripts.Render("~/bundles/jqueryval")
-}
+@await Html.PartialAsync("PostValidation")
diff --git a/SampleWebApp/Views/Shared/EditorTemplates/DropDownListType.cshtml b/SampleWebApp/Views/Shared/EditorTemplates/DropDownListType.cshtml
deleted file mode 100644
index e7d6ea2..0000000
--- a/SampleWebApp/Views/Shared/EditorTemplates/DropDownListType.cshtml
+++ /dev/null
@@ -1,8 +0,0 @@
-@model ServiceLayer.UiClasses.DropDownListType
-
-@Html.DropDownListFor( x => x.SelectedValue, Model.KeyValueList.Select( x => new SelectListItem
- {
- Selected = Model.SelectedValue != null && Model.KeyValueList[0].Key == x.Key,
- Text = x.Key,
- Value = x.Value
- }))
\ No newline at end of file
diff --git a/SampleWebApp/Views/Shared/EditorTemplates/MultiSelectListType.cshtml b/SampleWebApp/Views/Shared/EditorTemplates/MultiSelectListType.cshtml
deleted file mode 100644
index b926efd..0000000
--- a/SampleWebApp/Views/Shared/EditorTemplates/MultiSelectListType.cshtml
+++ /dev/null
@@ -1,3 +0,0 @@
-@model ServiceLayer.UiClasses.MultiSelectListType
-
-@Html.ListBoxFor(m => m.FinalSelection, new MultiSelectList(Model.AllPossibleOptions, "Value", "Key", Model.InitialSelection ))
\ No newline at end of file
diff --git a/SampleWebApp/Views/Shared/Error.cshtml b/SampleWebApp/Views/Shared/Error.cshtml
index be55b17..61bf998 100644
--- a/SampleWebApp/Views/Shared/Error.cshtml
+++ b/SampleWebApp/Views/Shared/Error.cshtml
@@ -1,9 +1,6 @@
-@model System.Web.Mvc.HandleErrorInfo
-
@{
ViewBag.Title = "Error";
}
Error.
An error occurred while processing your request.
-
diff --git a/SampleWebApp/Views/Shared/PostValidation.cshtml b/SampleWebApp/Views/Shared/PostValidation.cshtml
index 0344aa3..3cf69d3 100644
--- a/SampleWebApp/Views/Shared/PostValidation.cshtml
+++ b/SampleWebApp/Views/Shared/PostValidation.cshtml
@@ -1,96 +1,19 @@
-
-
Post Validation rules
-
- To help with testing the Post data class, i.e. the one that is linked to the database, has extra rules over the DetailPostDto.
- This means that more tests are done when the database is updated, which are then caught by SaveChanges and sent back as errors.
-
-
-
Rules in both DetailPostDto and Post
-
-
- | Property |
- Validation rule |
- Where shown? |
- Where Checked* |
-
-
- | Title |
- Must have between 2 and 128 characters in it |
- By property |
- Browser,MVC,EF |
-
-
- | Title |
- Must not contain HTML symbols, e.g. <, > |
- Exception |
- MVC |
-
-
- | Content |
- Cannot be empty |
- By property |
- Browser,MVC,EF |
-
-
- | Content |
- Must not contain HTML symbols, e.g. <, > |
- Exception |
- MVC |
-
-
- | Blog (Author) |
- Must have a blogger assigned to the post |
- By property |
- DTO,EF |
-
-
- | Tags |
- Must have at least one tag assigned to the Post |
- By property |
- DTO,EF |
-
-
-
-
Rules only in Post
-
Note that these strange rules have been added to allow testing of different error conditions
-
-
- | Property |
- Validation rule |
- Where shown? |
- Where Checked* |
-
-
- | Title |
- Must not include an exclamation mark, i.e '!' |
- By property |
- EF |
-
-
- | Title |
- Must not end with a question mark, i.e '?' |
- By property |
- EF |
-
-
- | Content |
-
- A sentence must not end with the following words:
- ' sheep.', ' lamb.', ' cow.' or ' calf.'
- |
- At top |
- EF |
-
-
-
-
- Note*: The 'Where Checked' terms are
-
-
- - Browser: in browser using javascript validation library
- - MVC: by statement
if (!ModelState.IsValid) in Controller actions
- - EF: by Entity Framework validation phase
- - DTO: By the code inside the DetailPostDto class
-
-
The test for HTML symbols is done by MVC and throws an exception, which in the release version goes to the default error page.
-
+Post Validations
+To test the validations try the following:
+
+ -
+ Title: Must be 2 to 128 characters.
+
+ -
+ Content: Required.
+
+ -
+ Title with trailing '!': The Post entity has a validation rule that does not allow Titles ending with '!'.
+
+ -
+ Blogger: A blogger must be selected.
+
+ -
+ Tags: At least one tag must be selected.
+
+
diff --git a/SampleWebApp/Views/Shared/TagValidation.cshtml b/SampleWebApp/Views/Shared/TagValidation.cshtml
index 8eb991c..28b9f8b 100644
--- a/SampleWebApp/Views/Shared/TagValidation.cshtml
+++ b/SampleWebApp/Views/Shared/TagValidation.cshtml
@@ -1,76 +1,13 @@
-
-
Tag Validation rules
-
- The Tag data class, i.e. the one that is linked to the database, a number of validation rules,
- including one that is checked inside the EF SaveChanges.
-
-
-
Validation rules in Tag class, and inside EF SaveChanges
-
-
- | Property |
- Validation rule |
- Where shown? |
- Where Checked* |
-
-
- | Name |
- Must not be empty |
- By property |
- Browser,MVC,EF |
-
-
- | Name |
- Must not be longer than 128 characters |
- By property |
- Browser,MVC,EF |
-
-
- | Name |
- Must not contain HTML symbols, e.g. <, > |
- Exception |
- MVC |
-
-
- | Slug |
- Must not be empty |
- By property |
- Browser,MVC,EF |
-
-
- | Slug |
- Must not be longer than 128 characters |
- By property |
- Browser,MVC,EF |
-
-
- | Slug |
- Must not be empty |
- By property |
- Browser,MVC,EF |
-
-
- | Slug |
- Must not contain spaces or non-alphanumeric characters |
- By property |
- MVC,EF |
-
-
- | Slug |
- Must be unique, i.e. must not exist in any other tag entry in the database |
- By property |
- SaveChanges |
-
-
-
-
- Note*: The 'Where Checked' terms are
-
-
- - Browser: in browser using javascript validation library
- - MVC: by statement
if (!ModelState.IsValid) in Controller actions
- - EF: by Entity Framework validation phase
- - SaveChanges: Special validaton code added to EF's SaveChanges
-
-
The test for HTML symbols is done by MVC and throws an exception, which in the release version goes to the default error page.
-
\ No newline at end of file
+Tag Validations
+To test the validations try the following:
+
+ -
+ Name: Required, max 128 characters.
+
+ -
+ Slug: Required, max 64 characters, must be alphanumeric only (no spaces or special characters).
+
+ -
+ Duplicate Slug: Each tag must have a unique slug.
+
+
diff --git a/SampleWebApp/Views/Shared/_Layout.cshtml b/SampleWebApp/Views/Shared/_Layout.cshtml
index 345fd91..9cfc644 100644
--- a/SampleWebApp/Views/Shared/_Layout.cshtml
+++ b/SampleWebApp/Views/Shared/_Layout.cshtml
@@ -1,12 +1,11 @@
-@using SampleWebApp.Infrastructure
@ViewBag.Title - SampleMvcWebApp
- @Styles.Render("~/Content/css")
-
+
+
@@ -17,44 +16,42 @@
- @*@Html.ActionLink("Example web app", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })*@
- @*@Html.Partial("_LoginPartial")*@
@RenderBody()
-
- @Scripts.Render("~/bundles/javascript")
- @RenderSection("scripts", required: false)
+
+
+ @await RenderSectionAsync("Scripts", required: false)
diff --git a/SampleWebApp/Views/Tags/Create.cshtml b/SampleWebApp/Views/Tags/Create.cshtml
index 216fd78..9fd1dac 100644
--- a/SampleWebApp/Views/Tags/Create.cshtml
+++ b/SampleWebApp/Views/Tags/Create.cshtml
@@ -1,4 +1,4 @@
-@model DataLayer.DataClasses.Concrete.Tag
+@model DataLayer.DataClasses.Concrete.Tag
@{
ViewBag.Title = "Create";
@@ -43,4 +43,4 @@
@Html.ActionLink("Back to List", "Index")
-@Html.Partial("TagValidation")
+@await Html.PartialAsync("TagValidation")
diff --git a/SampleWebApp/Views/Tags/Edit.cshtml b/SampleWebApp/Views/Tags/Edit.cshtml
index baab41e..26a41f9 100644
--- a/SampleWebApp/Views/Tags/Edit.cshtml
+++ b/SampleWebApp/Views/Tags/Edit.cshtml
@@ -1,4 +1,4 @@
-@model DataLayer.DataClasses.Concrete.Tag
+@model DataLayer.DataClasses.Concrete.Tag
@{
ViewBag.Title = "Edit";
@@ -44,4 +44,4 @@
@Html.ActionLink("Back to List", "Index")
-@Html.Partial("TagValidation")
+@await Html.PartialAsync("TagValidation")
diff --git a/SampleWebApp/Views/TagsAsync/Create.cshtml b/SampleWebApp/Views/TagsAsync/Create.cshtml
index 84783db..2ee56b8 100644
--- a/SampleWebApp/Views/TagsAsync/Create.cshtml
+++ b/SampleWebApp/Views/TagsAsync/Create.cshtml
@@ -1,4 +1,4 @@
-@model DataLayer.DataClasses.Concrete.Tag
+@model DataLayer.DataClasses.Concrete.Tag
@{
ViewBag.Title = "Create";
@@ -43,4 +43,4 @@
@Html.ActionLink("Back to List", "Index")
-@Html.Partial("TagValidation")
+@await Html.PartialAsync("TagValidation")
diff --git a/SampleWebApp/Views/TagsAsync/Edit.cshtml b/SampleWebApp/Views/TagsAsync/Edit.cshtml
index 3f41685..e8c04bd 100644
--- a/SampleWebApp/Views/TagsAsync/Edit.cshtml
+++ b/SampleWebApp/Views/TagsAsync/Edit.cshtml
@@ -1,4 +1,4 @@
-@model DataLayer.DataClasses.Concrete.Tag
+@model DataLayer.DataClasses.Concrete.Tag
@{
ViewBag.Title = "Edit";
@@ -44,4 +44,4 @@
@Html.ActionLink("Back to List", "Index")
-@Html.Partial("TagValidation")
+@await Html.PartialAsync("TagValidation")
diff --git a/SampleWebApp/Views/Web.config b/SampleWebApp/Views/Web.config
deleted file mode 100644
index ba26898..0000000
--- a/SampleWebApp/Views/Web.config
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/SampleWebApp/Views/_ViewImports.cshtml b/SampleWebApp/Views/_ViewImports.cshtml
new file mode 100644
index 0000000..a1023a1
--- /dev/null
+++ b/SampleWebApp/Views/_ViewImports.cshtml
@@ -0,0 +1,7 @@
+@using SampleWebApp
+@using DataLayer.DataClasses.Concrete
+@using ServiceLayer.PostServices
+@using ServiceLayer.BlogServices
+@using ServiceLayer.TagServices
+@using ServiceLayer.UiClasses
+@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
diff --git a/SampleWebApp/Views/_ViewStart.cshtml b/SampleWebApp/Views/_ViewStart.cshtml
index 2de6241..820a2f6 100644
--- a/SampleWebApp/Views/_ViewStart.cshtml
+++ b/SampleWebApp/Views/_ViewStart.cshtml
@@ -1,3 +1,3 @@
-@{
- Layout = "~/Views/Shared/_Layout.cshtml";
+@{
+ Layout = "_Layout";
}
diff --git a/SampleWebApp/Web.Debug.config b/SampleWebApp/Web.Debug.config
deleted file mode 100644
index 680849f..0000000
--- a/SampleWebApp/Web.Debug.config
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/SampleWebApp/Web.Release.config b/SampleWebApp/Web.Release.config
deleted file mode 100644
index 943c9c0..0000000
--- a/SampleWebApp/Web.Release.config
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/SampleWebApp/Web.config b/SampleWebApp/Web.config
deleted file mode 100644
index 02309cc..0000000
--- a/SampleWebApp/Web.config
+++ /dev/null
@@ -1,110 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- LocalHost
-
-
- jonsmith_
-
-
-
-
\ No newline at end of file
diff --git a/SampleWebApp/appsettings.Development.json b/SampleWebApp/appsettings.Development.json
new file mode 100644
index 0000000..ce2b527
--- /dev/null
+++ b/SampleWebApp/appsettings.Development.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning",
+ "Microsoft.EntityFrameworkCore": "Information"
+ }
+ }
+}
diff --git a/SampleWebApp/appsettings.json b/SampleWebApp/appsettings.json
new file mode 100644
index 0000000..e964d99
--- /dev/null
+++ b/SampleWebApp/appsettings.json
@@ -0,0 +1,13 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning",
+ "Microsoft.EntityFrameworkCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*",
+ "ConnectionStrings": {
+ "DefaultConnection": "Data Source=SampleWebApp.db"
+ }
+}
diff --git a/SampleWebApp/packages.config b/SampleWebApp/packages.config
deleted file mode 100644
index bc278c0..0000000
--- a/SampleWebApp/packages.config
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/SampleWebApp/wwwroot/css/site.css b/SampleWebApp/wwwroot/css/site.css
new file mode 100644
index 0000000..d66ce7a
--- /dev/null
+++ b/SampleWebApp/wwwroot/css/site.css
@@ -0,0 +1,23 @@
+body {
+ padding-top: 50px;
+ padding-bottom: 20px;
+}
+
+/* Set padding to keep content from hitting the edges */
+.body-content {
+ padding-left: 15px;
+ padding-right: 15px;
+}
+
+/* Override the default bootstrap behavior where horizontal description lists
+ will truncate terms that are too long to fit in the left column */
+.dl-horizontal dt {
+ white-space: normal;
+}
+
+/* Set width on the form input elements since they're 100% wide by default */
+input,
+select,
+textarea {
+ max-width: 280px;
+}
diff --git a/ServiceLayer/App.config b/ServiceLayer/App.config
deleted file mode 100644
index dac3ee5..0000000
--- a/ServiceLayer/App.config
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/ServiceLayer/BlogServices/BlogListDto.cs b/ServiceLayer/BlogServices/BlogListDto.cs
index c50f8e8..09f51fa 100644
--- a/ServiceLayer/BlogServices/BlogListDto.cs
+++ b/ServiceLayer/BlogServices/BlogListDto.cs
@@ -1,4 +1,4 @@
-#region licence
+#region licence
// The MIT License (MIT)
//
// Filename: BlogListDto.cs
@@ -24,19 +24,12 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#endregion
-
using System.ComponentModel.DataAnnotations;
-using System.Runtime.CompilerServices;
-using DataLayer.DataClasses.Concrete;
-using GenericServices.Core;
-
-[assembly: InternalsVisibleTo("Tests")]
namespace ServiceLayer.BlogServices
{
- public class BlogListDto : EfGenericDto
+ public class BlogListDto
{
-
[UIHint("HiddenInput")]
[Key]
public int BlogId { get; set; }
@@ -46,14 +39,6 @@ public class BlogListDto : EfGenericDto
[EmailAddress]
public string EmailAddress { get; set; }
- public int PostsCount { get; set; } //Uses AutoMapper Aggregate
-
- //----------------------------------------------
- //overridden properties or methods
-
- protected override CrudFunctions SupportedFunctions
- {
- get { return CrudFunctions.List; }
- }
+ public int PostsCount { get; set; }
}
}
diff --git a/ServiceLayer/PostServices/DetailPostDto.cs b/ServiceLayer/PostServices/DetailPostDto.cs
index 2cdc60d..a7f3a0e 100644
--- a/ServiceLayer/PostServices/DetailPostDto.cs
+++ b/ServiceLayer/PostServices/DetailPostDto.cs
@@ -1,4 +1,4 @@
-#region licence
+#region licence
// The MIT License (MIT)
//
// Filename: DetailPostDto.cs
@@ -28,22 +28,13 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
-using System.Runtime.CompilerServices;
-using DataLayer.DataClasses;
using DataLayer.DataClasses.Concrete;
-using GenericLibsBase;
-using GenericLibsBase.Core;
-using GenericServices;
-using GenericServices.Core;
using ServiceLayer.UiClasses;
-[assembly: InternalsVisibleTo("Tests")]
-
namespace ServiceLayer.PostServices
{
- public class DetailPostDto : EfGenericDto
+ public class DetailPostDto
{
-
[UIHint("HiddenInput")]
[Key]
public int PostId { get; set; }
@@ -55,28 +46,17 @@ public class DetailPostDto : EfGenericDto
[Required]
public string Content { get; set; }
- //AutoMapper understands that this means Blogger.Name and fills it with the Name of the Blogger
public string BloggerName { get; set; }
- //-------------------------------------------
- //properties that cannot be set directly (The data layer looks after them)
-
[ScaffoldColumn(false)]
- [DoNotCopyBackToDatabase]
public DateTime LastUpdated { get; set; }
- //------------------------------------------
- //these two items are altered by the SetupRestOfDto method based on the user's selection
-
[UIHint("HiddenInput")]
public int BlogId { get; set; }
[ScaffoldColumn(false)]
public ICollection Tags { get; set; }
- //-------------------------------------------
- //now the various lists for user interaction
-
///
/// This allows a single blogger to be chosen from the list
///
@@ -84,136 +64,18 @@ public class DetailPostDto : EfGenericDto
public MultiSelectListType UserChosenTags { get; set; }
- //-------------------------------------------
- //calculated properties to help display
- //(Note: SampleMvcWebApp was written before calculated properties using [Computed] was added to GenericServices.
- //see https://github.com/JonPSmith/GenericServices/wiki/Calculated-properties for a better way of doing this
-
///
/// When it was last updated in DateTime format
///
public DateTime LastUpdatedUtc { get { return DateTime.SpecifyKind(LastUpdated, DateTimeKind.Utc); } }
- public string TagNames { get { return string.Join(", ", Tags.Select(x => x.Name)); } }
+ public string TagNames { get { return Tags != null ? string.Join(", ", Tags.Select(x => x.Name)) : ""; } }
- //ctor
public DetailPostDto()
{
+ Tags = new List();
Bloggers = new DropDownListType();
UserChosenTags = new MultiSelectListType();
}
-
- //----------------------------------------------
- //overridden methods
-
- protected override CrudFunctions SupportedFunctions
- {
- get { return CrudFunctions.AllCrud; }
- }
-
- ///
- /// This sets up the dropdownlist for the possible bloggers and the MultiSelectList of tags
- ///
- ///
- ///
- protected override void SetupSecondaryData(IGenericServicesDbContext context, DetailPostDto dto)
- {
-
- dto.Bloggers.SetupDropDownListContent(
- context.Set()
- .ToList()
- .Select(x => new KeyValuePair(x.Name, x.BlogId.ToString("D"))),
- "--- choose blogger ---");
- if (dto.PostId != 0)
- //there is an entry, so set the selected value to that
- dto.Bloggers.SetSelectedValue(dto.BlogId.ToString("D"));
-
- var preselectedTags = dto.PostId == 0
- ? new List>() //Create, so no tags selected yet
- : Tags
- .Select(x => new { Key = x.Name, Value = x.TagId })
- .ToList()
- .Select(x => new KeyValuePair(x.Key, x.Value))
- .ToList();
- dto.UserChosenTags.SetupMultiSelectList(
- context.Set().ToList().Select(x => new KeyValuePair(x.Name, x.TagId)), preselectedTags);
- }
-
- protected override ISuccessOrErrors CreateDataFromDto(IGenericServicesDbContext context, DetailPostDto source)
- {
- var status = SetupRestOfDto(context);
-
- return status.IsValid
- ? base.CreateDataFromDto(context, this)
- : SuccessOrErrors.ConvertNonResultStatus(status);
- }
-
- protected override ISuccessOrErrors UpdateDataFromDto(IGenericServicesDbContext context, DetailPostDto source, Post destination)
- {
- var status = SetupRestOfDto(context, destination);
-
- return status.IsValid
- ? base.UpdateDataFromDto(context, this, destination)
- : status;
- }
-
- //---------------------------------------------------
- //private helpers
-
- private ISuccessOrErrors SetupRestOfDto(IGenericServicesDbContext context, Post post = null)
- {
-
- var db = context as SampleWebAppDb;
- if (db == null)
- throw new NullReferenceException("The IDbContextWithValidation must be linked to TemplateWebAppDb.");
-
- var status = SuccessOrErrors.Success("OK if no errors set");
-
- //now we sort out the blogger
- var errMsg = SetBloggerIdFromDropDownList(db);
- if (errMsg != null)
- status.AddNamedParameterError("Bloggers", errMsg);
-
- //now we sort out the tags
- errMsg = ChangeTagsBasedOnMultiSelectList(db, post);
- if (errMsg != null)
- status.AddNamedParameterError("UserChosenTags", errMsg);
-
- return status;
- }
-
- private string SetBloggerIdFromDropDownList(SampleWebAppDb db)
- {
-
- var blogId = Bloggers.SelectedValueAsInt;
- if (blogId == null)
- return "The blogger was not selected. You must do that before the post can be saved.";
-
- var blogger = db.Blogs.Find((int)blogId);
- if (blogger == null)
- return "Could not find the blogger you selected. Did another user delete it?";
-
- BlogId = (int)blogId; //will be copied over to database entity by AutoMapper
- return null;
- }
-
- private string ChangeTagsBasedOnMultiSelectList(SampleWebAppDb db, Post post = null)
- {
- var requiredTagIds = UserChosenTags.GetFinalSelectionAsInts();
- if (!requiredTagIds.Any())
- return "You must select at least one tag for the post.";
-
- if (requiredTagIds.Any(x => db.Tags.Find(x) == null))
- return "Could not find one of the tags. Did another user delete it?";
-
- if (post != null)
- //This is an update so we need to load the tags
- db.Entry(post).Collection(p => p.Tags).Load();
-
- var newTagsForPost = db.Tags.Where(x => requiredTagIds.Contains(x.TagId)).ToList();
- Tags = newTagsForPost; //will be copied over to database entity by AutoMapper
-
- return null;
- }
}
}
diff --git a/ServiceLayer/PostServices/DetailPostDtoAsync.cs b/ServiceLayer/PostServices/DetailPostDtoAsync.cs
index dd27b14..fc55c4f 100644
--- a/ServiceLayer/PostServices/DetailPostDtoAsync.cs
+++ b/ServiceLayer/PostServices/DetailPostDtoAsync.cs
@@ -1,4 +1,4 @@
-#region licence
+#region licence
// The MIT License (MIT)
//
// Filename: DetailPostDtoAsync.cs
@@ -27,25 +27,14 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
-using System.Data.Entity;
using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Threading.Tasks;
-using DataLayer.DataClasses;
using DataLayer.DataClasses.Concrete;
-using GenericLibsBase;
-using GenericLibsBase.Core;
-using GenericServices;
-using GenericServices.Core;
using ServiceLayer.UiClasses;
-[assembly: InternalsVisibleTo("Tests")]
-
namespace ServiceLayer.PostServices
{
- public class DetailPostDtoAsync : EfGenericDtoAsync
+ public class DetailPostDtoAsync
{
-
[UIHint("HiddenInput")]
[Key]
public int PostId { get; set; }
@@ -57,27 +46,16 @@ public class DetailPostDtoAsync : EfGenericDtoAsync
[Required]
public string Content { get; set; }
- //AutoMapper understands that this means Blogger.Name and fills it with the Name of the Blogger
public string BloggerName { get; set; }
- //-------------------------------------------
- //properties that cannot be set directly (The data layer looks after them)
-
[ScaffoldColumn(false)]
- [DoNotCopyBackToDatabase]
public DateTime LastUpdated { get; set; }
- //------------------------------------------
- //these two items are altered by the SetupRestOfDto method based on the user's selection
-
[UIHint("HiddenInput")]
public int BlogId { get; set; }
[ScaffoldColumn(false)]
- public ICollection Tags { get; set; } //this must be copied back
-
- //-------------------------------------------
- //now the various lists for user interaction
+ public ICollection Tags { get; set; }
///
/// This allows a single blogger to be chosen from the list
@@ -86,138 +64,18 @@ public class DetailPostDtoAsync : EfGenericDtoAsync
public MultiSelectListType UserChosenTags { get; set; }
- //-------------------------------------------
- //calculated properties to help display
- //(Note: SampleMvcWebApp was written before calculated properties using [Computed] was added to GenericServices.
- //see https://github.com/JonPSmith/GenericServices/wiki/Calculated-properties for a better way of doing this
-
///
/// When it was last updated in DateTime format
///
public DateTime LastUpdatedUtc { get { return DateTime.SpecifyKind(LastUpdated, DateTimeKind.Utc); } }
- public string TagNames { get { return string.Join(", ", Tags.Select(x => x.Name)); } }
+ public string TagNames { get { return Tags != null ? string.Join(", ", Tags.Select(x => x.Name)) : ""; } }
- //ctor
public DetailPostDtoAsync()
{
+ Tags = new List();
Bloggers = new DropDownListType();
UserChosenTags = new MultiSelectListType();
}
-
-
- //----------------------------------------------
- //overridden methods
-
- protected override CrudFunctions SupportedFunctions
- {
- get { return CrudFunctions.AllCrud; }
- }
-
- ///
- /// This sets up the dropdownlist for the possible bloggers and the MultiSelectList of tags
- ///
- ///
- ///
- protected override async Task SetupSecondaryDataAsync(IGenericServicesDbContext context, DetailPostDtoAsync dto)
- {
-
- var bloggers = await context.Set().ToListAsync();
-
- dto.Bloggers.SetupDropDownListContent(bloggers.Select(x => new KeyValuePair(x.Name, x.BlogId.ToString("D"))),
- "--- choose blogger ---");
- if (dto.PostId != 0)
- //there is an entry, so set the selected value to that
- dto.Bloggers.SetSelectedValue(dto.BlogId.ToString("D"));
-
- var preselectedTags = dto.PostId == 0
- ? new List>() //Create, so no tags selected yet
- : Tags
- .Select(x => new { Key = x.Name, Value = x.TagId })
- .ToList()
- .Select(x => new KeyValuePair(x.Key, x.Value))
- .ToList();
- dto.UserChosenTags.SetupMultiSelectList(
- context.Set().ToList().Select(x => new KeyValuePair(x.Name, x.TagId)), preselectedTags);
- }
-
-
- protected override async Task> CreateDataFromDtoAsync(IGenericServicesDbContext context, DetailPostDtoAsync source)
- {
- var status = await SetupRestOfDto(context);
-
- return status.IsValid
- ? await base.CreateDataFromDtoAsync(context, this)
- : SuccessOrErrors.ConvertNonResultStatus(status);
- }
-
- protected override async Task UpdateDataFromDtoAsync(IGenericServicesDbContext context, DetailPostDtoAsync source, Post destination)
- {
- var status = await SetupRestOfDto(context, destination);
-
- return status.IsValid
- ? await base.UpdateDataFromDtoAsync(context, this, destination)
- : status;
- }
-
- private async Task SetupRestOfDto(IGenericServicesDbContext context, Post post = null)
- {
-
- var db = context as SampleWebAppDb;
- if (db == null)
- throw new NullReferenceException("The IDbContextWithValidation must be linked to TemplateWebAppDb.");
-
- var status = SuccessOrErrors.Success("OK if no errors set");
-
- //now we sort out the blogger
- var errMsg = await SetupBloggerIdFromDropDownList(db, post);
- if (errMsg != null)
- status.AddNamedParameterError("Bloggers", errMsg);
-
- //now we sort out the tags
- errMsg = await ChangeTagsBasedOnMultiSelectList(db, post);
- if (errMsg != null)
- status.AddNamedParameterError("UserChosenTags", errMsg);
-
- return status;
- }
-
-
- //---------------------------------------------------
- //private helpers
-
- private async Task SetupBloggerIdFromDropDownList(SampleWebAppDb db, Post post)
- {
-
- var blogId = Bloggers.SelectedValueAsInt;
- if (blogId == null)
- return "The blogger was not selected. You must do that before the post can be saved.";
-
- var blogger = await db.Blogs.FindAsync((int)blogId);
- if (blogger == null)
- return "Could not find the blogger you selected. Did another user delete it?";
-
- BlogId = (int)blogId;
- return null;
- }
-
- private async Task ChangeTagsBasedOnMultiSelectList(SampleWebAppDb db, Post post)
- {
- var requiredTagIds = UserChosenTags.GetFinalSelectionAsInts();
- if (!requiredTagIds.Any())
- return "You must select at least one tag for the post.";
-
- if (requiredTagIds.Any(x => db.Tags.Find(x) == null))
- return "Could not find one of the tags. Did another user delete it?";
-
- if (post != null)
- //This is an update so we need to load the tags
- db.Entry(post).Collection(p => p.Tags).Load();
-
- var newTagsForPost = await db.Tags.Where(x => requiredTagIds.Contains(x.TagId)).ToListAsync();
- Tags = newTagsForPost; //will be copied over by copyDtoToData
-
- return null;
- }
}
}
diff --git a/ServiceLayer/PostServices/SimplePostDto.cs b/ServiceLayer/PostServices/SimplePostDto.cs
index 3a664bc..60a4bd0 100644
--- a/ServiceLayer/PostServices/SimplePostDto.cs
+++ b/ServiceLayer/PostServices/SimplePostDto.cs
@@ -1,4 +1,4 @@
-#region licence
+#region licence
// The MIT License (MIT)
//
// Filename: SimplePostDto.cs
@@ -28,49 +28,33 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
-using System.Runtime.CompilerServices;
-using DataLayer.DataClasses.Concrete;
-using GenericServices;
-using GenericServices.Core;
-
-[assembly: InternalsVisibleTo("Tests")]
namespace ServiceLayer.PostServices
{
- public class SimplePostDto : EfGenericDto
+ public class SimplePostDto
{
-
[UIHint("HiddenInput")]
[Key]
public int PostId { get; set; }
[UIHint("HiddenInput")]
- public int BlogId { get; set; }
+ public int BlogId { get; set; }
- public string BloggerName { get; set; }
+ public string BloggerName { get; set; }
[MinLength(2), MaxLength(128)]
public string Title { get; set; }
- [ScaffoldColumn(false)]
- public ICollection Tags { get; set; }
+ public List TagNamesList { get; set; } = new List();
[ScaffoldColumn(false)]
- public DateTime LastUpdated { get; set; }
+ public DateTime LastUpdated { get; set; }
///
/// When it was last updated in DateTime format
///
public DateTime LastUpdatedUtc { get { return DateTime.SpecifyKind(LastUpdated, DateTimeKind.Utc); } }
- public string TagNames { get { return string.Join(", ", Tags.Select(x => x.Name)); } }
-
- //----------------------------------------------
- //overridden properties or methods
-
- protected override CrudFunctions SupportedFunctions
- {
- get { return CrudFunctions.List; }
- }
+ public string TagNames { get { return string.Join(", ", TagNamesList); } }
}
}
diff --git a/ServiceLayer/PostServices/SimplePostDtoAsync.cs b/ServiceLayer/PostServices/SimplePostDtoAsync.cs
index f19d434..4495142 100644
--- a/ServiceLayer/PostServices/SimplePostDtoAsync.cs
+++ b/ServiceLayer/PostServices/SimplePostDtoAsync.cs
@@ -1,4 +1,4 @@
-#region licence
+#region licence
// The MIT License (MIT)
//
// Filename: SimplePostDtoAsync.cs
@@ -28,17 +28,11 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
-using System.Runtime.CompilerServices;
-using DataLayer.DataClasses.Concrete;
-using GenericServices.Core;
-
-[assembly: InternalsVisibleTo("Tests")]
namespace ServiceLayer.PostServices
{
- public class SimplePostDtoAsync : EfGenericDtoAsync
+ public class SimplePostDtoAsync
{
-
[UIHint("HiddenInput")]
[Key]
public int PostId { get; set; }
@@ -48,8 +42,7 @@ public class SimplePostDtoAsync : EfGenericDtoAsync
[MinLength(2), MaxLength(128)]
public string Title { get; set; }
- [ScaffoldColumn(false)]
- public ICollection Tags { get; set; }
+ public List TagNamesList { get; set; } = new List();
[ScaffoldColumn(false)]
public DateTime LastUpdated { get; set; }
@@ -59,14 +52,6 @@ public class SimplePostDtoAsync : EfGenericDtoAsync
///
public DateTime LastUpdatedUtc { get { return DateTime.SpecifyKind(LastUpdated, DateTimeKind.Utc); } }
- public string TagNames { get { return string.Join(", ", Tags.Select(x => x.Name)); } }
-
- //----------------------------------------------
- //overridden properties or methods
-
- protected override CrudFunctions SupportedFunctions
- {
- get { return CrudFunctions.List; }
- }
+ public string TagNames { get { return string.Join(", ", TagNamesList); } }
}
}
diff --git a/ServiceLayer/Properties/AssemblyInfo.cs b/ServiceLayer/Properties/AssemblyInfo.cs
deleted file mode 100644
index 2793a90..0000000
--- a/ServiceLayer/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-#region licence
-// The MIT License (MIT)
-//
-// Filename: AssemblyInfo.cs
-// Date Created: 2014/05/20
-//
-// Copyright (c) 2014 Jon Smith (www.selectiveanalytics.com & www.thereformedprogrammer.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-#endregion
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("ServiceLayer")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ServiceLayer")]
-[assembly: AssemblyCopyright("Copyright © 2014")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("35097f07-8bb1-4da4-ab04-7b4ac4894e18")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/ServiceLayer/ServiceLayer.csproj b/ServiceLayer/ServiceLayer.csproj
index 09244c2..a00358a 100644
--- a/ServiceLayer/ServiceLayer.csproj
+++ b/ServiceLayer/ServiceLayer.csproj
@@ -1,136 +1,19 @@
-
-
-
+
+
- Debug
- AnyCPU
- {D2813927-0F38-43C3-B47C-AE8F00D50CAE}
- Library
- Properties
+ net8.0
ServiceLayer
ServiceLayer
- v4.5.1
- 512
+ disable
+ disable
-
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
- bin\ReleaseAzure\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
-
-
- bin\AzureRelease\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
-
-
- bin\WebWizRelease\
- TRACE
- true
- pdbonly
- AnyCPU
- prompt
- MinimumRecommendedRules.ruleset
-
-
-
- False
- ..\packages\Autofac.3.5.0\lib\net40\Autofac.dll
-
-
- ..\packages\AutoMapper.4.2.1\lib\net45\AutoMapper.dll
- True
-
-
- ..\packages\DelegateDecompiler.0.18.0\lib\net40-Client\DelegateDecompiler.dll
- True
-
-
- ..\packages\DelegateDecompiler.EntityFramework.0.18.0\lib\net45\DelegateDecompiler.EntityFramework.dll
- True
-
-
- ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll
- True
-
-
- ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll
- True
-
-
- ..\packages\GenericLibsBase.1.0.1\lib\GenericLibsBase.dll
- True
-
-
- ..\packages\GenericServices.1.0.9\lib\GenericServices.dll
- True
-
-
- ..\packages\Mono.Reflection.1.0.0.0\lib\Mono.Reflection.dll
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
+
-
+
-
- {264e1878-12de-4099-b8d7-cc53a73fea49}
- DataLayer
-
+
-
-
-
\ No newline at end of file
+
+
diff --git a/ServiceLayer/Startup/ServiceLayerInitialise.cs b/ServiceLayer/Startup/ServiceLayerInitialise.cs
index 5fe79ef..58fd605 100644
--- a/ServiceLayer/Startup/ServiceLayerInitialise.cs
+++ b/ServiceLayer/Startup/ServiceLayerInitialise.cs
@@ -1,8 +1,8 @@
-#region licence
+#region licence
// The MIT License (MIT)
//
// Filename: ServiceLayerInitialise.cs
-// Date Created: 2014/05/20
+// Date Created: 2014/06/09
//
// Copyright (c) 2014 Jon Smith (www.selectiveanalytics.com & www.thereformedprogrammer.net)
//
@@ -24,32 +24,16 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#endregion
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
using DataLayer.Startup;
-
+using Microsoft.Extensions.Logging;
namespace ServiceLayer.Startup
{
- ///
- /// This handles the initialisation of this layer and any other layers
- ///
public static class ServiceLayerInitialise
{
- ///
- /// This should be called at Startup
- ///
- /// true if working with azure database
- /// true if the database provider allows the app to drop/create a database
- public static void InitialiseThis(bool isAzure, bool canCreateDatabase)
+ public static void InitialiseThis(ILoggerFactory loggerFactory = null)
{
-
- //Place any tasks that need initialising here
-
- DataLayerInitialise.InitialiseThis(isAzure, canCreateDatabase);
-
+ DataLayerInitialise.InitialiseThis(loggerFactory);
}
}
}
diff --git a/ServiceLayer/Startup/ServiceLayerModule.cs b/ServiceLayer/Startup/ServiceLayerModule.cs
deleted file mode 100644
index 39b40ef..0000000
--- a/ServiceLayer/Startup/ServiceLayerModule.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-#region licence
-// The MIT License (MIT)
-//
-// Filename: ServiceLayerModule.cs
-// Date Created: 2014/05/20
-//
-// Copyright (c) 2014 Jon Smith (www.selectiveanalytics.com & www.thereformedprogrammer.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-#endregion
-
-using Autofac;
-using DataLayer.Startup;
-using GenericServices;
-
-namespace ServiceLayer.Startup
-{
- public class ServiceLayerModule : Module
- {
-
- ///
- /// This registers all items in service layer and below
- ///
- ///
- protected override void Load(ContainerBuilder builder)
- {
-
- //Now register the DataLayer
- builder.RegisterModule(new DataLayerModule());
-
- //---------------------------
- //Register service layer: autowire all
- builder.RegisterAssemblyTypes(GetType().Assembly).AsImplementedInterfaces();
-
- //and register the GenericServices assembly
- builder.RegisterAssemblyTypes(typeof(IListService).Assembly).AsImplementedInterfaces();
-
- }
-
- }
-}
diff --git a/ServiceLayer/Startup/ServiceLayerServiceCollectionExtensions.cs b/ServiceLayer/Startup/ServiceLayerServiceCollectionExtensions.cs
new file mode 100644
index 0000000..1640754
--- /dev/null
+++ b/ServiceLayer/Startup/ServiceLayerServiceCollectionExtensions.cs
@@ -0,0 +1,16 @@
+using DataLayer.Startup;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace ServiceLayer.Startup
+{
+ public static class ServiceLayerServiceCollectionExtensions
+ {
+ public static IServiceCollection AddServiceLayer(this IServiceCollection services, string connectionString)
+ {
+ // Register data layer services
+ services.AddDataLayer(connectionString);
+
+ return services;
+ }
+ }
+}
diff --git a/ServiceLayer/TagServices/TagListDto.cs b/ServiceLayer/TagServices/TagListDto.cs
index efd0496..5d12491 100644
--- a/ServiceLayer/TagServices/TagListDto.cs
+++ b/ServiceLayer/TagServices/TagListDto.cs
@@ -1,4 +1,4 @@
-#region licence
+#region licence
// The MIT License (MIT)
//
// Filename: TagListDto.cs
@@ -24,19 +24,12 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#endregion
-
using System.ComponentModel.DataAnnotations;
-using System.Runtime.CompilerServices;
-using DataLayer.DataClasses.Concrete;
-using GenericServices.Core;
-
-[assembly: InternalsVisibleTo("Tests")]
namespace ServiceLayer.TagServices
{
- public class TagListDto : EfGenericDto
+ public class TagListDto
{
-
[UIHint("HiddenInput")]
[Key]
public int TagId { get; set; }
@@ -45,14 +38,6 @@ public class TagListDto : EfGenericDto
public string Slug { get; set; }
- public int PostsCount { get; set; } //uses AutoMapper Aggregate
-
- //----------------------------------------------
- //overridden properties or methods
-
- protected override CrudFunctions SupportedFunctions
- {
- get { return CrudFunctions.List; }
- }
+ public int PostsCount { get; set; }
}
}
diff --git a/ServiceLayer/packages.config b/ServiceLayer/packages.config
deleted file mode 100644
index 9c06c52..0000000
--- a/ServiceLayer/packages.config
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Tests/App.config b/Tests/App.config
deleted file mode 100644
index 875486b..0000000
--- a/Tests/App.config
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- jonsmith_
-
-
-
-
\ No newline at end of file
diff --git a/Tests/Properties/AssemblyInfo.cs b/Tests/Properties/AssemblyInfo.cs
deleted file mode 100644
index b722a8d..0000000
--- a/Tests/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-#region licence
-// The MIT License (MIT)
-//
-// Filename: AssemblyInfo.cs
-// Date Created: 2014/05/20
-//
-// Copyright (c) 2014 Jon Smith (www.selectiveanalytics.com & www.thereformedprogrammer.net)
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-#endregion
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Tests")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Tests")]
-[assembly: AssemblyCopyright("Copyright © 2014")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("edff866f-292e-46db-9cdf-74c70d23322d")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Tests/packages.config b/Tests/packages.config
deleted file mode 100644
index 1638b50..0000000
--- a/Tests/packages.config
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file