博客四元素 既然要寫一個博客類的網站,那就應該知道博客的相關信息。 標題|作者|時間|內容 | | | title|author|time|content 因為之前有瞭解過Redis,所以有點糾結於數據的存儲方式,最終決定還是按照書上寫的一步一步來,搞完了之後再決定是不是需要做修改。 書中介紹的存儲 ...
博客四元素
既然要寫一個博客類的網站,那就應該知道博客的相關信息。
標題 | 作者 | 時間 | 內容 |
---|---|---|---|
title | author | time | content |
因為之前有瞭解過Redis,所以有點糾結於數據的存儲方式,最終決定還是按照書上寫的一步一步來,搞完了之後再決定是不是需要做修改。
書中介紹的存儲方式如下:
post:count | title | 小猿的博客 |
author | 小猿 | |
time | 2018.5.17 | |
content | 世界如此美妙,我卻選擇的程式員 |
看的出來博客的所有內容都是以HashSet形式存儲的(目前狀態),保證存儲內容的唯一性取決於post:count的count,這個count應該類似於自增變數。
既然是面向對象編程,第一件事肯定是創建一個實體類;
using System; using System.Collections.Generic; using System.Text; using Blog.Common; namespace Blog.Models { public class BLogModel { public BLogModel(string title, string author, DateTime time, string content) { bool flag = true; if (!title.IsNullOrEmpty()) this.title = title; else flag = false; if (!author.IsNullOrEmpty()) this.author = author; else flag = false; if (time == null) flag = false; else this.time = time; if (!content.IsNullOrEmpty()) this.content = content; else flag = false; if(flag==false) { throw new ApplicationException("創建BLogModel實體有必填欄位為空"); } } public string title { get; set; } public string author { get; set; } public DateTime time { get; set; } public string content { get; set; } } }
創建這個實體類,我住了定義欄位之外主要做了兩件事。
①由於在我的SDK里沒有找到判空的方法,所以給string寫一個擴展方法IsNullOrEmpty;
②每一個博客對象都應該是完整的即每個欄位都是必填項,因為使用的是Redis存儲也就只能在C#中判斷必填項了;
這裡還說到另外一個問題,通常情況下需要建立文章縮略名稱和文章ID的關聯關係。這樣做的目的是為了確保文章的唯一性和符合網站網址規範上的一些操作。但是現在還不打算啟用這一操作。
糾結的入庫方式
本來我想的是在控制器中獲得數據然後調用RedisCommon的方法獲取一個連接對象添加一下就行了,但是代碼寫了很長一行才搞定exist的判斷,有點忍不了。還是決定把所有數據都扔給RedisCommon類叫他來完成這件事情。
首先一打開這個類我就決定先寫一個擴展方法(我可能最近比較迷戀寫擴展),和之前的ToDic正好相反,這次是把Dictionary
public static HashEntry[] ToHashEntry(this Dictionary<string, string> dic) { List<HashEntry> list = new List<HashEntry>(); foreach (var item in dic.Keys) { list.Add(new HashEntry(item, dic[item])); } return list.ToArray(); }
寫這個方法的目的是感覺以後會有很多的字典轉成HashEntry數組的情況,使用起來可能比較方便,然後就可以開心的寫入庫方法了。
public static void SetBLog(BLogModel bLog) { string postCount = GetData().StringIncrement("post:count").ToString(); Dictionary<string, string> dic = new Dictionary<string, string>(); dic.Add("title", bLog.title); dic.Add("author", bLog.author); dic.Add("time", bLog.time.ToString()); dic.Add("content", bLog.content); try { GetData().HashSet("post:"+postCount, dic.ToHashEntry()); } catch (Exception e) { throw e; } }
雖然還不想使用縮略名稱和ID關聯關係的這個功能,但還是寫上吧,省的以後費事。
public static bool SetSlugToId(string slug, string id) { if (!GetData().HashExists("slug.to.id", slug)) { GetData().HashSet("slug.to.id", slug, id); return true; } return false; }
集成log4net
log4net就很熟悉了,雖然可以把各種日誌都打到資料庫中,但是感覺最實用的還是日誌文件。
所以起手式還是dotnet cli命令dotnet add package log4net
這裡提一下,準備以後有時間瞭解一下bower,如果可以搞定的話,就玩一下。
然後操作步驟如下文
- 創建一個文件,起名叫log4net.config。
- 在項目起始方法中載入log4net。
- 創建一個全局異常類,其實可以不用這個類的,但是感覺還不錯就加進來了。
log4net.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <!-- This section contains the log4net configuration settings --> <log4net> <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender"> <file value="logfile/" /> <appendToFile value="true" /> <rollingStyle value="Composite" /> <staticLogFileName value="false" /> <datePattern value="yyyyMMdd'.log'" /> <maxSizeRollBackups value="10" /> <maximumFileSize value="1MB" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" /> </layout> </appender> <!-- Setup the root category, add the appenders and set the default level --> <root> <level value="ALL" /> <appender-ref ref="RollingLogFileAppender" /> </root> </log4net> </configuration>
在Startup文件中載入log4net,其實比原來就多加了三行代碼。
這裡需要說的就是創建靜態ILoggerRepository的時候需要導包,最機智的方法自然就是dotnet new sln創建一個解決方案,把項目填進去,用VS解決這件事。
public static ILoggerRepository repository{get;set;} public Startup(IConfiguration configuration) { Configuration = configuration; //載入log4net日誌配置文件 repository = LogManager.CreateRepository("NETCoreRepository"); XmlConfigurator.Configure(repository, new FileInfo("log4net.config")); }
全局異常類
using log4net; using Microsoft.AspNetCore.Mvc.Filters; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Blog { public class HttpGlobalExceptionFilter : IExceptionFilter { private ILog log = LogManager.GetLogger(Startup.repository.Name, typeof(HttpGlobalExceptionFilter)); public void OnException(ExceptionContext context) { log.Error(context.Exception); } } }
log的使用方式,一般情況下吧log對象放在基類中就夠用了。
protected static ILog log = LogManager.GetLogger(Startup.repository.Name, typeof(HttpGlobalExceptionFilter)); log.Info("log test fisish");