上章节大家早就定制好动态配置的菜系,用户登录网站的率先步便是进入首页内容,那我们先搭建转眼大家的首页内容。想着自个儿的网站内容首要是个体博客类型,所以,首页就显得博主本身的一些主干消息吗,哈哈。当然,做成静态的界面很不难,直接将音信填进html中就行了,基本没有啥技术含量,这大家那边要做成可安顿的:将个人新闻配置在json文件中(也能够储存在数据库,考虑音信内容结构的不得预期性和易变性,那里不应用数据库保存)。那样,现在大家要立异主页上的消息时,就毫无编写翻译公布网站,只要修改对应的json配置文件即可。

.NET Core 配置机制介绍

波及“配置”二字,大家脑海中会即刻显示出三个特出文件,那正是我们再熟识但是的app.config和web.config,平素以来大家早已习惯了将结构化的布局音信定义在那四个文本之中。到了.NET
Core的时候,很多大家习惯的东西都产生了改动,个中也包涵定义配置的章程。有趣味的校友能够活动官方文书档案介绍:.net
core
配置

.NET
Core不仅扶助以键-值对的方式、结构化的花样读取相关的配置新闻(那里和谐去钻探,不在祥述),更关键的是,近来得以将概念的结构化配置绑定为对象。在此之前大家必须逐一的读取配置消息,假若布置项太多以来,读取配置项其实是一项11分麻烦的办事。将来只用再定义对应组织的Option对象,框架自动帮大家绑定配置消息到那几个指标,大家一直访问对象中的属性即可。除此之外,.NET
Core选取依赖注入的主意来采用Option模型,那样大家就和福利的在急需的地点使用安顿新闻了。

接下去看具体怎么利用,首先,在品种中加进json配置文件,那里结构如下:

图片 1

我们遵照Json的格式,定义一个收受安插消息的类(结构完全等同json中的定义)

 1 /// <summary>
 2 /// 个人资料
 3 /// </summary>
 4 public class MyProfile
 5 {
 6     public IEnumerable<Project> Projects { set; get; }
 7 }
 8 
 9 /// <summary>
10 /// 项目经历
11 /// </summary>
12 public class Project
13 {
14     /// <summary>
15     /// 持续至日期
16     /// </summary>
17     public string LastToDate { set; get; }
18     /// <summary>
19     /// 项目名称
20     /// </summary>
21     public string Name { set; get; }
22     /// <summary>
23     /// 持续时间
24     /// </summary>
25     public int Lasting { set; get; }
26     /// <summary>
27     /// 所在公司
28     /// </summary>
29     public string Company { set; get; }
30     /// <summary>
31     /// 项目职务
32     /// </summary>
33     public string MyTitle { set; get; }
34     /// <summary>
35     /// 项目职责
36     /// </summary>
37     public string MyDuty { set; get; }
38     /// <summary>
39     /// 项目技术
40     /// </summary>
41     public string Technology { set; get; }
42     /// <summary>
43     /// 项目规格
44     /// </summary>
45     public int NumOfPeople { set; get; }
46     /// <summary>
47     /// 项目描述
48     /// </summary>
49     public IEnumerable<string> ProjectDescs { set; get; }
50     /// <summary>
51     /// 项目图片
52     /// </summary>
53     public IEnumerable<string> ProjectImgs { set; get; }
54 }

那怎么建立json数据和对象之间的炫耀呢,见证奇迹的时候到了,在Startup.cs文件中ConfigureServices方法中,扩展以下代码:

1 var builder = new ConfigurationBuilder()
2                 .SetBasePath(Directory.GetCurrentDirectory())
3                 .AddJsonFile("Datas/Config/MyProfile.json");
4 
5 var config = builder.Build();
6 
7 services.Configure<MyProfile>(config.GetSection("MyProfile"));

在急需采纳安顿新闻地方通过构造器注册,能够看来相关音讯完整的加载到目的中,是否新的布局体系来得特别轻量级,具有更好的扩张性,并且扶助二种化的数据源。

图片 2

个人音讯体现

