Step by step create ASP.NET MVC5 program [Repository+Autofac+Automapper+SqlSugar] (9)

Keywords: ASP.NET MySQL Programming SQL

Preface

Hello, boys and girls

I am Rector, a practitioner who focuses on. NET developer community building.

First of all, I want to find an inadequate reason for updating this series of articles two Fridays apart: Rector's recent work, various family firms, I hope you will understand.

Points of knowledge in this paper

Back to the theme of this article, or about a series of articles: "Step by step to create ASP.NET MVC5 program Repository+Autofac+Automapper+SqlSugar", this article will share the main contents of:

  • Layout and Making of Responsive Website Home Page
  • Presentation of lists of articles
  • Article Details Page

Front-end layout and production

Layout and Making of Responsive Website Home Page

In the pages of the previous series of articles in this article, the homepage of our website and the list page of articles have no application style. This article will share the production of the homepage, which contains the following contents:

  • Head navigation
  • Article list
  • Bootstrap Responsive Layout

The final home page rendering is as follows:

CSS style

First, create a resource folder named: resources in the project [TsBlog.Frontend], create a CSS style folder in it, and create a new style file named: site.css. At this time, the directory structure is as follows:

The style code is as follows:

site.css

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td { border: 0; margin: 0; padding: 0; }

body { color: #333; font-size: 14px; font-family: -apple-system,'helvetica neue', helvetica,"Helvetica Neue",Helvetica,Arial,"PingFang SC","Hiragino Sans GB","WenQuanYi Micro Hei","Microsoft Yahei",sans-serif; line-height: 22px; width: 100%; height: 100%; }
h1, h2, h3, h4, h5, h6 { clear: both; font-weight: normal; }
ol, ul { list-style: none; }
blockquote { quotes: none; border-left: 5px solid #eee; font-size: 14px; margin: 10px 0; padding: 10px 20px; }
    blockquote:before, blockquote:after { content: ''; content: none; }

a { color: #4484ce; }

/*bootstrap override*/
.btn { border-radius: 2px !important; }
.btn-primary { background-color: #4484CE !important; }
    .btn-primary:hover { background-color: #3A77BE !important; }

.navbar-nav a { color: #333 !important; }
    .navbar-nav > .active > a, .navbar-nav > .active > a:focus, .navbar-nav > .active > a:hover, .navbar-nav a:hover { border-radius: 2px; background-color: #e7e7e7 !important; }
/*site begin*/
.ts-navbar .navbar-nav { height: 50px; vertical-align: middle; line-height: 50px; }
    .ts-navbar .navbar-nav li { vertical-align: middle; line-height: 50px; float: none; display: inline-block; }
.ts-navbar .dropdown li { display: block; }
.ts-navbar .navbar-nav li a { padding: 8px 15px; }
.navbar-brand { height: auto; }
a.nav-btn-login { color: #fff !important; }
    a.nav-btn-login:hover { background-color: #3A77BE !important; color: #fff !important; }
.navbar-profile { margin-right: 0; }
/*home begin*/
.jumbotron h1 { margin-bottom: 15px; }
.jumbotron p { line-height: 28px; }
.post-title { display: block; font-size: 16px; font-weight: 600; border-bottom: 2px solid #e7e7e7; padding-bottom: 8px; }
.post-item-box { margin-bottom: 15px; }
    .post-item-box li { margin-top: 15px; margin-bottom: 15px; padding-top: 10px; padding-bottom: 10px; }
        .post-item-box li h2 { font-size: 16px; font-weight: 500; margin-bottom: 10px; }
.post-item-summary { color: #555; }
.footer-box { padding: 15px; margin-top: 15px; border-top: 1px solid #e7e7e7; }


/*post details*/

.article-content { padding-top: 15px; padding-bottom: 15px; }
    .article-content p { margin-top: 20px; margin-bottom: 20px; }
.article-fixed p { margin-top: 0; margin-bottom: 5px; }
.article-content h1, .article-content h2, .article-content h3, .article-content h4, .article-content h5, .article-content h6 { margin: 15px 0 10px; }
.article-content h1, .article-content h2 { border-bottom: 1px solid #eee; padding-bottom: 10px; }
.article-content h2 { font-size: 1.75em; line-height: 1.2 }
.article-content h3 { font-size: 1.5em; line-height: 1.2 }
.article-content blockquote { background: #f6f6f6 none repeat scroll 0 0; border-left: 2px solid #009a61; color: #555; font-size: 1em; }
.cloud-tags .cloud-tag-item { border: 1px solid #efefef; background-color: #f7f7f7; padding: 5px 10px; }
.cloud-tags .cloud-tag-item, .side-bar-article-list, .article-content { word-break: break-all; word-wrap: break-word; white-space: normal; }
    .article-content pre { background-attachment: scroll; background-clip: border-box; background-color: #f6f6f6; border: medium none; line-height: 1.45; max-height: 35em; overflow: auto; padding: 1em; position: relative; margin-bottom: 15px; margin-top: 15px; }
    .article-content ul li { padding-left: 15px; list-style: inside; }
    .article-content ul li { padding-left: 15px; list-style: inside; }
    .article-content ul, .article-content ol { margin-left: 3em; padding-left: 0; }
        .article-content ul li, .article-content ol li { margin: .3em 0; }

The above stylesheets are used in this article. You just need to copy them.

Head navigation

Open the view file [... TsBlog src Presentation TsBlog. Frontend Views Home Index. cshtml], and first make the header navigation bar, where the HTML code of the navigation bar is as follows:

<nav class="navbar navbar-default navbar-static-top ts-navbar">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="~/">TSBLOG</a>
            </div>
            <div id="navbar" class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li class="active"><a href="~/">Home</a></li>
                    <li class="dropdown">
                        <a href="#"Class=" dropdown-toggle "data-toggle=" dropdown "role=" button "aria-haspopup=" true "aria-expanded=" false "> classification navigation < class=" caret "> </span> </a>
                        <ul class="dropdown-menu">
                            <li class="dropdown-header">Backend development</li>
                            <li><a href="http://2sharings.com/category/csharp-development "> C# Programming </a> </li>"
                            <li><a href="http://2sharings.com/category/dot-net">.NET Programming </a> </li>"
                            <li><a href="http://2sharings.com/category/asp-dot-net">ASP.NET</a></li>
                            <li><a href="http://2sharings.com/category/asp-net-mvc">ASP.NET MVC</a></li>
                            <li><a href="http://2sharings.com/category/asp-dotnet-core">ASP.NET Core</a></li>
                            <li><a href="http://2sharings.com/category/winform">Winform</a></li>
                            <li role="separator" class="divider"></li>
                            <li class="dropdown-header">data base</li>
                            <li><a href="http://2sharings.com/category/mysql">MySQL</a></li>
                            <li><a href="http://2sharings.com/category/sql-server">SQL Server</a></li>
                            <li><a href="http://2sharings.com/category/sqlite">SqLite</a></li>
                        </ul>
                    </li>
                    <li><a href="~/home/about">About us</a></li>
                    <li><a href="~/home/contact">Contact us</a></li>
                </ul>
                <ul class="nav navbar-nav navbar-right navbar-profile">
                    <li><a href="~/account/register">Free registration</a></li>
                    <li><a class="btn btn-primary nav-btn-login" href="~/account/login">Login immediately</a></li>
                </ul>
            </div><!--/.nav-collapse -->
        </div>
    </nav>

Text HTML

The first part of the body is a BANNER. In this area, you can put some important descriptive information about the site, or you can put some rolling advertisement pictures and so on. You can deal with them according to your own needs.

The second part is an article list area, which lists 20 articles recently published by the website. The HTML code of the body is as follows:

<div class="container">
        <div class="jumbotron">
            <h1> Little Partner, Hello </h1>.
            <p> Welcome to Rector's ASP.NET MVC 5 series article tutorials. Here, Rector will work with you step by step to create a WEB application that integrates Repository+Autofac+Automapper+SqlSugar. </p>
            Are you ready? </p>
            <p>......</p>
            <p>Let's start exploring ASP.NET MVC 5 applications!! </p>
        </div>
        <strong class="post-title">list of articles (@(Model.Count()) </strong>
        <ul class="list-unstyled post-item-box">
            @foreach (var p in Model)
            {
                <li>
                    <h2><a href="~/post/details/@p.Id">@p.Title</a></h2>
                    <p class="post-item-summary">@p.Summary... <a href="~/post/details/@p.Id">Read the full text </a> </p>
                </li>
            }
        </ul>
    </div>

footer

At the end of the page is the footer, which contains relatively simple copyright information. The HTML code is as follows:

<footer class="footer-box">
        <div class="container">
            //Copyright - copy; @ (DateTime. Now. Year)
        </div>
    </footer>

The complete HTML code on the home page is as follows:

Index.cshtml

@model IEnumerable<TsBlog.ViewModel.Post.PostViewModel>
@{
    Layout = null;
}
<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>ASP.NET MVC 5 Series of article tutorials--home page | TSBLOG</title>
    <link href="~/Content/bootstrap.min.css" rel="stylesheet" />
    <link href="~/resources/css/site.css" rel="stylesheet" />

</head>
<body>
    <nav class="navbar navbar-default navbar-static-top ts-navbar">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="~/">TSBLOG</a>
            </div>
            <div id="navbar" class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li class="active"><a href="~/">Home</a></li>
                    <li class="dropdown">
                        <a href="#"Class=" dropdown-toggle "data-toggle=" dropdown "role=" button "aria-haspopup=" true "aria-expanded=" false "> classification navigation < class=" caret "> </span> </a>
                        <ul class="dropdown-menu">
                            <li class="dropdown-header">Backend development</li>
                            <li><a href="http://2sharings.com/category/csharp-development "> C# Programming </a> </li>"
                            <li><a href="http://2sharings.com/category/dot-net">.NET Programming </a> </li>"
                            <li><a href="http://2sharings.com/category/asp-dot-net">ASP.NET</a></li>
                            <li><a href="http://2sharings.com/category/asp-net-mvc">ASP.NET MVC</a></li>
                            <li><a href="http://2sharings.com/category/asp-dotnet-core">ASP.NET Core</a></li>
                            <li><a href="http://2sharings.com/category/winform">Winform</a></li>
                            <li role="separator" class="divider"></li>
                            <li class="dropdown-header">data base</li>
                            <li><a href="http://2sharings.com/category/mysql">MySQL</a></li>
                            <li><a href="http://2sharings.com/category/sql-server">SQL Server</a></li>
                            <li><a href="http://2sharings.com/category/sqlite">SqLite</a></li>
                        </ul>
                    </li>
                    <li><a href="~/home/about">About us</a></li>
                    <li><a href="~/home/contact">Contact us</a></li>
                </ul>
                <ul class="nav navbar-nav navbar-right navbar-profile">
                    <li><a href="~/account/register">Free registration</a></li>
                    <li><a class="btn btn-primary nav-btn-login" href="~/account/login">Login immediately</a></li>
                </ul>
            </div><!--/.nav-collapse -->
        </div>
    </nav>
    <div class="container">
        <div class="jumbotron">
            <h1>Hello, buddy</h1>
            <p>Welcome to Rector Of ASP.NET MVC 5 A series of article tutorials. Ad locum, Rector Create an integration step by step with you Repository+Autofac+Automapper+SqlSugar Of WEB Applications.</p>
            <p>Are you ready?</p>
            <p>......</p>
            <p>Let's get started. ASP.NET MVC 5 Explore the application!!!</p>
        </div>
        <strong class="post-title">Article list(@(Model.Count())piece)</strong>
        <ul class="list-unstyled post-item-box">
            @foreach (var p in Model)
            {
                <li>
                    <h2><a href="~/post/details/@p.Id">@p.Title</a></h2>
                    <p class="post-item-summary">@p.Summary ... <a href="~/post/details/@p.Id">Read the whole passage</a></p>
                </li>
            }
        </ul>
    </div>
    <footer class="footer-box">
        <div class="container">
            Copyright &copy; @(DateTime.Now.Year)
        </div>
    </footer>
    <script src="~/Scripts/jquery-3.2.1.min.js"></script>
    <script src="~/Scripts/bootstrap.min.js"></script>
</body>
</html>

Back-end Interface and Implementation

After completing the layout and production of front-end pages, we need back-end programs to provide interfaces and services for front-end pages to call, such as the view model in the Home View:

@model IEnumerable<TsBlog.ViewModel.Post.PostViewModel>

The Storage Interface and Realization of Articles

Open the file [IPostRepository.cs] and add a new interface method: FindHomePagePosts, code as follows:

using System.Collections.Generic;
using TsBlog.Domain.Entities;

namespace TsBlog.Repositories
{
    public interface IPostRepository : IRepository<Post>
    {
        /// <summary>
        /// Query Home Page Articles List
        /// </summary>
        /// <param name="limit">the number of records to query </param>
        /// <returns></returns>
        IEnumerable<Post> FindHomePagePosts(int limit = 20);
    }
}

Open the file [PostRepository.cs] and implement the corresponding interface method: FindHomePagePosts, code as follows:

using SqlSugar;
using System.Collections.Generic;
using TsBlog.Domain.Entities;

namespace TsBlog.Repositories
{
    /// <summary>
    /// Database Operations Classes for POST Tables
    /// </summary>
    public class PostRepository : GenericRepository<Post>, IPostRepository
    {
        #region Implementation of IPostRepository

        /// <summary>
        /// Query Home Page Articles List
        /// </summary>
        /// <param name="limit">the number of records to query </param>
        /// <returns></returns>
        public IEnumerable<Post> FindHomePagePosts(int limit = 20)
        {
            using (var db = DbFactory.GetSqlSugarClient())
            {
                var list = db.Queryable<Post>().OrderBy(x => x.Id, OrderByType.Desc).Take(limit).ToList();
                return list;
            }
        }
    }
    #endregion
}

Article Service Interface and Implementation

Open the file [IPostService.cs] and add a new interface method: FindHomePagePosts, code as follows:

using System.Collections.Generic;
using TsBlog.Domain.Entities;

namespace TsBlog.Services
{
    public interface IPostService : IService<Post>
    {
        /// <summary>
        /// Query Home Page Articles List
        /// </summary>
        /// <param name="limit">the number of records to query </param>
        /// <returns></returns>
        IEnumerable<Post> FindHomePagePosts(int limit = 20);
    }
}

Open the file [PostService.cs], and implement the corresponding interface method: FindHomePagePosts, code as follows:

using System.Collections.Generic;
using TsBlog.Domain.Entities;
using TsBlog.Repositories;

namespace TsBlog.Services
{
    public class PostService : GenericService<Post>, IPostService
    {
        private readonly IPostRepository _repository;
        public PostService(IPostRepository repository) : base(repository)
        {
            _repository = repository;
        }


        #region Implementation of IPostService

        /// <summary>
        /// Query Home Page Articles List
        /// </summary>
        /// <param name="limit">the number of records to query </param>
        /// <returns></returns>
        public IEnumerable<Post> FindHomePagePosts(int limit = 20)
        {
            return _repository.FindHomePagePosts(limit);
        }

        #endregion
    }
}

Additional modifications: The FindListByClause method in the warehouse interface is reconstructed, and the orderBy parameter is set as an empty parameter, which is implemented as follows:

/// <summary>
/// Query data according to conditions
/// </summary>
/// <param name="predicate">conditional expression tree </param>
/// <param name="orderBy">sort </param>
/// returns > generic entity set </returns >
IEnumerable<T> FindListByClause(Expression<Func<T, bool>> predicate, string orderBy = "");

Corresponding implementations in the corresponding modified generic warehouse:

/// <summary>
/// Query data according to conditions
/// </summary>
/// <param name="predicate">conditional expression tree </param>
/// <param name="orderBy">sort </param>
/// returns > generic entity set </returns >
public IEnumerable<T> FindListByClause(Expression<Func<T, bool>> predicate, string orderBy = "")
{
    using (var db = DbFactory.GetSqlSugarClient())
    {
        var query = db.Queryable<T>().Where(predicate);
        if (!string.IsNullOrEmpty(orderBy))
        {
            query = query.OrderBy(orderBy);
        }
        var entities = query.ToList();
        return entities;
    }
}

Similarly, corresponding modifications have been made in the service layer:

FindListByClause interface method in IService.cs file:

/// <summary>
/// Query data according to conditions
/// </summary>
/// <param name="predicate">conditional expression tree </param>
/// <param name="orderBy">sort </param>
/// returns > generic entity set </returns >
IEnumerable<T> FindListByClause(Expression<Func<T, bool>> predicate, string orderBy = "");

Generic service class: FindListByClause method implementation in GenericService.cs:

/// <summary>
/// Query data according to conditions
/// </summary>
/// <param name="predicate">conditional expression tree </param>
/// <param name="orderBy">sort </param>
/// returns > generic entity set </returns >
public IEnumerable<T> FindListByClause(Expression<Func<T, bool>> predicate, string orderBy = "")
{
    return _repository.FindListByClause(predicate, orderBy);
}

Before we start processing the HomeController controller, we first create two new help classes in the project [TsBlog.Core]: HtmlHelper.cs and StringHelper.cs. The codes are as follows:

HtmlHelper.cs:

using System.Text.RegularExpressions;

namespace TsBlog.Core
{
    public static class HtmlHelper
    {
        #region removes all tags from HTML, leaving only plain text.
        /// <summary>
        /// Remove all tags from HTML, leaving only plain text
        /// </summary>
        /// <param name="strHtml"></param>
        /// <returns></returns>
        public static string CleanHtml(this string strHtml)
        {
            if (string.IsNullOrEmpty(strHtml)) return strHtml;
            //Delete script
            strHtml = Regex.Replace(strHtml, "(\\<script(.+?)\\</script\\>)|(\\<style(.+?)\\</style\\>)", "", RegexOptions.IgnoreCase | RegexOptions.Singleline);
            //delete a tap
            var r = new Regex(@"<\/?[^>]*>", RegexOptions.IgnoreCase);
            Match m;
            for (m = r.Match(strHtml); m.Success; m = m.NextMatch())
            {
                strHtml = strHtml.Replace(m.Groups[0].ToString(), "");
            }
            return strHtml.Trim();
        }

        #endregion
    }
}

StringHelper.cs:

using System;

namespace TsBlog.Core
{
    public static class StringHelper
    {
        #region
        /// <summary>
        /// Intercept a string of specified length
        /// </summary>
        /// <param name="str">original string </param>
        ///<param name="strLength">The length of the string to be retained </param>
        /// <returns></returns>
        public static string CutStrLength(this string str, int strLength)
        {
            var strNew = str;
            if (string.IsNullOrEmpty(strNew)) return strNew;
            var strOriginalLength = strNew.Length;
            if (strOriginalLength > strLength)
            {
                strNew = strNew.Substring(0, strLength) + "...";
            }
            return strNew;
        }

        #endregion

        #region
        /// <summary>
        /// Intercept a string of specified length
        /// </summary>
        /// <param name="str">original string </param>
        ///<param name="strLength">The length of the string to be retained </param>
        /// <param name="endWithEllipsis">is or ends with an ellipsis (...)</param>
        /// <returns></returns>
        public static string CutStrLength(string str, int strLength, bool endWithEllipsis)
        {
            string strNew = str;
            if (!strNew.Equals(""))
            {
                int strOriginalLength = strNew.Length;
                if (strOriginalLength > strLength)
                {
                    strNew = strNew.Substring(0, strLength);
                    if (endWithEllipsis)
                    {
                        strNew += "...";
                    }
                }
            }
            return strNew;
        }

        #endregion

        #region truncation string (complete words can be retained)
        /// <summary>
        //Truncated string (complete words can be retained)
        /// </summary>
        ///<param name="valueToTruncate">String to be processed </param>
        /// <param name="maxLength">number of characters </param>
        /// <param name="options">truncation option </param>
        /// <returns></returns>
        public static string TruncateString(this string valueToTruncate, int maxLength, TruncateOptions options)
        {
            if (valueToTruncate == null)
            {
                return "";
            }

            if (valueToTruncate.Length <= maxLength)
            {
                return valueToTruncate;
            }

            var includeEllipsis = (options & TruncateOptions.IncludeEllipsis) ==
                    TruncateOptions.IncludeEllipsis;
            var finishWord = (options & TruncateOptions.FinishWord) ==
                    TruncateOptions.FinishWord;
            var allowLastWordOverflow =
              (options & TruncateOptions.AllowLastWordToGoOverMaxLength) ==
              TruncateOptions.AllowLastWordToGoOverMaxLength;

            var retValue = valueToTruncate;

            if (includeEllipsis)
            {
                maxLength -= 1;
            }

            var lastSpaceIndex = retValue.LastIndexOf(" ",
              maxLength, StringComparison.CurrentCultureIgnoreCase);

            if (!finishWord)
            {
                retValue = retValue.Remove(maxLength);
            }
            else if (allowLastWordOverflow)
            {
                var spaceIndex = retValue.IndexOf(" ",
                  maxLength, StringComparison.CurrentCultureIgnoreCase);
                if (spaceIndex != -1)
                {
                    retValue = retValue.Remove(spaceIndex);
                }
            }
            else if (lastSpaceIndex > -1)
            {
                retValue = retValue.Remove(lastSpaceIndex);
            }

            if (includeEllipsis && retValue.Length < valueToTruncate.Length)
            {
                retValue += "...";
            }
            return retValue;
        }

        #endregion
    }

    #Enumeration for region truncation strings
    /// <summary>
    //Enumeration for truncating strings
    /// </summary>
    [Flags]
    public enum TruncateOptions
    {
        /// <summary>
        /// No treatment
        /// </summary>
        None = 0x0,
        /// <summary>
        /// Keep the whole word
        /// </summary>
        FinishWord = 0x1,
        /// <summary>
        //Allow the last word to exceed the maximum length limit
        /// </summary>
        AllowLastWordToGoOverMaxLength = 0x2,
        /// <summary>
        /// String followed by ellipsis
        /// </summary>
        IncludeEllipsis = 0x4
    }
    #endregion
}

Add a new attribute to the article view file [... TsBlog src Libraries TsBlog.ViewModel Post PostViewModel. cs] in the item [TsBlog.ViewModel]: Summary, where PostViewModel is like this:

namespace TsBlog.ViewModel.Post
{
    /// <summary>
    ///Bowen View Entity Class
    /// </summary>
    public class PostViewModel
    {
        /// <summary>
        /// ID
        /// </summary>
        public int Id { get; set; }
        /// <summary>
        //Title
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        //Content
        /// </summary>
        public string Content { get; set; }
        /// <summary>
        //Author ID
        /// </summary>
        public string AuthorId { get; set; }
        /// <summary>
        ///Author's name
        /// </summary>
        public string AuthorName { get; set; }
        /// <summary>
        ///Creation time
        /// </summary>
        public string CreatedAt { get; set; }
        /// <summary>
        ///Release time
        /// </summary>
        public string PublishedAt { get; set; }
        /// <summary>
        ///Whether the logo has been deleted
        /// </summary>
        public string IsDeleted { get; set; }
        /// <summary>
        ///Is display allowed?
        /// </summary>
        public bool AllowShow { get; set; }
        /// <summary>
        //Browse volume
        /// </summary>
        public int ViewCount { get; set; }

        /// <summary>
        //Abstract
        /// </summary>
        public string Summary { get; set; }
    }
}

Create a folder named Extensions in the project [TsBlog.Frontend], and create a static extension class for the article [...\ TsBlog.Frontend\ Extensions PostExtension. cs], while implementing the following static extension methods:

using TsBlog.Core;
using TsBlog.ViewModel.Post;

namespace TsBlog.Frontend.Extensions
{
    public static class PostExtension
    {
        /// <summary>
        /// View Entities for Formatting Articles
        /// </summary>
        /// <param name="model">article view entity class </param>
        /// <returns></returns>
        public static PostViewModel FormatPostViewModel(this PostViewModel model)
        {
            if (model == null)
            {
                return null;
            }

            model.Summary = model.Content
                .CleanHtml()            //Remove all HTML Tags
                .TruncateString(200, TruncateOptions.FinishWord | TruncateOptions.AllowLastWordToGoOverMaxLength);     //Truncate the specified length as a summary of the article
            return model;
        }
    }
}

Home Controller

In the home page controller [... TsBlog. Frontend Controllers HomeController. cs], we use the method of article service interface to query the list of articles on the home page. The code is as follows:

using System.Linq;
using System.Web.Mvc;
using TsBlog.AutoMapperConfig;
using TsBlog.Frontend.Extensions;
using TsBlog.Services;

namespace TsBlog.Frontend.Controllers
{
    public class HomeController : Controller
    {
        /// <summary>
        /// Article Service Interface
        /// </summary>
        private readonly IPostService _postService;
        public HomeController(IPostService postService)
        {
            _postService = postService;
        }
        /// <summary>
        //Home page
        /// </summary>
        /// <returns></returns>
        public ActionResult Index()
        {
            var list = _postService.FindHomePagePosts();
            var model = list.Select(x => x.ToModel().FormatPostViewModel());
            return View(model);
        }
    }
}

OK, so far, our homepage production and data binding have been completed, run according to F5, we can see the effect of the homepage shown at the beginning of this article.

Article Details Page [Post Controller]

Create a new controller named PostController and add the following code:

using System.Web.Mvc;
using TsBlog.AutoMapperConfig;
using TsBlog.Services;

namespace TsBlog.Frontend.Controllers
{
    public class PostController : Controller
    {
        /// <summary>
        /// Article Service Interface
        /// </summary>
        private readonly IPostService _postService;

        public PostController(IPostService postService)
        {
            _postService = postService;
        }

        /// <summary>
        /// Details of the article
        /// </summary>
        /// <param name="id">article ID</param>
        /// <returns></returns>
        public ActionResult Details(int id)
        {
            var post = _postService.FindById(id);
            var model = post.ToModel();
            return View(model);
        }
    }
}

Add the view of the article details page [...\ TsBlog. Frontend Views Post Details. cshtml], and add the following view HTML code:

@model TsBlog.ViewModel.Post.PostViewModel
@{
    Layout = null;
}
<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>@(Model.Title) | TSBLOG</title>
    <link href="~/Content/bootstrap.min.css" rel="stylesheet" />
    <link href="~/resources/css/site.css" rel="stylesheet" />
</head>
<body>
    <nav class="navbar navbar-default navbar-static-top ts-navbar">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="~/">Website name</a>
            </div>
            <div id="navbar" class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a href="~/">Home</a></li>
                    <li class="dropdown">
                        <a href="#"Class=" dropdown-toggle "data-toggle=" dropdown "role=" button "aria-haspopup=" true "aria-expanded=" false "> classification navigation < class=" caret "> </span> </a>
                        <ul class="dropdown-menu">
                            <li class="dropdown-header">Backend development</li>
                            <li><a href="http://2sharings.com/category/csharp-development "> C# Programming </a> </li>"
                            <li><a href="http://2sharings.com/category/dot-net">.NET Programming </a> </li>"
                            <li><a href="http://2sharings.com/category/asp-dot-net">ASP.NET</a></li>
                            <li><a href="http://2sharings.com/category/asp-net-mvc">ASP.NET MVC</a></li>
                            <li><a href="http://2sharings.com/category/asp-dotnet-core">ASP.NET Core</a></li>
                            <li><a href="http://2sharings.com/category/winform">Winform</a></li>
                            <li role="separator" class="divider"></li>
                            <li class="dropdown-header">data base</li>
                            <li><a href="http://2sharings.com/category/mysql">MySQL</a></li>
                            <li><a href="http://2sharings.com/category/sql-server">SQL Server</a></li>
                            <li><a href="http://2sharings.com/category/sqlite">SqLite</a></li>
                        </ul>
                    </li>
                    <li><a href="~/home/about">About us</a></li>
                    <li><a href="~/home/contact">Contact us</a></li>
                </ul>
                <ul class="nav navbar-nav navbar-right navbar-profile">
                    <li><a href="~/account/register">Free registration</a></li>
                    <li><a class="btn btn-primary nav-btn-login" href="~/account/login">Login immediately</a></li>
                </ul>
            </div>
        </div>
    </nav>
    <div class="container">
        <h1 class="post-title">@Model.Title</h1>
        <article class="article-content">
            @Html.Raw(Model.Content)
        </article>
    </div>
    <footer class="footer-box">
        <div class="container">
            Copyright &copy; @(DateTime.Now.Year)
        </div>
    </footer>
    <script src="~/Scripts/jquery-3.2.1.min.js"></script>
    <script src="~/Scripts/bootstrap.min.js"></script>
</body>
</html>

OK, today's issue about the layout and production of the homepage and article details page is shared here, hoping to help you understand ASP.NET MVC WEB application development.

Source Hosting Address for this issue: Please go to the first address of the article to get the uuuuuuuuuu Step by step create ASP.NET MVC5 program [Repository+Autofac+Automapper+SqlSugar] (9)>
See the database script file in the directory: TsBlog document scripts mysql v1.9\

If you like Rector's article series, please give me a big compliment.

** If you are not addicted to the tutorial, you are welcome to join the official QQ group of Tuheng. 483350228. If you have problems in running the program restored according to the tutorial, please refer to the source code corresponding adjustment and modification in this issue. You are also welcome to join the QQ group. What do you know? * * * * *

Thank you for your patience. This series is not finished yet. See you next time.

This article is first published in: Picture sharing network <Step by step create ASP.NET MVC5 program [Repository+Autofac+Automapper+SqlSugar] (9)>

Posted by WM_Programmer_noob on Tue, 25 Dec 2018 19:21:06 -0800