深入理解Asp.net MVC路由

深入理解Asp.net MVC路由

吴剑 2012-10-22

原创文章,转载必需注明出处:http://www.cnblogs.com/wu-jian/

 

前言

从.Net Framework 1.0时代开始写WebForm,直到最近断断续续看到Razor的语法风格,然后搜了Asp.net MVC的一些介绍,于是想把自己的一个项目从WebForm转换成MVC。边摸索边Coding,花了两周时间,差不多大功告成。项目中有用到多级域名,代码写到这部分突然就被卡住了,一直没深入了解Asp.net Routing,被卡住理所当然,感觉关于Asp.net MVC底层知识的文章很少,大多是一些应用层面,或底层原理的部分片段,不能帮助我系统的理解。代码是最好的学习和交流方式,于是结合自己的项目实例,反编译了部分微软的类库来参考,将过程整理和表述,如能给人予帮助,不甚荣幸,同时个人能力有限,不足之处还请及时指正。

 

“静态路由表”

在Asp.net中,需要将请求的URL根据我们设置的匹配规则交给相应的处理程序去处理,从Url到处理程序的过程,称之为路由,如下图所示:

<图1>

在Asp.net中,命名空间 System.Web.Routing 包含了路由的所有功能,从命名上可以看出它与 System.Web.Mvc 是平级的。没错,Asp.net Routing是一个独立组件,你可以用它来路由MVC,路由Web Form,甚至路由自己的Web框架。

在深入Routing之前,我们暂且按最简单的方式来想像路由:在内存中有一张表,这张表记录了Url的匹配规则和处理程序,当一个Url请求到达时,遍历这张表,如发现Url与规则匹配,交由到对应的处理程序。

OK,按这个简单逻辑我们首先需要找到这张表。它位于 System.Web.Routing.RouteTable.Routes 静态属性中,类型为 RouteCollection, RouteCollection为 Route 的集合,当我们要添加一条路由信息时,即向这个集合中添加一个Route对象。为方便描述,本文中姑且我们把这个存放Route集合的静态属性称之为“静态路由表”吧。

public class RouteTable
{public RouteTable();//静态属性获取所有路由的对象public static RouteCollection Routes { get; }
}

 

向“静态路由表”中添加记录

如何向“静态路由表”中添加记录?有如下两种方式:

一、直接调用System.Web.Routing.RouteCollection.Add()方法

public void Add(string name, RouteBase item)
{//...
}

 

二、调用System.Web.Mvc.RouteCollectionExtensions.MapRoute()扩展方法

扩展方法是C#3.0的新特性,比如假设微软的团队A开发了System.Web.Routing,团队B开发了System.Web.Mvc。团队B需要使用团队A开发的RouteCollection.Add(),同时还需要再对它进行一些扩展,此时团队B使用了扩展方法而无需关心团队A的代码: 

反编译 System.Web.Mvc.RouteCollectionExtensions.MapRoute 方法

public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)
{if (routes == null){throw new ArgumentNullException("routes");}if (url == null){throw new ArgumentNullException("url");}Route item = new Route(url, new MvcRouteHandler()) {Defaults = new RouteValueDictionary(defaults),Constraints = new RouteValueDictionary(constraints),DataTokens = new RouteValueDictionary()};if ((namespaces != null) && (namespaces.Length > 0)){item.DataTokens["Namespaces"] = namespaces;}routes.Add(name, item);return item;
}

对扩展方法总结:

1、扩展方法与方法所在的类都必须为静态的。

2、第1个参数为待扩展的类型,并且前面添加this关键字。

 

“静态路由表”的数据结构

System.Web.Routing.Route 类

