Προσθήκη Πλαίσιο Οντότητας για Δημοσιεύσεις στο Blog (Παρουσίαση ΜSK1
Μπορείτε να βρείτε ολόκληρο τον κώδικα πηγής για τα άρθρα στο blog GitHub
Μερικά τμήματα 1 ΜSK1 2 της σειράς σχετικά με την προσθήκη του Entity Framework σε ένα έργο κεντρικής εμβέλειας .NET
Μέρος 1 επιχειρήσεις μπορούν να βρεθούν ΕΔΩ.
Μέρος 2 επιχειρήσεις μπορούν να βρεθούν ΕΔΩ.
Εισαγωγή
Στα προηγούμενα μέρη, δημιουργήσαμε τη βάση δεδομένων και το πλαίσιο για τα ιστολόγια μας, και πρόσθεσε τις υπηρεσίες να αλληλεπιδράσουν με την βάση δεδομένα. Σε αυτό το postM SK2 θα αναλυθούμε πώς αυτές οι υπηρεσίες τώρα λειτουργούν με τους υπάρχοντες ελεγκτές και τις απόψειςΜSK3
Ελέγχοντες
Οι ελεγκτές για τα Blogs είναι πραγματικά αρκετά απλοί; σε συνάρτηση με την αποφυγή του 'Fat ControllerM SK2 αντιπροσωπεία ΜSK3 πρότυπο ιδεοποιήσαμε νωρίς στην ASPMSKA4NET MVC ημέρεςMKA5
Το πρότυπο ελέγχου λίπους στο ASP.NET MVC
I MVC frameworks μια καλή πρακτική είναι να κάνετε όσο το δυνατόν λιγότερο στις μεθόδους ελέγχου σας. Αυτό συμβαίνει επειδή ο ελεγκτής είναι υπεύθυνος για την επεξεργασία του αιτήματος και την επιστροφή μιας απάντησηςΜSK1 Δεν πρέπει να ευθύνεται για τη επιχειρηματική λογική της εφαρμογής.Αυτή είναι η ευθύνη του μοντέλου
Το 'Fat Controller' αντιπροσωπεία είναι όπου ο ελεγκτής κάνει πάρα πολύM SK2 Αυτό μπορεί να οδηγήσει σε ένα αριθμό προβλημάτωνMSKA3 συμπεριλαμβανομένωνMKA4
- Διπλασιασμός κώδικα σε πολλαπλές δράσεις: Μια δράση θα πρέπει να είναι μια ενιαία μονάδα εργασίας, απλά λαμβάνοντας το μοντέλο και επιστρέφοντας την προβολήΜSK1 Εάν βρείτε τον εαυτό σας επαναλαμβανόμενος κώδικα σε πολλαπλές ενέργειες, αυτό είναι ένα σημάδι ότι θα έπρεπε να αναπαράγετε αυτόν τον κωδικό σε μια ξεχωριστή μέθοδοM SK3
- Κώδικα που είναι δύσκολο να δοκιμάσετε: Έχοντας ' αναπληρώσεις ελεγκτές ΜSK1 μπορεί να σας κάνει δύσκολο να δοκιμάσετε τον κωδικό Η . αναπληρώνει το Testing θα πρέπει να προσπαθήσει να ακολουθήσει όλα τα πιθανά μονοπάτια μέσω του κώδικα ΜSK3 και αυτό μπορεί να είναι δύσκολο αν ο κωδικός δεν είναι καλά - αναπληρωμένο και επικεντρωθεί σε μια ενιαία ευθύνη
- Κώδικα που είναι δύσκολο να διατηρηθεί: επιχειρήσεις Η διατήρηση είναι μια βασική ανησυχία κατά την κατασκευή εφαρμογών. Έχοντας 'kitchen sinkM SK2 μέθοδοι δράσης μπορεί εύκολα να οδηγήσει σε εσάς και άλλους προγραμματιστές χρησιμοποιώντας τον κώδικα για να κάνετε αλλαγές που σπάζουν άλλα τμήματα της εφαρμογήςΜSK3
- Κώδικα που είναι δύσκολο να κατανοήσουμε: Αυτό είναι μια βασική ανησυχία για τους προγραμματιστές. Εάν εργάζεστε σε ένα έργο με μεγάλη βάση κωδικώνΜSK1 μπορεί να είναι δύσκολο να καταλάβετε τι συμβαίνει σε μια δράση ελέγχου εάν κάνει πάρα πολύ.
Ο έλεγχος του blog
Ο διαχειριστής του ιστολογίου είναι σχετικά απλός. Έχει ΜSK1 κύριες ενέργειες ΜSK2 και μία ' συμβατή δράση ΜΚ4 για τους παλιούς συνδέσμους blog ΜΣΚ5 Αυτά είναι ΜСК6
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)
Ως εκ τούτου, οι ενέργειες αυτές αποκαλούν IBlogService για να αποκτήσουν τα δεδομένα που χρειάζονται. IBlogService Περιγράφεται λεπτομερώς στο Προηγούμενο post.
Από την άλλη πλευρά, οι ενέργειες αυτές είναι ως εξής:
- Δείκτης:Αυτό είναι ο κατάλογος των αναρτήσεων στο blog ΜSK1επιβεβαιώσεις στην Αγγλική γλώσσα;θα μπορούμε να επεκτείνουμε αυτό αργότερα για να επιτρέψουμε πολλές γλώσσεςM SK3Θα δείτε ότι χρειάζεται
pageκαιpageSizeως παραμέτρους.Αυτό είναι για τη σελίδαΜSK1 των αποτελεσμάτων. - Εμφάνιση:Αυτή είναι η ατομική ανάρτηση στο blogΜSK1Πρέπει να
slugΑπό την εφημερίδα και τοlanguageως παραμέτρους.Αυτή είναι η μέθοδος που χρησιμοποιείτε για να διαβάσετε αυτό το blog post. - Κατηγορία:Αυτό είναι ο κατάλογος των blog posts για μια συγκεκριμένη κατηγορίαΜSK1Πρέπει να
category,pageκαιpageSizeΟι παράμετροι . - Γλώσσα: Αυτό δείχνει ένα blog post για μια δεδομένη γλώσσαΜSK1 Χρειάζεται το
slugκαιlanguageΟι παράμετροι . - Compat: Αυτό είναι μια δράση συμβατότητας για τους παλιούς συνδέσμους blog. Χρειάζεται το
slugκαιlanguageΟι παράμετροι .
Κατσάκι
Όπως αναφέρθηκε σε ένα Προηγούμενο post εφαρμόζουμε OutputCache και ResponseCahce για την κρυπτογράφηση των αποτελεσμάτων των ιστολογικών δημοσιεύσεων.Αυτό βελτιώνει την εμπειρία του χρήστη και μειώνει το φορτίο στον διακομιστή.
Αυτά εφαρμόζονται με τη χρήση των κατάλληλων διακοσμητών δράσης που προσδιορίζουν τις παραμέτρους που χρησιμοποιούνται για την δράση ( αναφορές, καθώς και hx-request για τις αιτήσεις HTMX). Για παράδειγμα με Index Εμείς αναφέρουμε αυτές τις: επιχειρήσεις
[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)})]
Προβλέψεις
Οι απόψεις για το blog είναι σχετικά απλές. Είναι κατά κύριο λόγο μόνο μια λίστα με τις δημοσιεύσεις στο blogΜSK1 με λίγες λεπτομέρειες για κάθε post. Views/Blog φάκελο. Οι κύριες προβολές είναιΜSK1
_PostPartial.cshtml
Αυτή είναι η μερική εικόνα για ένα ενιαίο blog post. Χρησιμοποιείται μέσα στο δικό μας Post.cshtml ΔΙΑΒΑΣΤΕ ΕΠΙΧΕΙΡΕΥΣΗ
@model Mostlylucid.Models.Blog.BlogPostViewModel
@{
Layout = "_Layout";
}
<partial name="_PostPartial" model="Model"/>
_BlogSummaryList.cshtml
Αυτή είναι η μερική προβολή για μια λίστα blog posts. Χρησιμοποιείται μέσα στο δικό μας Index.cshtml Δείτε επίσης και στην ιστοσελίδα.
@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>
Αυτό χρησιμοποιεί το _ListPost μερική προβολή για την εμφάνιση των ατομικών δημοσιεύσεων στο blog μαζί με το Ετικέτες Βοηθός που μας επιτρέπει να τοποθετήσουμε τα άρθρα του blog.
_ListPost.cshtml
Η _Η μερική προβολή της λίστας χρησιμοποιείται για την εμφάνιση των ατομικών δημοσιεύσεων στο blog στη λίστα. Χρησιμοποιείται εντός του _BlogSummaryList ΔΙΑΒΑΣΤΕ ΕΠΙΧΕΙΡΕΥΣΗ
@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>
Όπως σας ενδιαφέρει' αναμένεται να δείτε εδώ έχουμε μια σύνδεση με την ατομική ανάρτηση blog, αναμένετε τις κατηγορίες για το postΜSK2 αναμένω τις γλώσσες που είναι διαθέσιμες στο post, αναμένει τη συνοπτική της ανάρτησηςM SK4 αναμέρει την ημερομηνία δημοσίευσης και τον χρόνο ανάγνωσηςMK5 αναμένοντας
Έχουμε επίσης ετικέτες σύνδεσης HTMX για τις κατηγορίες και τις γλώσσες που μας επιτρέπουν να εμφανίσουμε τα εντοπισμένα μηνύματα και τις δημοσιεύσεις για μια συγκεκριμένη κατηγορία.
Έχουμε δύο τρόπους για να χρησιμοποιήσουμε το HTMX εδώ, ένα που δίνει την πλήρη URL και ένα που είναι 'HTML μόνοM SK2 (ΜSK4MSKA5Δεν υπάρχει URLMSKI6Αυτό συμβαίνει επειδή θέλουμε να χρησιμοποιούμε το πλήρες URL για τις κατηγορίες και τις γλώσσεςMSKE7 αλλά δεν έχουμε ανάγκη η πλήρης URL για τη μεμονωμένη ανάρτηση στο blogMISK9
<a asp-controller="Blog" asp-action="Show" hx-boost="true" hx-swap="show:window:top" hx-target="#contentcontainer" asp-route-slug="@Model.Slug"
Αυτή η προσέγγιση εντοπίζει μια πλήρη URL για την ατομική ανάρτηση στο blog και χρησιμοποιεί hx-boost 'boost ΜSK1 το αίτημα για χρήση HTMX ΜSK2this καθορίζει την hx-request Ο επικεφαλής για 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>
Εναλλακτικά, αυτή η προσέγγιση χρησιμοποιεί τις ετικέτες HTMX για να πάρει τις κατηγορίες για τα άρθρα του blog. Αυτό χρησιμοποιεί την hx-controller, hx-action, hx-push-url, hx-get, hx-target και hx-route-category Tags για να πάρετε τις κατηγορίες για τα άρθρα του blog ενώ hx-push-url Έχει καθοριστεί true για να πιέσετε το URL στο ιστορικό του προγράμματος περιήγησης.
Χρησιμοποιείται και στο εσωτερικό μας Index Μέθοδος δράσης για τις αιτήσεις HTMX.
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);
}
Όπου μας επιτρέπει είτε να επιστρέψουμε την πλήρη προβολή ή μόνο τη μερική προβολία για τις αιτήσεις HTMX, δίνει μια ΜSK1SPA' όπως η εμπειρίαM SK3
Home Σελίδα
Στον HomeController αναφερόμαστε επίσης σε αυτές τις υπηρεσίες blog για να λάβουμε τα πιο πρόσφατα άρθρα blog για την αρχική σελίδα. Αυτό γίνεται στο Index Μέθοδος δράσης.
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);
}
Όπως θα σας αρέσει' αναμένεται να δείτε εδώ χρησιμοποιούμε το IBlogService για να πάρετε τις τελευταίες δημοσιεύσεις στο blog για την αρχική σελίδα. Χρησιμοποιούμε επίσης το GetUserInfo μέθοδος για τη λήψη των πληροφοριών του χρήστη για την αρχική σελίδα.
Και πάλι αυτό έχει ένα αίτημα HTMX για να επιστρέψει την εν μέρει προβολή των δημοσιεύσεων στο blog, ώστε να μας επιτρέπει να τοποθετήσουμε τις δημοσιεύσεις του blog στην αρχική σελίδα.
Στο συμπέρασμα
Στο επόμενο τμήμα μας θα ανακαλύψουμε' θα πάμε σε λεπτομέρειες για το πώς χρησιμοποιούμε την IMarkdownBlogService για να λαμβάνουμε τη βάση δεδομένων με τις δημοσιεύσεις του blog από τα αρχεία μάρκας.Αυτό είναι ένα βασικό μέρος της εφαρμογής, καθώς μας επιτρέπει να χρησιμοποιούμε τα αρχείο μάρκετινγκ για να Λαμβάνεται η βάση δεδομένα με τις αναρτήσεις του blog.