Back to "Att lägga till enhetens ram för bloggposter (Teil 3)"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

ASP.NET Entity Framework

Att lägga till enhetens ram för bloggposter (Teil 3)

Friday, 16 August 2024

Ni kan hitta alla källkod för bloggarna på GitHub

Delar 1 & | | 2 | i serien om att lägga till Entity Framework till ett NET Core project

Del 1 kan hittas här.

Del 2 kan hittas här.

Inleiding

I de tidigare delarna satte vi upp databasen och kontexten för våra bloggposter

Controller

Utkontroller för bloggar är verkligen ganska enkla.

Fat Controllers mönster i ASP.NET MVC

I MVC ramverk är en bra praxis att göra så lite som möjligt i dina kontroller-metoder. Det beror på att kontrollören är ansvarig för att hantera begäran och återskapa ett svar. Den borde inte vara ansvarig für den affärslogiken i applikationenMSC2 Det är ansvaret för modellenM SK3

Den 'Fat Controllern ' antipatronen är där kontrollören gör för mycket. Det kan leda till ett antal problem

  1. Duplicering av kod i flera åtgärder: En handling borde vara en enda enhet av arbete, bara att fylla i modellen och återskapa bilden. Om du finner dig själv att upprepa koden i flera handlingar , är det ett tecken på att du ska omformera den här koden till en separat metod
  2. Kod som är svår att testa: Genom att ha "'", fat controllers, '", kan det bli svårt att testa koden.
  3. Kod som är svår att underhålla: Hållbarhet är en viktig bekymmer när man bygger applikationer.
  4. Kod som är svår att förstå: Detta är en viktig bekymmer för utvecklare. Om du jobbar på ett projekt med en stor kodbas, kan det vara svårt att förstå vad som händer i en kontrollaktion om den gör för mycket.

Blogkontrollören

