基於 abp vNext 和 .NET Core 開發博客項目 - Blazor 實戰系列(五)

来源:https://www.cnblogs.com/meowv/archive/2020/06/13/13096000.html
-Advertisement-
Play Games

系列文章 基於 abp vNext 和 .NET Core 開發博客項目 - 使用 abp cli 搭建項目 基於 abp vNext 和 .NET Core 開發博客項目 - 給項目瘦身,讓它跑起來 基於 abp vNext 和 .NET Core 開發博客項目 - 完善與美化,Swagger登場 ...


系列文章

  1. 基於 abp vNext 和 .NET Core 開發博客項目 - 使用 abp cli 搭建項目
  2. 基於 abp vNext 和 .NET Core 開發博客項目 - 給項目瘦身,讓它跑起來
  3. 基於 abp vNext 和 .NET Core 開發博客項目 - 完善與美化,Swagger登場
  4. 基於 abp vNext 和 .NET Core 開發博客項目 - 數據訪問和代碼優先
  5. 基於 abp vNext 和 .NET Core 開發博客項目 - 自定義倉儲之增刪改查
  6. 基於 abp vNext 和 .NET Core 開發博客項目 - 統一規範API,包裝返回模型
  7. 基於 abp vNext 和 .NET Core 開發博客項目 - 再說Swagger,分組、描述、小綠鎖
  8. 基於 abp vNext 和 .NET Core 開發博客項目 - 接入GitHub,用JWT保護你的API
  9. 基於 abp vNext 和 .NET Core 開發博客項目 - 異常處理和日誌記錄
  10. 基於 abp vNext 和 .NET Core 開發博客項目 - 使用Redis緩存數據
  11. 基於 abp vNext 和 .NET Core 開發博客項目 - 集成Hangfire實現定時任務處理
  12. 基於 abp vNext 和 .NET Core 開發博客項目 - 用AutoMapper搞定對象映射
  13. 基於 abp vNext 和 .NET Core 開發博客項目 - 定時任務最佳實戰(一)
  14. 基於 abp vNext 和 .NET Core 開發博客項目 - 定時任務最佳實戰(二)
  15. 基於 abp vNext 和 .NET Core 開發博客項目 - 定時任務最佳實戰(三)
  16. 基於 abp vNext 和 .NET Core 開發博客項目 - 博客介面實戰篇(一)
  17. 基於 abp vNext 和 .NET Core 開發博客項目 - 博客介面實戰篇(二)
  18. 基於 abp vNext 和 .NET Core 開發博客項目 - 博客介面實戰篇(三)
  19. 基於 abp vNext 和 .NET Core 開發博客項目 - 博客介面實戰篇(四)
  20. 基於 abp vNext 和 .NET Core 開發博客項目 - 博客介面實戰篇(五)
  21. 基於 abp vNext 和 .NET Core 開發博客項目 - Blazor 實戰系列(一)
  22. 基於 abp vNext 和 .NET Core 開發博客項目 - Blazor 實戰系列(二)
  23. 基於 abp vNext 和 .NET Core 開發博客項目 - Blazor 實戰系列(三)
  24. 基於 abp vNext 和 .NET Core 開發博客項目 - Blazor 實戰系列(四)

上一篇完成了分類標簽友鏈的列表查詢頁面數據綁定,還剩下一個文章詳情頁的數據沒有綁,現在簡單的解決掉。

文章詳情

之前已經添加了四個參數:year、month、day、name,用來組成我們最終的URL,繼續添加一個參數用來接收API返回的數據。

[Parameter]
public int year { get; set; }

[Parameter]
public int month { get; set; }

[Parameter]
public int day { get; set; }

[Parameter]
public string name { get; set; }

/// <summary>
/// URL
/// </summary>
private string url => $"/{year}/{(month >= 10 ? month.ToString() : $"0{month}")}/{(day >= 10 ? day.ToString() : $"0{day}")}/{name}/";

/// <summary>
/// 文章詳情數據
/// </summary>
private ServiceResult<PostDetailDto> post;

