.net mvc

这里写自定义目录标题

  • 欢迎使用Markdown编辑器
    • 新的改变
    • 功能快捷键
    • 合理的创建标题,有助于目录的生成
    • 如何改变文本的样式
    • 插入链接与图片
    • 如何插入一段漂亮的代码片
    • 生成一个适合你的列表
    • 创建一个表格
      • 设定内容居中、居左、居右
      • SmartyPants
    • 创建一个自定义列表
    • 如何创建一个注脚
    • 注释也是必不可少的
    • KaTeX数学公式
    • 新的甘特图功能,丰富你的文章
    • UML 图表
    • FLowchart流程图
    • 导出与导入
      • 导出1
      • 导入

欢迎使用Markdown编辑器

你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

新的改变

我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:

  1. 全新的界面设计 ,将会带来全新的写作体验;
  2. 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
  3. 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
  4. 全新的 KaTeX数学公式 语法;
  5. 增加了支持甘特图的mermaid语法1 功能;
  6. 增加了 多屏幕编辑 Markdown文章功能;
  7. 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
  8. 增加了 检查列表 功能。

功能快捷键

撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G

合理的创建标题,有助于目录的生成

直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC语法后生成一个完美的目录。

如何改变文本的样式

强调文本 强调文本

加粗文本 加粗文本

标记文本

删除文本

引用文本

H2O is是液体。

210 运算结果是 1024.

插入链接与图片

链接: link.

图片: Alt

带尺寸的图片: Alt

居中的图片: Alt

居中并且带尺寸的图片: Alt

当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。

如何插入一段漂亮的代码片

去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片.

// An highlighted block
var foo = 'bar';

生成一个适合你的列表

  • 项目
    • 项目
      • 项目
  1. 项目1
  2. 项目2
  3. 项目3
  • 计划任务
  • 完成任务

创建一个表格

一个简单的表格是这么创建的:

项目 Value
电脑 $1600
手机 $12
导管 $1

设定内容居中、居左、居右

使用:---------:居中
使用:----------居左
使用----------:居右

第一列 第二列 第三列
第一列文本居中 第二列文本居右 第三列文本居左

SmartyPants

SmartyPants将ASCII标点字符转换为“智能”印刷标点HTML实体。例如:

TYPE ASCII HTML
Single backticks 'Isn't this fun?' ‘Isn’t this fun?’
Quotes "Isn't this fun?" “Isn’t this fun?”
Dashes -- is en-dash, --- is em-dash – is en-dash, — is em-dash

创建一个自定义列表

Markdown
Text-to- HTML conversion tool
Authors
John
Luke

如何创建一个注脚

一个具有注脚的文本。2

注释也是必不可少的

Markdown将文本转换为 HTML

KaTeX数学公式

您可以使用渲染LaTeX数学表达式 KaTeX:

Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n1)!nN 是通过欧拉积分

Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=0tz1etdt.

你可以找到更多关于的信息 LaTeX 数学表达式here.

新的甘特图功能,丰富你的文章

Mon 06 Mon 13 Mon 20 已完成 进行中 计划一 计划二 现有任务 Adding GANTT diagram functionality to mermaid
  • 关于 甘特图 语法,参考 这儿,

UML 图表

可以使用UML图表进行渲染。 Mermaid. 例如下面产生的一个序列图:

张三 李四 王五 你好!李四, 最近怎么样? 你最近怎么样,王五? 我很好,谢谢! 我很好,谢谢! 李四想了很长时间, 文字太长了 不适合放在一行. 打量着王五... 很好... 王五, 你怎么样? 张三 李四 王五

这将产生一个流程图。:

链接
长方形
圆角长方形
菱形
  • 关于 Mermaid 语法,参考 这儿,

FLowchart流程图

我们依旧会支持flowchart的流程图:

Created with Raphaël 2.2.0 开始 我的操作 确认? 结束 yes no
  • 关于 Flowchart流程图 语法,参考 这儿.

导出与导入

导出1