public class Route : RouteBase
{/// <summary>/// 使用指定的 URL 模式和处理程序类初始化 System.Web.Routing.Route 类的新实例/// </summary>/// <param name="url">路由的 URL 模式</param>/// <param name="routeHandler">处理路由请求的对象</param>public Route(string url, IRouteHandler routeHandler);/// <summary>/// 使用指定的 URL 模式、默认参数值和处理程序类初始化 System.Web.Routing.Route 类的新实例/// </summary>/// <param name="url">路由的 URL 模式</param>/// <param name="defaults">用于 URL 中缺失的任何参数的值</param>/// <param name="routeHandler">处理路由请求的对象</param>public Route(string url, RouteValueDictionary defaults, IRouteHandler routeHandler);/// <summary>/// 使用指定的 URL 模式、默认参数值、约束和处理程序类初始化 System.Web.Routing.Route 类的新实例/// </summary>/// <param name="url">路由的 URL 模式</param>/// <param name="defaults">要在 URL 不包含所有参数时使用的值</param>/// <param name="constraints">一个用于指定 URL 参数的有效值的正则表达式</param>/// <param name="routeHandler">处理路由请求的对象</param>public Route(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler);/// <summary>/// 使用指定的 URL 模式、默认参数值、约束、自定义值和处理程序类初始化 System.Web.Routing.Route 类的新实例/// </summary>/// <param name="url">路由的 URL 模式</param>/// <param name="defaults">要在 URL 不包含所有参数时使用的值</param>/// <param name="constraints">一个用于指定 URL 参数的有效值的正则表达式</param>/// <param name="dataTokens">传递到路由处理程序但未用于确定该路由是否匹配特定 URL 模式的自定义值。 这些值会传递到路由处理程序,以便用于处理请求</param>/// <param name="routeHandler">处理路由请求的对象</param>public Route(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler);/// <summary>/// 获取或设置为 URL 参数指定有效值的表达式的词典/// 返回一个包含参数名称和表达式的对象/// </summary>public RouteValueDictionary Constraints { get; set; }/// <summary>/// 获取或设置传递到路由处理程序但未用于确定该路由是否匹配 URL 模式的自定义值/// 返回一个包含自定义值的对象/// </summary>public RouteValueDictionary DataTokens { get; set; }/// <summary>/// 获取或设置要在 URL 不包含所有参数时使用的值/// 返回一个包含参数名称和默认值的对象/// </summary>public RouteValueDictionary Defaults { get; set; }/// <summary>/// 获取或设置处理路由请求的对象/// 返回处理请求的对象/// </summary>public IRouteHandler RouteHandler { get; set; }/// <summary>/// 获取或设置路由的 URL 模式/// 返回用于匹配路由和 URL 的模式/// </summary>public string Url { get; set; }/// <summary>/// 返回有关所请求路由的信息/// </summary>/// <param name="httpContext">一个对象,封装有关 HTTP 请求的信息</param>/// <returns>返回一个对象,其中包含路由定义中的值</returns>public override RouteData GetRouteData(HttpContextBase httpContext);/// <summary>/// 返回与路由关联的 URL 的相关信息/// </summary>/// <param name="requestContext">一个对象,封装有关所请求的路由的信息</param>/// <param name="values">一个包含路由参数的对象</param>/// <returns>返回一个包含与路由关联的 URL 的相关信息的对象</returns>public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);/// <summary>/// 确定参数值是否与该参数的约束匹配/// </summary>/// <param name="httpContext">一个对象,封装有关 HTTP 请求的信息</param>/// <param name="constraint">用于测试 parameterName 的正则表达式或对象</param>/// <param name="parameterName">要测试的参数的名称</param>/// <param name="values">要测试的值</param>/// <param name="routeDirection">一个指定 URL 路由是否处理传入请求或构造 URL 的值</param>/// <returns>如果参数值与约束匹配,则为 true;否则为 false。</returns>protected virtual bool ProcessConstraint(HttpContextBase httpContext, object constraint, string parameterName, RouteValueDictionary values, RouteDirection routeDirection);
}

静态路由表的数据结构即为Route类的结构,它遵循一定规则存放数据,如上代码所示,将设置的Url规则存放于Url属性中,将处理程序存放于RouteHandler属性中。

将用户设置的其它数据存放于字典(RouteValueDictionary)中,并将字典分为3个类别:

Defaults:描述Url规则的默认值

Constraints:描述Url规则的约束

DataTokens:其它自定义数据(如处理程序的命名空间)

 

为结合项目应用更直观的演示静态路由表的数据结构,我编写了一个简单的DEMO

向“静态路由表”中添加数据:

public class RouteConfig
{public static void RegisterRoutes(RouteCollection routes){routes.IgnoreRoute("{resource}.axd/{*pathInfo}");routes.MapRoute(name: "Default",url: "{controller}/{action}/{id}",defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },constraints: new { controller = "[a-zA-Z]+" },namespaces: new string[] { "WebRoutingDemo.Controllers.HomeController" }                );}
}

打印“静态路由表”中所有数据:

protected void Page_Load(object sender, EventArgs e)
{//静态路由表System.Web.Routing.RouteCollection routeItems = System.Web.Routing.RouteTable.Routes;//遍历静态路由表foreach (System.Web.Routing.Route routeItem in routeItems){//UrlResponse.Write("<strong>Url:</strong><br />");Response.Write(string.Format("&nbsp;&nbsp;&nbsp;&nbsp;{0}<br />", routeItem.Url));//DefaultsResponse.Write("<strong>Defaults:</strong><br />");if (routeItem.Defaults != null){foreach (KeyValuePair<string, object> defaultItem in routeItem.Defaults){Response.Write(string.Format("&nbsp;&nbsp;&nbsp;&nbsp;{0}:{1}<br />", defaultItem.Key, defaultItem.Value));}}//ConstraintsResponse.Write("<strong>Constraints:</strong><br />");if (routeItem.Constraints != null){foreach (KeyValuePair<string, object> constraintsItem in routeItem.Constraints){Response.Write(string.Format("&nbsp;&nbsp;&nbsp;&nbsp;{0}:{1}<br />", constraintsItem.Key, constraintsItem.Value));}}//DataTokens Response.Write("<strong>DataTokens:</strong><br />");if (routeItem.DataTokens != null){foreach (KeyValuePair<string, object> dataTokensItem in routeItem.DataTokens){Response.Write(string.Format("&nbsp;&nbsp;&nbsp;&nbsp;{0}:{1}<br />", dataTokensItem.Key, dataTokensItem.Value));}}Response.Write("=============================<br />");}
}

打印结果:

Url:
    api/{controller}/{id}
Defaults:
    id:
Constraints:
DataTokens:
=============================
Url:
    {resource}.axd/{*pathInfo}
Defaults:
Constraints:
DataTokens:
=============================
Url:
    {controller}/{action}/{id}
Defaults:
    controller:Home
    action:Index
    id:
Constraints:
    controller:[a-zA-Z]+
DataTokens:
    Namespaces:System.String[]
=============================
 

 

路由的核心逻辑

路由的核心逻辑是将请求的URL与“静态路由表”中配置的URL规则进行比较,找到第一条匹配的记录,并将请求交由其处理程序(RouteHandler)进行后续处理。

请求的URL如何与“静态路由表”进行匹配?我猜想过程应该是这样:首先一个URL请求到达,然后遍历“静态路由表”,将表中的URL表达式与请求的URL进行比较,如请求URL符合该表达式,获取RouteHandler并中止遍历。当然这只是我的猜想,实际微软把这个过程封装在了System.Web.Routing.ParsedRoute类中,感兴趣的朋友可通过反编译查看详细过程。

在应用层面,微软为开发者提供了一个扩展点以实现对路由的自定义处理:System.Web.Routing.RouteBase.GetRouteData()方法。这是一个抽象方法,也就是说只要是“静态路由表”中的记录,都必须实现这个方法。如下代码:

System.Web.Routing.RouteBase 类

public abstract class RouteBase
{protected RouteBase();/// <summary>/// 当在派生类中重写时,会返回有关请求的路由信息/// </summary>/// <param name="httpContext">一个对象,封装有关 HTTP 请求的信息</param>/// <returns>一个对象,包含路由定义的值(如果该路由与当前请求匹配)或 null(如果该路由与请求不匹配)</returns>public abstract RouteData GetRouteData(HttpContextBase httpContext);/// <summary>/// 当在派生类中重写时,会检查路由是否与指定值匹配,如果匹配,则生成一个 URL,然后检索有关该路由的信息/// </summary>/// <param name="requestContext">一个对象,封装有关所请求的路由的信息</param>/// <param name="values">一个包含路由参数的对象</param>/// <returns>一个对象(包含生成的 URL 和有关路由的信息)或 null(如果路由与 values 不匹配)</returns>public abstract VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values);
}

 