然後在初始化方法OnInitializedAsync()中請求數據。

/// <summary>
/// 初始化
/// </summary>
protected override async Task OnInitializedAsync()
{
    // 獲取數據
    post = await Http.GetFromJsonAsync<ServiceResult<PostDetailDto>>($"/blog/post?url={url}");
}

現在拿到了post數據,然後在HTML中綁定即可。

@if (post == null)
{
    <Loading />
}
else
{
    @if (post.Success)
    {
        var _post = post.Result;

        <article class="post-wrap">
            <header class="post-header">
                <h1 class="post-title">@_post.Title</h1>
                <div class="post-meta">
                    Author: <a itemprop="author" rel="author" href="javascript:;">@_post.Author</a>
                    <span class="post-time">
                        Date: <a href="javascript:;">@_post.CreationTime</a>
                    </span>
                    <span class="post-category">
                        Category:<a href="/category/@_post.Category.DisplayName/">@_post.Category.CategoryName</a>
                    </span>
                </div>
            </header>
            <div class="post-content" id="content">
                @((MarkupString)_post.Html)
            </div>
            <section class="post-copyright">
                <p class="copyright-item">
                    <span>Author:</span>
                    <span>@_post.Author</span>
                </p>
                <p class="copyright-item">
                    <span>Permalink:</span>
                    <span><a href="/post@_post.Url">https://meowv.com/post@_post.Url</a></span>
                </p>
                <p class="copyright-item">
                    <span>License:</span>
                    <span>本文采用<a target="_blank" href="http://creativecommons.org/licenses/by-nc-nd/4.0/"> 知識共用 署名-非商業性使用-禁止演繹(CC BY-NC-ND)國際許可協議 </a>進行許可</span>
                </p>
            </section>
            <section class="post-tags">
                <div>
                    <span>Tag(s):</span>
                    <span class="tag">
                        @if (_post.Tags.Any())
                        {
                            @foreach (var tag in _post.Tags)
                            {
                                <a href="/tag/@tag.DisplayName/"># @tag.TagName</a>
                            }
                        }
                    </span>
                </div>
                <div>
                    <a @onclick="async () => await Common.BaskAsync()">back</a>
                    <span>· </span>
                    <a href="/">home</a>
                </div>
            </section>
            <section class="post-nav">
                @if (_post.Previous != null)
                {
                    <a class="prev"
                       rel="prev"
                       @onclick="@(async () => await Common.NavigateTo($"/post{_post.Previous.Url}, true))"
                       href="/post@_post.Previous.Url">@_post.Previous.Title</a>
                }
                @if (_post.Next != null)
                {
                    <a class="next"
                       rel="next"
                       @onclick="@(async () => await Common.NavigateTo($"/post{_post.Next.Url}", true))"
                       href="/post@_post.Next.Url">
                        @_post.Next.Title
                    </a>
                }
            </section>
        </article>
    }
    else
    {
        <ErrorTip />
    }
}

其中有幾個地方需要註意一下:

我們從post對象中取到的文章內容HTML,直接顯示是不行了,需要將其解析為HTML標簽,需要用到MarkupString

然後頁面上有一個後退按鈕,這裡我在Common.cs中寫了一個方法來實現。

/// <summary>
/// 後退
/// </summary>
/// <returns></returns>
public async Task BaskAsync()
{
    await InvokeAsync("window.history.back");
}

還有就是上一篇和下一篇的問題,將具體的URL傳遞給NavigateTo()方法,然後跳轉過去即可。

Common.cs中將之前文章創建RenderPage()方法修改成NavigateTo()。這個命名更好一點。

/// <summary>
/// 跳轉指定URL
/// </summary>
/// <param name="uri"></param>
/// <param name="forceLoad">true,繞過路由刷新頁面</param>
/// <returns></returns>
public async Task NavigateTo(string url, bool forceLoad = false)
{
    _navigationManager.NavigateTo(url, forceLoad);

    await Task.CompletedTask;
}