如果你想尝试使用此编辑器, 你可以在此篇文章任意编辑。当你完成了一篇文章的写作, 在上方工具栏找到 文章导出 ,生成一个.md文件或者.html文件进行本地保存。

导入

如果你想加载一篇你写过的.md文件,在上方工具栏可以选择导入功能进行对应扩展名的文件导入,
继续你的创作。

本文主要是作者回顾MVC基础的文章,整合个人认为基础且重点的信息,通过简单实践进行复习。

相关代码地址:https://github.com/OtherRuan/Review-Serials

WebForm
开始说MVC的时候不得不提下WebForm,熟悉两者的区别和优劣,能够更好的理解MVC。早些时候,开始做asp.net开发的时候离不开webform的控件拖拽的方式开发,只需要拖拽系统的控件就能完成web页面,效率之快毋庸置疑。但是随之而来的是臃肿的应用程序,耦合度极高的前后端,ViewState大量占用带宽等问题,在当今越来越追求性能的背景下。WebForm也面临退伍的命运,就像Asp.Net5已经完全摒弃了WebForm的开发方式。

性能问题是WebForm最主要的问题,通过MVC与WebForm两者性能的对比,可以明显的看出WebForm性能上存在的问题。

  1. 响应时间

(图片来源自:http://www.codeproject.com/Articles/866143/Learn-MVC-step-by-step-in-days-Day)

可以看出响应时间上WebForm是MVC的两倍,因为WebForm需要将控件进一步转换成html文本响应。如下流程

用户请求–>服务器控件–>转换成Html–>返回响应

  1. 带宽消耗

由于服务器控件的状态变换控制是通过事件回发来完成的,而回发状态信息则保存在ViewState中,以达到减少开发时间。但是ViewState却大幅增加了页面的大小,从上图可以看到WebForm的页面大小比MVC要大2倍上下。

其他问题,如重写问题、单元测试问题等等

MVC
解决WebForm性能问题,从几个问题来看。首先,由于WebForm是由aspx和aspx.cs两者通过CodeBehind高度耦合,导致无法单元测试, 因此我们将二者独立开,即Controller。其次ViewState导致页面大,服务器控件多的情况下,加之难以重写的问题,因此前端采用纯Html方式,也就是View。以下是MVC的流程图

简要介绍几个内容:

  1. Controller:也就是后端逻辑处理

  2. View

MVC通过创建ViewResult对象渲染View到响应包中。过程如下:

a. ViewResult内部创新ViewPageActivator对象

b. ViewResult选择正确的ViewEngine,将ViewPageActivator作为ViewEngine构造函数的参数

c. ViewEngine创建View 对象

d. ViewResult 触发 View对象的方法RenderView

ViewResult和ActionResult的关系

ActionResult是抽象类,ViewResult–>ViewResultBase–>ActionResult。 -->为继承关系

ViewResult描述了完整的HTML响应,而ContentResult响应文本请求。

  1. 数据对象Model在Controller与View之间的传递

a. ViewState的使用

ViewState是一个dictionary,Controller将数据Model对象添加到这个Dictionary中,View从中读取数据。

ex. ViewState[“Employee”] = new Employee();

b. ViewBag的使用

ViewBag.Employee = new Employee();

c. ViewState和ViewBag的问题

1) 性能问题

ViewData的数据是Object,我们需要强制转换它。

2) Type安全问题与Runtime编译时错误问题

当发生强转出错时,我们会获取运行时错误信息。但是好的程序,应该要获取编译时错误

3) 数据发送端与接收端没有必要联系

由于controller和view是相互解耦的,这时如果view和controller是两个不同的程序员时,使用viewState就容易造成运行时错误,强转错误

  1. 理解强类型视图

针对3.c指出的类型问题,我们可以采用强类型视图,预先定义好model对象的类型,避免发生转换错误。

@model MVCReview.Models.Employee

@if(Model.Salary>15000)
{
>
Employee Salary: @Model.Salary.ToString(“C”)

}
else
{
>

    Employee Salary: @Model.Salary.ToString("C")
}