bloggreglern är relativt enkel. Den har 4 huvudaktioner ( och en ' lösningsaktion ' för de gamla bloggarna länkarna

Task<IActionResult> Index(int page = 1, int pageSize = 5)

Task<IActionResult> Show(string slug, string language = BaseService.EnglishLanguage)

Task<IActionResult> Category(string category, int page = 1, int pageSize = 5)

Task<IActionResult> Language(string slug, string language)

IActionResult Compat(string slug, string language)

Dessa händelser kallas för IBlogService att få de data de behöver. Den IBlogService är detaljerad i föregående artikel.

De här åtgärderna är

  • Index: Det här är listan av bloggare Beiträge (defaults to English Language; vi kan utöka detta senare för att tillåta flera språk page och pageSize som parametrar. Detta är för paginationen. av resultatenM SK2
  • Visa: Det här är den individuella bloggposten . Det tar slug av postet och language som parametrar. Det här är metoden du i dagsläget använder för att läsa den här bloggposten
  • Kategorien: Det här är listan av bloggarna för en given kategori . Det tar category, page och pageSize som parametrar.
  • Språk: Det här visar en bloggpost för ett given språk slug och language som parametrar.
  • Kompatiera: Det här är en compatibilitetsaktion för de gamla bloggarna länkarna . Det tar slug och language som parametrar.

Caching

Som i ett tidigare Beitrag vi implementerar OutputCache och ResponseCahce att kassera resultatet av bloggarna. Detta förbättrar användarupplevelsen och minskar belastning på servern.

De implementeras med hjälp av lämpliga Action-dekoratorer som specifikerar parametrerna som används för Action (, hx-request för HTMX begäran). För att testa med Index vi specifikerar dessa

    [ResponseCache(Duration = 300, VaryByHeader  = "hx-request", VaryByQueryKeys = new[] {nameof(page), nameof(pageSize)}, Location = ResponseCacheLocation.Any)]
    [OutputCache(Duration = 3600, VaryByHeaderNames = new[] {"hx-request"} ,VaryByQueryKeys = new[] { nameof(page), nameof(pageSize)})]

Föreställningar

Föreställningarna för bloggen är relativt enkla. De är i stort sett bara en lista på bloggposter , med några detaljer för varje post Views/Blog folder. De viktigaste bilderna är

_PostPartial.cshtml

Detta är den delaktiga bilden för en enda bloggpost. Den används inom vår Post.cshtml synsätt.

@model Mostlylucid.Models.Blog.BlogPostViewModel

@{
    Layout = "_Layout";
}
<partial name="_PostPartial" model="Model"/>

_BlogSummaryList.cshtml

Det här är den delaktiga bilden av en lista på bloggarna. Den används inom Index.cshtml se som på hemsidan.

@model Mostlylucid.Models.Blog.PostListViewModel
<div class="pt-2" id="content">

    @if (Model.TotalItems > Model.PageSize)
    {
        <pager
            x-ref="pager"
            link-url="@Model.LinkUrl"
               hx-boost="true"
               hx-push-url="true"
               hx-target="#content"
               hx-swap="show:none"
               page="@Model.Page"
               page-size="@Model.PageSize"
               total-items="@Model.TotalItems"
            class="w-full"></pager>
    }
    @if(ViewBag.Categories != null)
{
    <div class="pb-3">
        <h4 class="font-body text-lg text-primary dark:text-white">Categories</h4>
        <div class="flex flex-wrap gap-2 pt-2">
            @foreach (var category in ViewBag.Categories)
            {
                <a hx-controller="Blog" hx-action="Category" hx-push-url="true" hx-get hx-target="#contentcontainer" hx-route-category="@category" href>
                    <span class="inline-block rounded-full dark bg-blue-dark px-2 py-1 font-body text-sm text-white outline-1 outline outline-green-dark dark:outline-white">@category</span>
                </a>
            }
        </div>
    </div>
}
@foreach (var post in Model.Posts)
{
    <partial name="_ListPost" model="post"/>
}
</div>

Det här använder _ListPost partiell bild för att visa de individuella bloggarna tillsammans med söknings-tag hjälpprogram som tillåter oss att klicka på bloggarna

_ListPost.cshtml

Den _Listpost partial view används för att visa de individuella bloggarna i listan. Det används inom _BlogSummaryList synsätt.

@model Mostlylucid.Models.Blog.PostListModel

<div class="border-b border-grey-lighter pb-8 mb-8">
 
    <a asp-controller="Blog" asp-action="Show" hx-boost="true"  hx-swap="show:window:top"  hx-target="#contentcontainer" asp-route-slug="@Model.Slug"
       class="block font-body text-lg font-semibold transition-colors hover:text-green text-blue-dark dark:text-white  dark:hover:text-secondary">@Model.Title</a>
    <div class="flex space-x-2 items-center py-4">
    @foreach (var category in Model.Categories)
    {
    <a hx-controller="Blog" hx-action="Category" class="rounded-full bg-blue-dark font-body text-sm text-white px-2 py-1 outline outline-1 outline-white" hx-push-url="true" hx-get hx-target="#contentcontainer" hx-route-category="@category" href>@category
    </a>
    }

    @{ var languageModel = (Model.Slug, Model.Languages, Model.Language); }
        <partial name="_LanguageList" model="languageModel"/>
    </div>
    <div class="block font-body text-black dark:text-white">@Model.Summary</div>
    <div class="flex items-center pt-4">
        <p class="pr-2 font-body font-light text-primary light:text-black dark:text-white">
            @Model.PublishedDate.ToString("f")
        </p>
        <span class="font-body text-grey dark:text-white">//</span>
        <p class="pl-2 font-body font-light text-primary light:text-black dark:text-white">
            @Model.ReadingTime
        </p>
    </div>
</div>

Som ni kommer att se här har vi en länk till den individuella bloggposten, ,, kategorierna för posten,,, språket som postan finns i,

Vi har också HTMX länkarna tag för kategorierna och språken som låter oss visa lokaliserade meddelanden och meddelanden från en given kategori.

Vi har två sätt att använda HTMX här, ett som ger den fulla URL och ett som är ' HTML bara ' (iMska4 eM Ska5 ingen URL Mska6 Det beror på att vi vill använda den fulle URL för kategorierna och språkenMske7 men vi behöver inte denfulla URL för den individuella bloggposten

 <a asp-controller="Blog" asp-action="Show" hx-boost="true"  hx-swap="show:window:top"  hx-target="#contentcontainer" asp-route-slug="@Model.Slug"

Den här metoden skapar en komplett URL för den individuella bloggposten hx-boost till 'boost hx-request header till true).

  <a hx-controller="Blog" hx-action="Category" class="rounded-full bg-blue-dark font-body text-sm text-white px-2 py-1 outline outline-1 outline-white" hx-push-url="true" hx-get hx-target="#contentcontainer" hx-route-category="@category" href>@category
    </a>

Å andra sidan använder den här metoden HTMX-tag för att få kategorierna för bloggarna. hx-controller, hx-action, hx-push-url, hx-get, hx-target och hx-route-category tag för att få kategorierna för bloggarna medan hx-push-url ställs till true att trycka på URL: n till webbläsarens historia.

Den används också i Index handlingsmetoden för HTMX-behovet.

  public async Task<IActionResult> Index(int page = 1, int pageSize = 5)
    {
        var posts =await  blogService.GetPagedPosts(page, pageSize);
        if(Request.IsHtmx())
        {
            return PartialView("_BlogSummaryList", posts);
        }
        posts.LinkUrl = Url.Action("Index", "Blog");
        return View("Index", posts);
    }

Där det tillåter oss att antingen återställa hela bilden eller bara den delaktiga bilden för HTMX begäran.

Hemsida

I HomeController vi refererar också till dessa bloggar för att få de senaste bloggarna på hemsidan. Detta görs i Index handlingsmetod.

   public async Task<IActionResult> Index(int page = 1,int pageSize = 5)
    {
            var authenticateResult = GetUserInfo();
            var posts =await blogService.GetPagedPosts(page, pageSize);
            posts.LinkUrl= Url.Action("Index", "Home");
            if (Request.IsHtmx())
            {
                return PartialView("_BlogSummaryList", posts);
            }
            var indexPageViewModel = new IndexPageViewModel
            {
                Posts = posts, Authenticated = authenticateResult.LoggedIn, Name = authenticateResult.Name,
                AvatarUrl = authenticateResult.AvatarUrl
            };
            
            return View(indexPageViewModel);
    }

Som ni ser här använder vi IBlogService för att få de senaste bloggarna på hemsidan. Vi använder också GetUserInfo sättet att få användarinformationen för hemsidan.

Återigen har detta en HTMX- begäran om att återställa den partiella synen på bloggarna för att tillåta oss att öppna bloggarna på hemsidan.

I slutsats

I nästa del kommer vi - ' - att gå in i de svårlösta detaljerna av hur vi använder IMarkdownBlogService att fylla databasen med bloggarna från markerdown-filerna. Detta är en viktig del av applikationen eftersom det tillåter oss att använda markerdown files för att fylla datan med bloggposterna

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.