現在數據算是綁定完了,但是遇到了一個大問題,就是詳情頁面的樣式問題,因為用到了Markdown,所以之前是載入了許多JS文件來處理的。那麼現在肯定行不通了,所以關於詳情頁的樣式問題暫時擱淺,讓我尋找一下好多解決方式。

現在顯示是沒有問題了,就是不太好看,還有關於添加文章的功能,不知道有什麼好的 Markdown 編輯器可以推薦我使用。

1

到這裡Blazor的前端展示頁面已經全部弄完了,接下來開始寫後臺相關的頁面。

後臺首頁

關於後臺管理的所有頁面都放在Admin文件夾下,在Pages文件夾下新建Admin文件夾,然後先添加兩個組件頁面:Admin.razorAuth.razor

Admin.razor為後臺管理的首頁入口,我們在裡面直接添加幾個預知的鏈接並設置其路由。

@page "/admin"

<div class="post-wrap">
    <h2 class="post-title">-&nbsp;博客內容管理&nbsp;-</h2>
    <ul>
        <li>
            <a href="/admin/post"><h3>

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 給所有開發人員配備一個開發調試小助手 來來來,幫我看下剛纔按鈕請求的參數是否正確 來來來,幫我看下當前打開的頁面的頁面地址是什麼 來來來…… 這是你未來的場景 應用系統開發過程中 關於前端調試, 最常聽到的是, 你F12一下 點擊NetWork 查看請求 Headers 看一下請求的內容 關鍵是左側 ...
  • 在開發UIBarChart的過程中,需要繪製Y軸的刻度,數據作圖時,縱橫坐標軸刻度範圍及刻度值的取法,很大程度上取決於數據的分佈。對某一組數據,我們很容易就能知道如何選取這些值才能使圖畫得漂亮。但是要想找到一個通用的演算法,用以對任意分佈的數據決定這些值,並不是一件容易的事 ...
  • ExceptionFilter 主要是為了捕捉系統異常。通常我們會繼承 ExceptionFilterAttribute ,實現自定義系統異常捕捉。 版本:.Net Core 3.1 一、基本創建過程 新建 .Net Core Mvc 並新建控制器 ExceptionFilterController ...
  • 我們來創建動態菜單吧 首先,先對動態菜單的概念、操作、流程進行約束:1.Host和各個Tenant有自己的自定義菜單2.Host和各個Tenant的許可權與自定義菜單相關聯2.Tenant有一套預設的菜單,規定對應的TenantId=-1,在添加租戶時自動將標準菜單和標準菜單的許可權初始化到添加的租戶 ...
  • 直接上代碼 1 public static class ImageCompress 2 { 3 /// <summary> 4 /// 圖片壓縮 5 /// </summary> 6 /// <param name="imagePath">圖片文件路徑</param> 7 /// <param na ...
  • 看了看原生UWP的ScrollViewer,滑動很流暢(例如 開始菜單),但是WPF自帶的ScrollViewer滾動十分生硬.. 突發奇想,今天來實現一個流暢滾動的ScrollViewer. 一、目標 查閱網上的實現方法,要麼直接重寫控制項,要麼一堆Storyboard..很是無奈,還有些許bug. ...
  • 無論是開發app還是網站,可能都需要一個廣告功能,比如我們常見的在首頁有個輪播廣告,裡面會輪播顯示多個圖片。還有比如一個新聞門戶網站 很常見的 banner橫幅廣告,還有js特效廣告等。本篇說說在abp(5.9)中如何實現廣告模塊。 源碼地址:https://gitee.com/bxjg1987/a ...
  • 一:背景 1. 講故事 上一篇跟大家聊到了Target-typed new 和 Lambda discard parameters,看博客園和公號里的閱讀量都達到了新高,甚是欣慰,不管大家對新特性是多頭還是空頭,起碼還是對它抱有一種極為關註的態度,所以我的這個系列還得跟,那就繼續開擼吧,今天繼續帶來 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...