通过GetRouteData()方法判断请求的URL是否与“静态路由表”中的记录匹配,如返回一个RouteData对象,表示匹配成功,循环中止;如返回null,表示匹配失败,循环继续,直到遍历完整个“静态路由表”。大致逻辑如下图所示:

<图2>

System.Web.Routing.RouteData类

public class RouteData
{public RouteData();public RouteData(RouteBase route, IRouteHandler routeHandler);/// <summary>/// 获取在 ASP.NET 路由确定路由是否匹配请求时,传递到路由处理程序但未使用的自定义值的集合。/// 属性Namespaces表示辅助Controller类型的解析而设置的命名空间列表,该属性值从DataTokens字典中提取,对应的Key为namespaces/// 返回一个包含自定义值的对象。/// </summary>public RouteValueDictionary DataTokens { get; }/// <summary>/// 获取或设置表示路由的对象。/// 返回一个表示路由定义的对象。/// </summary>public RouteBase Route { get; set; }/// <summary>/// 获取或设置处理所请求路由的对象。/// 返回一个处理路由请求的对象。/// </summary>public IRouteHandler RouteHandler { get; set; }/// <summary>/// 获取路由的 URL 参数值和默认值的集合。/// 直接从请求地址解析出来的变量/// Controller和Action名称的同名属性直接从Values字典中提取,对应的Key分别为controller和action/// 返回一个对象,其中包含根据 URL 和默认值分析得出的值。/// </summary>public RouteValueDictionary Values { get; }/// <summary>/// 使用指定标识符检索值。/// </summary>/// <param name="valueName">要检索的值的键。</param>/// <returns>其键与 valueName 匹配的 System.Web.Routing.RouteData.Values 属性中的元素。</returns>public string GetRequiredString(string valueName);
}

 

总结

我们设置的URL规则通过System.Web.Routing.RouteCollection.Add()方法添加进“静态路由表”,每条规则以一个Route对象存放,对象的Defaults属性存放了我们设置的URL默认值,Constraints属性存放了对URL的一些约束,DataTokens属性存放其它数据。

当用户浏览网页时,请求的URL与静态路由表的记录进行匹配,匹配逻辑和过程包括在实现了RouteBase.GetRouteData的一个方法中,微软的Route.GetRouteData为我们提供了一个默认实现,当然我们也可以在自定义的方法中实现,如DEMO代码所示。

URL与“静态路由表”是否匹配取决于GetRouteData方法是否返回RouteData对象,如果RouteData为null表示未匹配。如果RouteData不为null,则表示URL与“静态路由表”相匹配,并将RouteHandler的值传递到RouteData中,供后续逻辑使用。

 

DEMO

DEMO参考了DomainRoute的源代码,示例了一个自定义的路由处理过程,它实现了GetRouteData方法,演示了路由处理的一些细节,包括URL规则与请求URL的匹配过程、将URL中的名称参数、Defaults、DataTokens还原为RouteData对象。

开发环境:.Net Framework 4.0;Visual Studio 2012

下载地址:http://files.cnblogs.com/wu-jian/WebRoutingDemo.rar 

 

<全文完>

 

微信打赏 如果您觉得本文对您有所帮助,可扫描两侧的二维码向作者打赏。您的支持是原创的源动力!
作者:吴剑
出处:http://www.cnblogs.com/wu-jian/
本文版权归作者所有,欢迎转载,但必需注明出处,并且在转载页面明显位置给出原文连接,否则保留追究法律责任的权利。
支付宝打赏

转载于:https://www.cnblogs.com/wu-jian/archive/2012/10/22/2579668.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/550219.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高中计算机学业水平测试知识点总结,高中化学学业水平测试知识点总结

高中化学学业水平测试知识点总结大家有总结吗&#xff1f;下面小编整理了高中化学学业水平测试知识点总结&#xff0c;欢迎大家参考借鉴&#xff01;高中化学学业水平测试知识点总结第一章从实验学化学 第一节化学实验基本方法一.化学实验安全1. 遵守实验室规则。2. 了解安全措…