@model MVCReview.Models.Employee 指定了类型

  1. 理解ViewModel

ViewModel作为Model和View之前的交互的数据容器。Model一般为具体业务数据,是基于业务和数据库结构创建的。而ViewModel是具体的View数据,基于View页面对象

之前提到,当我们用model作为view的对象时,如果我们想新增其他信息时,这就违背了SRP和SOLID原则。

Controller集合多个Model,合并成一个view的viewmodel

  1. ViewModel的实例

using MVCReview.Models;
using MVCReview.ViewModels;
public class EmployeeViewModel
{
public string EmployeeName { get; set; }
public string Salary { get; set; }
public string SalaryColor { get; set; }
public string UserName { get; set; }
}

其中EmployeeViewModel中含有两个对象的集合,Employee对象的数据和User的数据UserName。

DAL层
什么是EF
    ORM: 与数据库通信,mapping数据库的表对象

2. 什么是Code First

EF有三种创建模式

a) Database First Approach:先创建数据库表,然后EF生成关联的Model类和DAL代码

b) Model First Approach: Model类以及Model之间的关系,使用Model designer先定义好,EF会生成DAL代码和在数据库中生成表

c) Code First Approach: 手动创建POCO类。表间的关系通过POCO定义。当程序第一次运行时会生成DAL代码和数据库表

Authentication权限
ASP.NET Form Authentication所做的工作:

用户请求Form权限允许访问程序
浏览器把相关的Cookies保存到请求中
请求到达服务端后,服务器检查请求的cookie信息:Authentication Cookie
解析Cookie信息得到用户信息,如果没有cookie则认定用户为匿名用户anoymous
FormsAuthentication.SetAuthCookie(account.Name, false);

ModelState.AddModelError(“AddError”, “Invalid Username or password!”);

@Html.ValidationMessage(“AddError”, new {style=“color:red;” })

Global添加权限属性过滤—共用权限验证

如何添加页眉页脚
ViewModel添加FootViewModel
@{Html.RenderPartial(“Footer”,Model.FootData)}
Html.RenderPartial与html.partial区别:

renderPartial直接将View转成Http响应stream,而partial则返回结果MvcHtmlString对象。MvcHtmlString代表html编码后的字符串,razor会对string一直编码,但MvcHtmlString例外。使用场景:当我们不需要使用razor进行编码的时候。partial之所以返回MvcHtmlString而非String,原因就是Partial 的使用通常是作为HTML文本而非string. Html.renderPartial比partial快,所以推荐。

实现角色安全
创建用户角色枚举
服务调用,记录到Session中
创建PartialView权限范围内的功能,如添加新用户
添加Action,render这个PartialView
Html.RenderAction
这样还不够,因为登录的用户可以通过输入url地址,来使用添加用户的功能。使用MVC ActionFilter来执行Action处理前和处理后的逻辑

MVC filter有四种,Action、Authorization、Result、Exception

使用ActionFilter过滤结果对象
ActionExcutedContext