有了可安顿的个人新闻数据,我们只须要在主页团长之体现出来即可,后台管理–菜单管理,添加贰个主页菜单,排序最前,设置访问路径/Home/Index,图标准样品式,保存后左边导航便冒出新增的主页菜单项。在HomeController控制器的Index方法中,已经读取到个人音信数据,重返前端渲染,效果如下:

 1 <div class="tab-pane active" id="timeline">
 2     <ul class="timeline timeline-inverse">
 3 
 4         @foreach (var project in Model.Projects.Reverse())
 5         {
 6             <li class="time-label">
 7                 @project.LastToDate
 8             </li>
 9             <li>
10                 <i class="fa fa-tags bg-blue"></i>
11                 <div class="timeline-item">
12                     持续时间:@(project.Lasting)个月 <i class="fa fa-clock-o"></i>
13                     <h3 class="timeline-header">
14                         <a>项目名称</a> @project.Name
15                     </h3>
16                     <div class="timeline-body">
17                         <p class="text-muted">所在公司: @project.Company</p>
18                         <p class="text-muted">项目职务: @project.MyTitle</p>
19                         <p class="text-muted">项目职责: @project.MyDuty</p>
20                         <p class="text-muted">项目技术: @project.Technology</p>
21                     </div>
22                     <div class="timeline-footer">
23                         <a class="btn btn-primary btn-xs">更多 >></a>
24                     </div>
25                 </div>
26             </li>
27             <li>
28                 <i class="fa fa-thumb-tack bg-aqua"></i>
29                 <div class="timeline-item">
30                     规模:@(project.NumOfPeople)个人 <i class="fa fa-cube"></i>
31                     <h3 class="timeline-header no-border">
32                         <a>项目描述</a>
33                     </h3>
34                     <div class="timeline-body">
35                         @if (project.ProjectDescs != null)
36                         {
37 
38                             var descIndex = 0;
39 
40                             foreach (var projectDesc in project.ProjectDescs)
41                             {
42                                 <p class="text-muted">@(++descIndex). @projectDesc.</p>
43                             }
44                         }
45                     </div>
46                 </div>
47             </li>
48             if (project.ProjectImgs != null)
49             {
50                 <li>
51                     <i class="fa fa-camera bg-purple"></i>
52                     <div class="timeline-item">
53                         <i class="fa fa-photo"></i>
54                         <h3 class="timeline-header">
55                             <a>效果预览</a>
56                         </h3>
57                         <div class="timeline-body">
58                             <div class="row">
59                                 @foreach (var projectImg in project.ProjectImgs)
60                                 {
61                                     <div class="col-sm-6 col-md-4">
62                                         <img style="cursor: pointer; height: 150px;" src="@projectImg"
63                                              alt="..." class="img-responsive thumbnail center-block img-more">
64                                     </div>
65                                 }
66                             </div>
67                         </div>
68                     </div>
69                 </li>
70             }
71 
72         }
73 
74         <!-- start -->
75         <li class="time-label">
76             2009.02
77         </li>
78         <li>
79             <i class="fa fa-clock-o bg-gray"></i>
80         </li>
81     </ul>
82 </div>

图片 3

当前图片是用压缩后的缩略图显示的(为了网页神速加载),可能用户想要展开看原始图,全体大家那块能够优化一下,点击缩略图,弹出模态框,呈现原始尺寸图片。ok,主页部分大功告成,后台修改json文件配置,我们的主页内容也和方便人民群众的更新了。

 1 <script>
 2     $('.img-more').click(function () {
 3         var file = $(this).attr('src')
 4         var fileNames = file.split('.')
 5         $("#myModal").find("#img_show").html("<image src='" +
 6             fileNames[0] + '-lg.' + fileNames[1] +
 7             "' class='carousel-inner img-responsive img-rounded' />")
 8         $("#myModal").modal();
 9     })
10 </script>

报到验证功用

还记得第③章内容吗,大家早就落到实处了用户的注册和登录,可是近年来从未做连锁的登录验证和权杖管理(权限管理现在等后边完成用户剧中人物单独开一章说,本章首要说一下登录验证)。比如大家撤消用户时,再度通过浏览器链接,输入http://localhost:16546/Configuration/Menu/Index,就可以跳过登录,直接访问菜单界面。这块我们要自己实现的话,不外乎2种方案:

第二种:定义一个公家的控制器,别的具有的控制器继承它,公共的控制器完毕重写如下方法:

 1 public class AuthenticationControllor : Controller
 2 {
 3     protected override void OnActionExecuting(ActionExecutingContext filterContext)
 4     {
 5         if (filterContext.HttpContext.Session["username"] == null)
 6             filterContext.Result = new RedirectToRouteResult("Login", new RouteValueDictionary { { "from", Request.Url.ToString() } });
 7             
 8         base.OnActionExecuting(filterContext);
 9     }
10 }

第二种:定义表明天性,继承ActionFilterAttribute,在急需证实的地方,扩充属性认证:

 1 // 登录认证特性
 2 public class AuthenticationAttribute : ActionFilterAttribute
 3 {
 4     public override void OnActionExecuting(ActionExecutingContext filterContext)
 5     {
 6         if (filterContext.HttpContext.Session["username"] == null)
 7             filterContext.Result = new RedirectToRouteResult("Login", new RouteValueDictionary { { "from", Request.Url.ToString() } });
 8             
 9         base.OnActionExecuting(filterContext);
10     }
11 }

那大家选取哪一类艺术呢?都不用,哈哈,因为Indentity帮大家早就做到了颇具的印证工作,直接在供给证明的控制器或措施上,增添品质过滤器[Authorize]即可。

图片 4

我们再考试下,注销登录后,大家浏览器中输入菜单界面地址链接,网站判断此时没有登录,就会跳转到登录界面。用户输入登录消息科学后,跳转到须要拜访的菜单界面。

 图片 5

加载Loading意义和form表单重复提交防护

 上海体育场合我们得以看来,每一次页面加载的时候页面底部会产出一条进度条和二个筋斗的loading,那样给用户的体会会很好,这是怎么落到实处的啊。其实AdminLTE已经提供了很有益的选用:首先大家在母版页Layout.cshtml引入<script