chrome html 读写文件路径,Chrome浏览器支持直接读写本地文件了

本文首发于公众号&#xff1a;符合预期的CoyPan写在前面最新版的Chrome(Chrome 83, 须要开启权限)支持直接读写本地文件了。javascript开启方法&#xff1a;Chrome浏览器升级到83版本以上&#xff1b;访问chrome://flags/&#xff0c;开启 Native File System API 选项当前如何…

最长单调递增子序列_最长递增子序列(动态规划 + 二分搜索)

题目给定数组arr&#xff0c;返回arr的最长递增子序列举例&#xff1a;arr [2,1,5,3,6,4,8,9,7]&#xff0c;返回的最长递增子序列为[1,3,4,8,9]要求&#xff1a;如果arr的长度为N&#xff0c;请实现时间复杂度为O(nlogn)的方法。分析这一题也是经典的动态规划&#xff0c;那么…

二叉排序树(BinarySortTree)

相关知识&#xff1a; 二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”&#xff08;left subtree&#xff09;和“右子树”&#xff08;right subtree&#xff09;。 二叉树中的左右子树不可随意交换。 根节点&#xff1a;一棵树最上面的节点称为根节点。 父…

惠普台式计算机系列,惠普发布设计笔记本、设计台式电脑等Z系列产品

惠普发布新一代惠普Z系列产品&#xff0c;包含设计笔记本、设计台式电脑、显示器和VR等产品。惠普Z系列设计笔记本HP ZBook 14u G6配有4K显示屏&#xff0c;支持100% Adobe RGB色域显示&#xff0c;拥有600尼特亮度&#xff0c;满足创意族群对色彩的精确要求。HP ZBook 15u G6图…

ORM多表操作之多对多查询

创建多对多的关系 authormodels.ManyToManyFleld(" ")  (推荐) 书籍对象它的所有关联作者 book_obj.authors.all() 掌握&#xff1a;通过filter values(双下划线)进行多对多的关联查询&#xff08;形式一对多&#xff09; django是将python语句翻译成sql语句执行 聚…

计算机的iscsi配置,我们将了解如何设置自己的支持iscsi配置的存储节点

iSCSI代表Internet小型计算机系统接口。它用于使用块级数据传输通过TCP / IP访问网络上的存储。NFS与iSCSI之间通常存在比较。关键区别在于NFS是文件级实现&#xff0c;而iSCSI是块级实现。这适用于TCP / IP层&#xff0c;并允许通过局域网(LAN)发送SCSI命令。在诸如iSCSI和光纤…

计算机基础知识复习资料,计算机基础知识复习资料

.Word 资料Ch1 计算机基础知识1.1 现代信息技术1.1.1、特征&#xff1a;●以数字技术和电子技术为基础&#xff1b;●以计算机及其软件为核心&#xff1b;●采用电子技术(包括激光技术)进行信息的收集、传递、加工、存储、显示与控制。1.1.2、数字技术一、二进位数字——比特(b…

linux上安装Docker

Docker的三大核心概念&#xff1a;镜像、容器、仓库 镜像&#xff1a;类似虚拟机的镜像、用俗话说就是安装文件 容器&#xff1a;类似一个轻量级的沙箱&#xff0c;容器是从镜像创建应用运行实例&#xff0c;可以将其启动、开始、停止、删除、而这些容器都是相互隔离、互不可见…

幼儿园计算机教师论文,幼儿园中班教师论文

幼儿园中班教师论文导语&#xff1a;幼儿教育是什么&#xff1f;幼儿应如何正确接受教育&#xff1f;幼儿接受与不接受教育区别又如 何&#xff1f;这些看似简单的问题&#xff0c;其实不然。在当今科技发达的今天&#xff0c;幼儿的教育起着承前启后的重要阶段&#xff0c;不仅…

ASP.NET 5 入门 (2) – 自定义配置

