目前的進度
首頁文章列表 (Controller & View)
內文
連接DB
閱讀文章的基本功能已經大致完成,但還沒有文章,所以現在開始著手寫連接DB的部份
前文提到當我們request /blog或者/blog/{id} 時,會執行BlogFactory的2個Method,從database裡面抓取Blog數據,傳給Views
public class BlogController : Controller
{
public IActionResult Index()
{
List<Models.Blog> blogs = BlogFactory.GetBlogsByPage(1);
ViewData["Title"] = "";
return View(blogs);
}
[Route("/blog/{id:int}")]
public IActionResult Individual(int id)
{
ViewData["BlogId"] = id;
List<Models.Blog> blogs = BlogFactory.GetBlog(id);
if (blogs.Count > 0)
{
ViewData["Title"] = blogs[0].Title;
return View("Detail", blogs[0]);
}
else
{
return Redirect("~/");
}
}
}
以下是BlogFactory內容
using Dapper;
namespace Blog.Models
{
public static class BlogFactory
{
static ExternalJsonConfigReader configReader = new ExternalJsonConfigReader(@"C:Configconfig.json");
static string blogConnStr = configReader.GetValue("BlogConnStr");
static int blogPerPage = 10;
public static List<Blog> GetBlogs()
{
using (var connection = new SqlConnection(blogConnStr))
{
return connection.Query<Blog>("select * from GetVisibleBlogs() order by id desc").ToList();
}
}
/// <summary>
/// using int as parameter can avoid sql injection too. how brilliant me!
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public static List<Blog> GetBlog(int id)
{
using (var connection = new SqlConnection(blogConnStr))
{
return connection.Query<Blog>($"select * from GetVisibleBlogs() where id=@id", new { id = id }).ToList();
}
}
public static BlogIdPair GetBlogNextBlog(int id)
{
try
{
using (var connection = new SqlConnection(blogConnStr))
{
return connection.QuerySingle<BlogIdPair>($"select * from GetBlogNextBlog(@id)", new { id = id });
}
}
catch (Exception ex)
{
return null;
}
}
public static BlogIdPair GetBlogPrevBlog(int id)
{
try
{
using (var connection = new SqlConnection(blogConnStr))
{
return connection.QuerySingle<BlogIdPair>($"select * from GetBlogPrevBlog(@id)", new { id = id });
}
}
catch (Exception ex)
{
return null;
}
}
}
}
目前先提供4個method,分別是供首頁用的GetBlogs()、內文用的GetBlog(int id)、和導航的GetBlogNextBlog()和GetBlogPrevBlog()
當我們要連接Database時,首先要建立一個SqlConnection,傳一個connectionString進去,這個connectionString就是database的登入資訊,包含有db的hostname、port、登入方式、帳密等,不同資料庫會有不同的寫法,我家在用的主要是微軟sql server的Community版 - sql express,它的connection string長這樣:
"Data Source={ip或者hostname};Initial Catalog={db名稱};Persist Security Info=True;User ID=帳號帳號;Password=密碼密碼"
如果你資料庫就建在本機,而且是用windows的話,可以直接用windows目前使用者登入,不用填帳密就不怕被人偷看到
"Data Source=127.0.0.1;Initial Catalog={DB名稱};Integrated Security=True"
和DB connect後就可以開始用這個connection操作DB
using (var connection = new SqlConnection(blogConnStr))
{
return connection.Query<Blog>("select * from GetVisibleBlogs() order by id desc").ToList();
}
SqlConnection.Query()這個method讓用家執行裡面的Sql Query,比如select * from table那些,它會傳回一個IEnumerable<dynamic>,裡面裝著Query的結果。connection.Query<Blog>這裡則是dapper提供的generic type方法,Dapper會自動從傳回的結果中對比Blog物件的屬性,如果名字和datatype都符合,就自動填入Blog物件中。
public IActionResult Index()
{
List<Models.Blog> blogs = BlogFactory.GetBlogsByPage(1);
ViewData["Title"] = "";
return View(blogs);
}
@model Blog
@model IEnumerable<Blog>
還記得Views/Blog/index.cshtml和Views/Blog/Detail.cshtml的第一行分別是以上這兩句嗎?
@model表示這個View能接受什麼類型的object作parameter
除了使用@model之外,也可以填寫ViewData這個Dictionary<string, object> (或者ViewBag)來傳送資料進去View
兩者的分別在於model是強型別,ViewData則沒規定,可以亂來,但這屬於anti-pattern,盡量不用。
當拿到List<Blog>後,就填入Views中再return,request就能收到它產生的html網頁內容。
惡耗! 網站剛上線就發現本來在用的SSL供應商取消了免費政策!
加入了Collection功能