src=”~/lib/AdminLTE/plugins/pace/pace.js”></script>,然后参预以下脚本,就兑现上述的意义,很简短吗:

1 //ajax请求Pace效果
2 $(document).ajaxStart(function () {
3     Pace.restart()
4 })

前面达成的菜系管理,存在1个小标题,比如用户在保存的时候,网速慢或服务器反应延迟的气象,用户等不急再次点击form表单中的提交按钮,就会促成重复提交的情形,一般会造成至极。就算说在后台增添逻辑判断也得以消除,不过再次提交造成的十分各个种种,要就大增种种注解,寸进尺退。笔者的想法是在前者提交后,服务器未回到结果在此以前,将付诸按钮置为不可用状态,那样用户不能够再度点击,从而防止服务器端极度。然而还有个难点,必须在jquery前端验证之后,才能开端置为不可用,不然前端验证失效。所以我们修改下jquery前端验证的暗中认可的submitHandler。每当用户点击提交按钮时,会率先接触前端验证,验证不通过,直接显示错误提醒;验证通过后,将按钮置不可用,直到服务器再次来到结果。

1 //防止重复提交
2 $.validator.setDefaults({
3     submitHandler: function (form) {
4         $(form).find('[type="submit"]').attr('disabled', true);
5         form.submit();
6     }
7 });

404,500等错误页面提醒

事先大家建了部分菜单项,因为尚未点名访问路径,点击后会有404荒唐;别的,一些服务器极度,网页抛出500谬误。那么些要求捕获一下,并提供本身的页面展现给用户。在Startup.cs文件Configure方法中,配置如下:

 1 if (env.IsDevelopment())
 2 {
 3     app.UseExceptionHandler("/Home/Error/500");
 4     app.UseStatusCodePagesWithReExecute("/Home/Error/{0}");
 5 
 6     app.UseDeveloperExceptionPage();
 7     app.UseBrowserLink();
 8     app.UseDatabaseErrorPage();
 9 }
10 else
11 {
12     app.UseExceptionHandler("/Home/Error/500");
13     app.UseStatusCodePagesWithReExecute("/Home/Error/{0}");
14 }

相应的控制器代码更新如下:

1 [Route("Home/Error/{statusCode}")]
2 public IActionResult Error(int statusCode)
3 {
4     return View(new ErrorViewModel
5     {
6         StatusCode = statusCode,
7         RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier
8     });
9 }

对应视图代码也急需创新一下:

 1 @model MyWebSite.ViewModels.ErrorViewModel
 2 @{
 3     ViewData["Title"] = "错误";
 4 }
 5 <div class="error-page" style="margin-top: 100px;">
 6     @if (Model.StatusCode == 500)
 7     {
 8         <!-- 500类型错误 -->
 9         <h2 class="headline text-red"> @Model.StatusCode</h2>
10 
11         <div class="error-content">
12             <h3>
13                 <i class="fa fa-warning text-red"></i> Oops! Something went wrong.
14             </h3>
15             <div>
16                 StatusCode:<code>@Model.StatusCode</code>
17             </div>
18             <div>
19                 Request ID: <code>@Model.RequestId</code>
20             </div>
21             <p>
22                 We will work on fixing that right away.
23                 Meanwhile, you may <a asp-area="" asp-controller="Home" asp-action="Index">return to index</a> or try using the search form.
24             </p>
25             <form class="search-form">
26                 <div class="input-group">
27                     <input type="text" name="search" class="form-control" placeholder="Search">
28                     <div class="input-group-btn">
29                         <button type="submit" name="submit" class="btn btn-danger btn-flat">
30                             <i class="fa fa-search"></i>
31                         </button>
32                     </div>
33                 </div>
34             </form>
35         </div>
36     }
37     else
38     {
39         <!-- 其他类型错误 -->
40         <h2 class="headline text-yellow"> @Model.StatusCode</h2>
41 
42         <div class="error-content">
43             <h3>
44                 <i class="fa fa-warning text-yellow"></i> Oops! Page not found.
45             </h3>
46             <div>
47                 StatusCode:<code>@Model.StatusCode</code>
48             </div>
49             <div>
50                 Request ID: <code>@Model.RequestId</code>
51             </div>
52             <p>
53                 We could not find the page you were looking for.
54                 Meanwhile, you may <a asp-area="" asp-controller="Home" asp-action="Index">return to index</a> or try using the search form.
55             </p>
56             <form class="search-form">
57                 <div class="input-group">
58                     <input type="text" name="search" class="form-control" placeholder="Search">
59                     <div class="input-group-btn">
60                         <button type="submit" name="submit" class="btn btn-warning btn-flat">
61                             <i class="fa fa-search"></i>
62                         </button>
63                     </div>
64                 </div>
65             </form>
66         </div>
67     }
68 </div>

小结

 
以上,那期关于网站的调动已介绍达成,最终,后台管理–菜单管理,添加对应博客链接的菜单项,为了便利用户通过链接待上访问作者的博客,看下演示效果啊:

 图片 6

相关文章

网站地图xml地图