# Het 'Entity Framework' toevoegen voor Blog Posts (Part 3)

<!--category-- ASP.NET, Entity Framework -->
<datetime class="hidden">2024-08-16T18:00</datetime>

Je kunt alle broncode voor de blogposts vinden op: [GitHub](https://github.com/scottgal/mostlylucidweb/tree/main/Mostlylucid/Blog)

**Paren 1 & | | 2 | van de reeks over het toevoegen van een 'Entity Framework' aan een \.\NET Core project.**

Deel 1 kan gevonden worden [Hier.](/blog/addingentityframeworkforblogpostspt1).

Deel 2 kan gevonden worden [Hier.](/blog/addingentityframeworkforblogpostspt2).

## Inleiding

In de vorige delen hebben we de database en de context opgezet voor onze blogposts, en de diensten toegevoegd om te interageren met de database. In deze postM SK2 zullen we uitleggen hoe deze Diensten nu werken met de bestaande controllers en aansigtesMSC3

[TOC]

## Controllers

Out-controllers voor Blogs zijn echt heel simpel; in lijn met het voorkomen van de 'Fat ControllerM SK2 antipatroon ( een patroon dat we in het begin van de ASP ideologiseerden.

### Het vetcontroleerderpatroon in ASP.NET MVC

I MVC-frameworks is een goede praktijk om zo weinig mogelijk te doen in je controleermethoden. Dit komt omdat de controleer verantwoordelijk is voor het behandelen van de vraag en het teruggeven van een antwoord. Het zou niet verantwoordelijk moeten zijn voor de zakelijke logica van de toepassing

Het 'Fat Controller' antipatroon is waar de controller teveel doet.

1. Duplikaat van code in meerdere acties:
   Een actie zou een enkele werkeenheid moeten zijn, gewoon het model bevolken en de visie teruggeven. Als je code in meerdere acties herhaalt, is dit een teken dat je deze code moet herfactoren tot een aparte methode.
2. Code dat moeilijk te testen is:
   Door te hebben 'fat controllers' kun je het moeilijk maken om de code te testen . De test moet proberen alle mogelijke paden door de code heen te volgen , en dit kan moeilijk zijn als de code niet goed is M SK4 structuurd en op één enkele verantwoordelijkheid geconcentreerd is.
3. Code dat moeilijk te onderhouden is:
   Onhoudbaarheid is een belangrijk probleem bij het bouwen van applicaties. Het hebben van 'kitchen sinkM SK2 actiemethoden kan je gemakkelijk leiden tot andere ontwikkelaars die de code gebruiken om veranderingen te maken die andere delen van de toepassing breken.
4. Een moeilijk te begrijpen code:
   Dit is een belangrijke bezorgdheid voor ontwikkelaars. Als je aan een project werkt met een grote codebase, kan het moeilijk zijn om te begrijpen wat er gebeurt in een controller-aktie als hij teveel doet.

### De Blog Controller

De blogcontroleerder is relatief eenvoudig. Het heeft 4 belangrijkste acties ( en één 'compatie-actieMSC4 voor de oude bloglinksM SK5 Dit zijn:

```csharp
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)
```

Deze acties noemen in turn de `IBlogService` om de nodige gegevens te krijgen. De `IBlogService` is gedetailleerd in de [vorige post](/blog/addingentityframeworkforblogpostspt2).

Deze acties zijn als volgt.

- Index: Dit is de lijst van blogposts M SK1defaults to English Language; we kunnen dit later uitbreiden om meerdere talen toe te laten spreken `page` en `pageSize` Als parameters. Dit is voor paginatie. van de resultaten
- Vertoon: Dit is de individuele blogpost. Het kost het `slug` van de post en het `language` Als parameters. Dit is de methode die je momenteel gebruikt voor het lezen van deze blogpost
- Kategorie: Dit is de lijst van blogposts voor een bepaalde categorie. `category`, `page` en `pageSize` Als parameters.
- Taal: Dit toont een blogpost voor een bepaalde taal. `slug` en `language` Als parameters.
- Compat: Dit is een compatibiliteitsactie voor de oude bloglinks. `slug` en `language` Als parameters.

### Caching

Zoals gezegd in een [eerdere post](https://www.mostlylucid.net/blog/aspnetcachingwithhtmx) We implementeren `OutputCache` en `ResponseCahce` Dit verbetert de gebruikerservaring en vermindert de lading op de server.

Deze worden implementeerd met de passende actie-decoratoren die de parameters voor de actie ( en `hx-request` voor HTMX-vragen). Voor examen met `Index` We geven deze aan:

```csharp
    [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)})]
```

## Aansigte

De aansigten voor de blog zijn relatief eenvoudig. Ze zijn meestal slechts een lijst van blogposts, met een paar details voor elke postM SK2 De aanzichten zijn in `Views/Blog` folder. De belangrijkste aansigten zijn:

### `_PostPartial.cshtml`

Dit is de gedeeltelijke visie voor een enkele blogpost. Het wordt gebruikt in onze `Post.cshtml` view.

```razor
@model Mostlylucid.Models.Blog.BlogPostViewModel

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

### `_BlogSummaryList.cshtml`

Dit is de gedeeltelijke kijk op een lijst van blogposts. Het wordt gebruikt in onze website. `Index.cshtml` Kijk ook op de homepage.

```razor
@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>
```

Dit gebruikt de `_ListPost` Een gedeeltelijk beeld om de individuele blogposts te laten zien. [Paging tag helper](/blog/addpagingwithhtmx) Daarmee kunnen we de blogposts bladzijden maken.

### `_ListPost.cshtml`

De gemeenschappelijke wetgeving van het land. _Listpost gedeeltelijke visie wordt gebruikt om de individuele blogposts in de lijst te laten zien. Het wordt gebruikt binnen de `_BlogSummaryList` view.

```razor
@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>
```

Zoals je hier ziet, hebben we een link naar de individuele blogpost.

We hebben ook HTMX-link-tags voor de categorieën en de talen om ons toe te laten de gelocaliseerde posten en de posten voor een bepaalde categorie tonen.

We hebben twee manieren om HTMX te gebruiken hier, een die de volle URL geeft en een die is 'HTML alleenM SK2 (iMska4eMka5 geen URLM Ska6 Dit komt omdat we de volleURL willen gebruiken voor de categorieën en de talenMske7 maar we nietMsek8 de volledige URL nodig hebben voor de individuele blogpostMsko9

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

Deze aanpak populaeert een volledige URL voor de individuele blogpost en gebruikt `hx-boost` naar 'boost' de vraag om HTMX te gebruiken. `hx-request` Opskrif naar: `true`).

```razor
  <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>
```

Alternativ gebruikt deze aanpak de HTMX-tags om de categorieën voor de blogposts te krijgen. Dit gebruikt de `hx-controller`, `hx-action`, `hx-push-url`, `hx-get`, `hx-target` en `hx-route-category` Tags om de categorieën voor de blogposts te krijgen terwijl `hx-push-url` is opgesteld. `true` om de URL naar de browsergeschiedenis te duwen.

Het wordt ook gebruikt in ons bedrijf. `Index` Aksiemethode voor de HTMX-vragen.

```csharp
  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);
    }
```

Waar het ons in staat stelt ofwel de volledige kijk terug te geven of alleen maar de gedeeltelijke kijk voor HTMX-requests, met een 'SPA

## Huisblad

In de `HomeController` We refereren ook naar deze blogdiensten om de nieuwste blogposts voor de homepage te krijgen. Dit is gedaan in de `Index` actiemethode.

```csharp
   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);
    }
```

Zoals je hier ziet, gebruiken we de '. `IBlogService` om de nieuwste blogposts voor de homepage te krijgen. We gebruiken ook de `GetUserInfo` Hoe krijg je de gebruikerinformatie voor de homepage.

Nogmaals, dit heeft een HTMX-vraag om de gedeeltelijke visie voor de blogposten terug te geven zodat we de blog posts in de homepage kunnen zetten.

## In slotting:

In ons volgende deel gaan we naar de vreselijke details van hoe we het `IMarkdownBlogService` om de database te vullen met de blogposts van de markerdown-files. Dit is een belangrijk onderdeel van de toepassing omdat het ons in staat stelt om de markdown- files te gebruiken om de databasis te vulle met de blogsposts .