ActionDescriptor包含Action、Controller等等的描述,如name、Type等
Canceled:返回当前Action是否取消执行的状态
Exception:执行Action中的Exception对象
ExceptionHandled:返回执行Action时Exception对象是否被处理。
Result:ActionResult对象,即Action返回的结果对象。可以操作结果视图对象里的Model和View。
完善项目
创建ViewModel基类ReactViewModel,包含基础信息,如Footer、Username
创建layout view. ReactView.cshtml
强类型视图,引用ReactViewModel对象
定义@RenderSection(“ContentBody”)
Index页面引用layout
Index 页面实例section,@section ContentBody{ //html元素 }
@html.RenderBody()做了什么?

Razor允许我们利用RenderBody来定义section外的content内容。非包含在section内的内容将自动包含在renderBody中。

MVC响应请求的过程
MVC是如何响应你发送的请求?

当一个请求发生时,就会创建一个线程来执行相应的程序。Web服务器上的Asp.net中,.net framework维护线程池。每一次请求发送到web服务器,线程池就分配一个线程(工作线程)响应这个请求。工作线程将会锁定单独处理这个请求,因此很有可能一个应用程序接受N多个线程且长期占用资源的情况。当线程池请求占满,没有可用的线程响应请求,这叫线程饥饿。

解决方案:

异步请求

线程池为异步请求分配工作线程
工作线程初始化异步操作的信息后就返回线程池,异步操作将继续在CLR线程中执行。
当CLR线程执行完后将通知ASP.NET
Web服务器将获取工作线程处理剩余的请求并发送响应
Request–>work thread–>CLR thread–>work thread–>response

解决线程饥饿的问题
请求发送到web服务器
Web服务器从线程池中分配工作线程响应请求
工作线程触发Action方法执行
Action通过Task.Factory.StartNew方法开始异步处理
Async关键字确保工作线程在异步处理开始后的释放。逻辑处理将在单独的CLR线程后台执行
Await关键,确保下一行的执行等待异步操作完成后
异步操作完成后,则需要分配新的工作线程处理剩余的请求和发送响应
错误处理-显示自定义错误页面
Exception Filter

使用步骤:

开启ExceptionFilter

2. 添加属性到Action、Controller、Global级别

Action方法发生错误时,Exception Filter获取Control的错误,并处理filter的内容。当Action发生错误时,filter会从/Views/[Controller]或者/Views/Shared文件夹中找以Error为命名的文件,创建ViewResult响应结果

错误处理-日志错误
ExceptionFilter:HandleErrorAttribute

Override OnException method

改变原有的Exception Filter

//filters.Add(new HandleErrorAttribute());//ExceptionFilter
filters.Add(new EmployeeExceptionFilter());
base.OnException(filterContext);
错误处理后,OnException将返回ViewResult也就是Error View。 重定义filterContext的Result就可以重定义ViewResult

路由
理解RouteTable
包含所有应用程序的所有URL路由的定义,静态属性RouteCollection

RouteConfig.RegisterRoutes(RouteTable.Routes);
RouteConfig.cs里RegisterRoutes将会在Asp.Net MVC请求环中决定Url路由对应的Controller和Action

MVC请求周期:

1. UrlRoutingModule

终端用户第一次请求经过UrlRoutingModule对象,UrlRoutingModule是HttpModule

2. Routing路由

UrlRoutingModule从RouteTable里的RouteCollection中,获取匹配的Route对象。该匹配过程就是对比RouteConfig里定义的Url的路由模式

3. 创建MVC Route Handler

匹配对应的Route对象后,UrlRoutingModule会从Route对象中获取MvcRouteHandler对象

4. 创建RouteData和RequestContext

UrlRoutingModule对象会通过Route对象创建RouteData(包含Routes的相关信息,如action、controller、parameters信息),继而通过RouteData创建RequsetContext对象。

5. 创建MVCHandler

MvcRouteHandler创建MVCHandler实例传递RequestContexst对象。

6. 创建Controller实例

MVCHandler借助ControllerFactory,创建Controller实例。

7. 执行方法

MVCHandler会触发Controller的执行。执行方法定义在Controller的基类中。

8. 触发Action方法

所有Controller关联一个ControllerActionInvoker对象。内置的执行方法利用ControllerActionInvoker触发action方法的执行

9. 执行结果

返回ViewResult结果

Request–>UrlRoutingModule (RouteTable) -->Route -->MVCRouteHandler、RouteData–>RequestContext

MvcRouteHandler–>MvcHandler (ControllerFactory)–>Controller (ControllerActionInvoker)–>ActionàViewResult

如何实现友好的URL
配置RouteConfig里的RegisterRoute

或者在Controller上添加Route()属性

参考文献
Learn MVC Project in 7 days


  1. mermaid语法说明 ↩︎

  2. 注脚的解释 ↩︎

你可能感兴趣的:(c#,asp.net)