原文:ASP.NET 5 入门 (2) – 自定义配置ASP.NET 5 入门 (2) – 自定义配置 ASP.NET 5 理解和入门 建立和开发ASP.NET 5 项目 初步理解ASP.NET5的配置 正如我的第一篇文章ASP.NET 5 (vNext) 理解和概述 所说,ASP.NET 5的具有全新的配置机制,我们可以通过以下几点来进行理解: 支持…

中有冒号 文件路径_用Matlab脚本文件实现Excel文件的合并

日常吐槽前段时间跟同事聊天&#xff0c;同事洗脑了一个新的&#xff08;扎心的&#xff09;世界观&#xff0c;“人生分三个阶段&#xff0c;20岁时承认父母很平庸&#xff0c;30岁时承认自己很平庸&#xff0c;40岁时承认孩子很平庸”。这是这位同事在孩子学而思考试后的心得…

ios系统gps测试软件,GPS工具箱苹果版

GPS工具箱为用户准备的以手机GPS为基础的多功能位置服务的软件&#xff0c;它包括了很多非常实用的工具&#xff0c;包含线路追踪、测速、位置记录、面积测量等等&#xff0c;是GPS模块的功能发挥的非常充分到位&#xff0c;并且软件支持离线map和KML、KMZ导入导出、GPX文件导出…

用统计功能计算机计算js,js实现计算器功能

本文实例为大家分享了js实现计算器功能的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下知识点eval() 函数可计算某个字符串&#xff0c;并执行其中的的 JavaScript 代码。代码如下js计算器计算器.h1{position: relative;color:blueviolet;font-size:50px;text-align…

方法的覆盖

【转载】类继承时方法覆盖问题。&#xff08;static方法不能被”覆盖“&#xff09; (2014-04-03 17:51:17) 转载▼在看TIJ4的144页说&#xff1a; “覆盖”只有在某方法是基类的接口的一部分时才会出现。 即&#xff0c;必须能将一个对象向上转型为他的基本类型并调用相同的方…

恋与制作人 服务器错误,恋与制作人安装失败怎么办_恋与制作人安装失败解决方法_游戏吧...

恋与制作人是一款受到了很多玩家喜爱的游戏&#xff0c;游戏是奇迹暖暖原班人马打造的&#xff0c;但是却有玩家在安装时出现了安装失败的问题。下面游戏吧小编就为各位各位玩家带来了恋与制作人的安装失败解决方法。安装失败解决方法一、 安装软件时提示应用程序未安装或者提示…

create-react-app创建项目后运行npm run eject命令报错解决办法

用create-react-app创建项目,因要配置各种组件&#xff0c;比如babel&#xff0c;antd等&#xff0c; 需要运行npm run eject命令把项目的配置文件暴露出来&#xff0c;但是还是一如既然碰到报错&#xff0c;因为是在本地新创建的文件&#xff0c;没有添加git记录 解决办法&…

wps的计算机在哪里设置密码,wps文件怎么设置和取消密码 wps文件密码设置和取消的步骤方法...

在wps制作文件时&#xff0c;有时候我们需要中途离开&#xff0c;但是担心其他用户不小心操作导致文件丢失&#xff0c;那么我们可以设置wps文件密码&#xff0c;这样就可以避免了&#xff0c;那么怎么将wps文件设置密码呢?其实设置方法非常简单&#xff0c;下面教程之家网为大…

魔兽世界联盟物价稳定的服务器,一个残酷的真相!在《魔兽世界》怀旧服,女生一般都爱选联盟...

原标题&#xff1a;一个残酷的真相&#xff01;在《魔兽世界》怀旧服&#xff0c;女生一般都爱选联盟随着《魔兽世界》经典旧世的人气渐涨&#xff0c;暴雪又追加了3组PVP服&#xff0c;让不少没能抢注到心仪昵称的玩家欣喜若狂。这样一来&#xff0c;原本就饱受争议的服务器选…

SQL Server 2005 Hierarchies WITH Common Table Expressions

代码 1 createtableEmployee2 (3 Id INTIDENTITY(1,1) PRIMARYKEY, 4 [Name]varchar(30) null, 5 JobTitle varchar(30) null, 6 Manager intnull7 )8 9 insertEmployee10 selectincf, IT Director,nullunionall11 selectinc3, Finance Director,nullunionall12 select…