diff --git a/X.PagedList.sln b/X.PagedList.sln index 3fe570f5..9d154cf2 100644 --- a/X.PagedList.sln +++ b/X.PagedList.sln @@ -15,7 +15,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "X.PagedList.Mvc.Core", "src EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "X.PagedList.Tests", "tests\X.PagedList.Tests\X.PagedList.Tests.csproj", "{C78B1316-1EF9-45C3-A3FD-9A131BA3DD62}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "X.PagedList.Mvc.Example.Core", "examples\X.PagedList.Mvc.Example.Core\X.PagedList.Mvc.Example.Core.csproj", "{288F5726-904F-48B8-8363-EA1A22D331D1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example.Website", "examples\Example.Website\Example.Website.csproj", "{288F5726-904F-48B8-8363-EA1A22D331D1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example.DAL", "examples\Example.DAL\Example.DAL.csproj", "{AD16A8D1-EAF0-4947-BCEC-A8B423B2F117}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -39,6 +41,10 @@ Global {288F5726-904F-48B8-8363-EA1A22D331D1}.Debug|Any CPU.Build.0 = Debug|Any CPU {288F5726-904F-48B8-8363-EA1A22D331D1}.Release|Any CPU.ActiveCfg = Release|Any CPU {288F5726-904F-48B8-8363-EA1A22D331D1}.Release|Any CPU.Build.0 = Release|Any CPU + {AD16A8D1-EAF0-4947-BCEC-A8B423B2F117}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD16A8D1-EAF0-4947-BCEC-A8B423B2F117}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD16A8D1-EAF0-4947-BCEC-A8B423B2F117}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD16A8D1-EAF0-4947-BCEC-A8B423B2F117}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -48,6 +54,7 @@ Global {3FB17E16-B671-450F-81BD-FD607D6A78C4} = {BDDADD09-D112-418E-8469-BC762EC09936} {C78B1316-1EF9-45C3-A3FD-9A131BA3DD62} = {0170B742-C624-4C22-9DE1-2A93CF9C12D6} {288F5726-904F-48B8-8363-EA1A22D331D1} = {309A8FC8-4784-4D8D-903F-BD54EBB0F1D7} + {AD16A8D1-EAF0-4947-BCEC-A8B423B2F117} = {309A8FC8-4784-4D8D-903F-BD54EBB0F1D7} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {1A82D446-6F26-48B2-8085-DFA5F87453FC} diff --git a/examples/Example.DAL/Animal.cs b/examples/Example.DAL/Animal.cs new file mode 100644 index 00000000..6aa15c55 --- /dev/null +++ b/examples/Example.DAL/Animal.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; + +namespace Example.DAL; + +public partial class Animal +{ + public long Id { get; set; } + + public string Name { get; set; } = null!; +} diff --git a/examples/Example.DAL/DatabaseContext.cs b/examples/Example.DAL/DatabaseContext.cs new file mode 100644 index 00000000..ed35c104 --- /dev/null +++ b/examples/Example.DAL/DatabaseContext.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore; + +namespace Example.DAL; + +public partial class DatabaseContext : DbContext +{ + public DatabaseContext() + { + } + + public DatabaseContext(DbContextOptions options) + : base(options) + { + } + + public virtual DbSet Animals { get; set; } + + public virtual DbSet Users { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + // Only configure the DbContext if it hasn't been configured yet + if (!optionsBuilder.IsConfigured) + { + // DbContext is not yet configured, configure it now + optionsBuilder.UseSqlite("Data Source="); + } + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.ToTable("Animal"); + }); + + modelBuilder.Entity(entity => + { + entity.ToTable("User"); + }); + + OnModelCreatingPartial(modelBuilder); + } + + partial void OnModelCreatingPartial(ModelBuilder modelBuilder); +} diff --git a/examples/Example.DAL/Example.DAL.csproj b/examples/Example.DAL/Example.DAL.csproj new file mode 100644 index 00000000..f097e9d8 --- /dev/null +++ b/examples/Example.DAL/Example.DAL.csproj @@ -0,0 +1,17 @@ + + + + net7.0 + enable + enable + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + diff --git a/examples/Example.DAL/User.cs b/examples/Example.DAL/User.cs new file mode 100644 index 00000000..c65e0c41 --- /dev/null +++ b/examples/Example.DAL/User.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; + +namespace Example.DAL; + +public partial class User +{ + public long Id { get; set; } + + public string Name { get; set; } = null!; +} diff --git a/examples/Example.Website/Controllers/Bootstrap41Controller.cs b/examples/Example.Website/Controllers/Bootstrap41Controller.cs new file mode 100644 index 00000000..0dcc5bc0 --- /dev/null +++ b/examples/Example.Website/Controllers/Bootstrap41Controller.cs @@ -0,0 +1,10 @@ +using Example.DAL; + +namespace Example.Website.Controllers; + +public class Bootstrap41Controller : HomeController +{ + public Bootstrap41Controller(DatabaseContext databaseContext) : base(databaseContext) + { + } +} \ No newline at end of file diff --git a/examples/Example.Website/Controllers/HomeController.cs b/examples/Example.Website/Controllers/HomeController.cs new file mode 100644 index 00000000..a861300d --- /dev/null +++ b/examples/Example.Website/Controllers/HomeController.cs @@ -0,0 +1,102 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Example.DAL; +using Microsoft.AspNetCore.Mvc; +using X.PagedList; + +namespace Example.Website.Controllers; + +public class HomeController : Controller +{ + private const int PageSize = 10; + + private readonly DatabaseContext _databaseContext; + + public HomeController(DatabaseContext databaseContext) + { + _databaseContext = databaseContext; + } + + public IActionResult Index(int page = 1) + { + ViewBag.Names = GetPagedNames(page); + return View(); + } + + public IActionResult AjaxIndex(int page = 1) + { + var listPaged = GetPagedNames(page); + ViewBag.Names = listPaged; + return View(); + } + + public async Task EFCore(int page = 1) + { + // return a 404 if user browses to before the first page + if (page < 1) + { + return NotFound(); + } + + var records = await _databaseContext.Animals + .Select(o => o.Name) + .ToPagedListAsync(page, PageSize); + + // return a 404 if user browses to pages beyond last page. special case first page if no items exist + if (records.PageNumber != 1 && page > records.PageCount) + { + return NotFound(); + } + + ViewBag.Names = records; + + return View(); + } + + public IActionResult GetOnePageOfNames(int page = 1) + { + var listPaged = GetPagedNames(page); + ViewBag.Names = listPaged; + return PartialView("_NameListPartial", ViewBag.Names); + } + + public IActionResult Error() + { + return View(); + } + + private IPagedList GetPagedNames(int? page) + { + // return a 404 if user browses to before the first page + if (page.HasValue && page < 1) + { + return null; + } + + // retrieve list from database/whereverand + var listUnPaged = GetStuffFromFile(); + + // page the list + + var listPaged = listUnPaged.ToPagedList(page ?? 1, PageSize); + + // return a 404 if user browses to pages beyond last page. special case first page if no items exist + if (listPaged.PageNumber != 1 && page.HasValue && page > listPaged.PageCount) + { + return null; + } + + return listPaged; + } + + /// + /// In this case we return array of string, but in most DB situations you'll want to return IQueryable + /// + /// + private IEnumerable GetStuffFromFile() + { + var sampleData = System.IO.File.ReadAllText("Names.txt"); + return sampleData.Split('\n'); + } +} \ No newline at end of file diff --git a/examples/X.PagedList.Mvc.Example.Core/X.PagedList.Mvc.Example.Core.csproj b/examples/Example.Website/Example.Website.csproj similarity index 71% rename from examples/X.PagedList.Mvc.Example.Core/X.PagedList.Mvc.Example.Core.csproj rename to examples/Example.Website/Example.Website.csproj index 72007741..0369adfd 100644 --- a/examples/X.PagedList.Mvc.Example.Core/X.PagedList.Mvc.Example.Core.csproj +++ b/examples/Example.Website/Example.Website.csproj @@ -1,11 +1,12 @@ - net6.0;net7.0 + net7.0 + diff --git a/examples/X.PagedList.Mvc.Example.Core/Names.txt b/examples/Example.Website/Names.txt similarity index 100% rename from examples/X.PagedList.Mvc.Example.Core/Names.txt rename to examples/Example.Website/Names.txt diff --git a/examples/X.PagedList.Mvc.Example.Core/Program.cs b/examples/Example.Website/Program.cs similarity index 70% rename from examples/X.PagedList.Mvc.Example.Core/Program.cs rename to examples/Example.Website/Program.cs index 5de2fe10..35c6d537 100644 --- a/examples/X.PagedList.Mvc.Example.Core/Program.cs +++ b/examples/Example.Website/Program.cs @@ -1,9 +1,11 @@ +using System.IO; +using Example.DAL; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -namespace X.PagedList.Mvc.Example.Core; +namespace Example.Website; public class Program { @@ -12,7 +14,15 @@ public static void Main(string[] args) var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); + builder.Services.AddDbContext(options => + { + var connectionString = $"Data Source={Path.Combine(builder.Environment.ContentRootPath, "data", "example.sqlite")}"; + + options.UseSqlite(connectionString); + }); + var app = builder.Build(); + if (builder.Environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); @@ -23,7 +33,7 @@ public static void Main(string[] args) // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } - app.UseHttpsRedirection(); + app.UseStaticFiles(); app.UseRouting(); diff --git a/examples/X.PagedList.Mvc.Example.Core/Properties/launchSettings.json b/examples/Example.Website/Properties/launchSettings.json similarity index 100% rename from examples/X.PagedList.Mvc.Example.Core/Properties/launchSettings.json rename to examples/Example.Website/Properties/launchSettings.json diff --git a/examples/X.PagedList.Mvc.Example.Core/Views/Bootstrap41/AjaxIndex.cshtml b/examples/Example.Website/Views/Bootstrap41/AjaxIndex.cshtml similarity index 100% rename from examples/X.PagedList.Mvc.Example.Core/Views/Bootstrap41/AjaxIndex.cshtml rename to examples/Example.Website/Views/Bootstrap41/AjaxIndex.cshtml diff --git a/examples/X.PagedList.Mvc.Example.Core/Views/Bootstrap41/Index.cshtml b/examples/Example.Website/Views/Bootstrap41/Index.cshtml similarity index 100% rename from examples/X.PagedList.Mvc.Example.Core/Views/Bootstrap41/Index.cshtml rename to examples/Example.Website/Views/Bootstrap41/Index.cshtml diff --git a/examples/X.PagedList.Mvc.Example.Core/Views/Bootstrap41/_NameListPartial.cshtml b/examples/Example.Website/Views/Bootstrap41/_NameListPartial.cshtml similarity index 100% rename from examples/X.PagedList.Mvc.Example.Core/Views/Bootstrap41/_NameListPartial.cshtml rename to examples/Example.Website/Views/Bootstrap41/_NameListPartial.cshtml diff --git a/examples/X.PagedList.Mvc.Example.Core/Views/Home/AjaxIndex.cshtml b/examples/Example.Website/Views/Home/AjaxIndex.cshtml similarity index 100% rename from examples/X.PagedList.Mvc.Example.Core/Views/Home/AjaxIndex.cshtml rename to examples/Example.Website/Views/Home/AjaxIndex.cshtml diff --git a/examples/Example.Website/Views/Home/EFCore.cshtml b/examples/Example.Website/Views/Home/EFCore.cshtml new file mode 100644 index 00000000..4a8e66e2 --- /dev/null +++ b/examples/Example.Website/Views/Home/EFCore.cshtml @@ -0,0 +1,58 @@ +@{ + ViewBag.Title = "Product Listing"; + var pagedList = (IPagedList)ViewBag.Names; +} + +@using X.PagedList.Mvc.Core; @*import this so we get our HTML Helper*@ +@using X.PagedList; @*import this so we can cast our list to IPagedList (only necessary because ViewBag is dynamic)*@ +@using X.PagedList.Mvc.Core.Fluent +@using X.PagedList.Web.Common + + + + + + +

List of Products from EF Core

+
    + @foreach (var name in ViewBag.Names) + { +
  • @name
  • + } +
+ + +@Html.PagedListPager(pagedList, page => Url.Action("EFCore", new { page })) + +

Fluent pager

+@(Html.Pager(pagedList) + .Url(page => Url.Action("EFCore", new { page })) + .Build()) + +

Pager for #85

+@(Html.Pager(pagedList) + .Url(page => Url.Action("EFCore", new { page })) + .WithPartialView("Paging/_Pager_85") + .DisplayLinkToFirstPage (PagedListDisplayMode.IfNeeded) + .DisplayLinkToLastPage(PagedListDisplayMode.IfNeeded) + .DisplayLinkToPreviousPage() + .DisplayLinkToNextPage() + .MaximumPageNumbersToDisplay(3) + .Build()) + +

Pager with ItemSliceAndTotalPosition at the end

+@Html.PagedListPager(pagedList, + page => Url.Action("EFCore", new { page }), + new PagedListRenderOptions() + { + DisplayItemSliceAndTotal = true, + ItemSliceAndTotalPosition = ItemSliceAndTotalPosition.End + }) + +

Pager with ItemSliceAndTotalPosition at the beginning

+@Html.PagedListPager(pagedList, + page => Url.Action("EFCore", new { page }), + new PagedListRenderOptions() + { + DisplayItemSliceAndTotal = true, + }) \ No newline at end of file diff --git a/examples/X.PagedList.Mvc.Example.Core/Views/Home/Index.cshtml b/examples/Example.Website/Views/Home/Index.cshtml similarity index 100% rename from examples/X.PagedList.Mvc.Example.Core/Views/Home/Index.cshtml rename to examples/Example.Website/Views/Home/Index.cshtml diff --git a/examples/X.PagedList.Mvc.Example.Core/Views/Home/_NameListPartial.cshtml b/examples/Example.Website/Views/Home/_NameListPartial.cshtml similarity index 100% rename from examples/X.PagedList.Mvc.Example.Core/Views/Home/_NameListPartial.cshtml rename to examples/Example.Website/Views/Home/_NameListPartial.cshtml diff --git a/examples/X.PagedList.Mvc.Example.Core/Views/Shared/Error.cshtml b/examples/Example.Website/Views/Shared/Error.cshtml similarity index 100% rename from examples/X.PagedList.Mvc.Example.Core/Views/Shared/Error.cshtml rename to examples/Example.Website/Views/Shared/Error.cshtml diff --git a/examples/X.PagedList.Mvc.Example.Core/Views/Shared/Paging/_Pager.cshtml b/examples/Example.Website/Views/Shared/Paging/_Pager.cshtml similarity index 100% rename from examples/X.PagedList.Mvc.Example.Core/Views/Shared/Paging/_Pager.cshtml rename to examples/Example.Website/Views/Shared/Paging/_Pager.cshtml diff --git a/examples/X.PagedList.Mvc.Example.Core/Views/Shared/Paging/_Pager_85.cshtml b/examples/Example.Website/Views/Shared/Paging/_Pager_85.cshtml similarity index 100% rename from examples/X.PagedList.Mvc.Example.Core/Views/Shared/Paging/_Pager_85.cshtml rename to examples/Example.Website/Views/Shared/Paging/_Pager_85.cshtml diff --git a/examples/X.PagedList.Mvc.Example.Core/Views/Shared/_Layout-41.cshtml b/examples/Example.Website/Views/Shared/_Layout-41.cshtml similarity index 92% rename from examples/X.PagedList.Mvc.Example.Core/Views/Shared/_Layout-41.cshtml rename to examples/Example.Website/Views/Shared/_Layout-41.cshtml index 1550fd28..468e2328 100644 --- a/examples/X.PagedList.Mvc.Example.Core/Views/Shared/_Layout-41.cshtml +++ b/examples/Example.Website/Views/Shared/_Layout-41.cshtml @@ -3,7 +3,7 @@ - @ViewData["Title"] - X.PagedList.Mvc.Example.Core + @ViewData["Title"] - Example.Website @@ -19,7 +19,7 @@