学习ASP.NET MVC5框架揭秘笔记-ASP.NET路由(二)

实例演示:通过路由实现请求地址与.aspx页面的映射

我们创建一个简单的ASP.NET Web Forms应用,并采用一套独立于.aspx文件路径的URL来访问对应的Web页面,两者之间的映射通过路由来实现,我们依然沿用员工管理的场景。

首先我们将员工的所有信息(ID、姓名、性别、出生日期和所在部门)定义在如下所示的Employee类型中,然后定义一个EmployeeRepository类型来维护员工列表的数据。简单起见,员工列表通过静态字段employees表示。EmployeeRepository的GetEmployees方法根据指定的ID返回对应的员工。如果指定的ID为“*”,则返回所有员工列表。

public class Employee
    {
        public string Id { get; private set; }
        public string Name { get; private set; }
        public string Gender { get; private set; }
        public DateTime BirthDate { get; private set; }
        public string Department { get; private set; }

        public Employee(string id, string name, string gender,DateTime birthDate, string department)
        {
            this.Id = id;
            this.Name = name;
            this.Gender = gender;
            this.BirthDate = birthDate;
            this.Department = department;
        }
    }
 public class EmployeeRepository
    {
        private static IList<Employee> employees;
        static EmployeeRepository()
        {
            employees = new List<Employee>();
            employees.Add(new Employee(Guid.NewGuid().ToString(), "张三", "男", new DateTime(1981, 8, 24), "销售部"));
            employees.Add(new Employee(Guid.NewGuid().ToString(), "李四", "女", new DateTime(1982, 7, 10), "人事部"));
            employees.Add(new Employee(Guid.NewGuid().ToString(), "王五", "男", new DateTime(1981, 9, 21), "人事部"));
        }
        public IEnumerable<Employee> GetEmployees(string id = "")
        {
            return employees.Where(e => e.Id == id || string.IsNullOrEmpty(id) || id == "*");
        }
    }

要通过一个独立于物理路径的URL来访问该.aspx页面,就要利用路由来实现两者之间的映射。我们将实现映射的路由注册代码定义在Global.asax文件中。如下面的代码片段所示,我们在Application_Start方法中通过RouteTable的Routes属性得到表示全局路由表的RouteCollection对象,并调用其MapPageRoute方法将页面的路径与一个路由模板进行映射。

public class Global : System.Web.HttpApplication
    {
        protected void Application_Start(object sender, EventArgs e)
        {
            var defaults = new RouteValueDictionary { { "name", "*" }, { "id", "*" } };
            RouteTable.Routes.MapPageRoute("", "employees/{name}/{id}","~/default.aspx", true, defaults);
        }
    }

作为MapPageRoute方法最后一个参数的RouteValueDictionary对象用于提供定义在路由模板中两个路由变量(“{name}”和“{id}”)的默认值。如果我们为定义路由模板中的路由变量指定了默认值,在当前请求地址的后续部分缺失的情况下,路由系统会采用提供的默认值对该地址进行填充之后再进行模式匹配。在如上的代码片段中,我们将{name}和{id}两个变量的默认值均指定为“*”。对于针对URL为“/employees”的请求,注册的Route会将其格式化成“/employees/*/*”,后者无疑与定义的路由模板的模式相匹配。

我们在Default.aspx页面中分别采用GridView和DetailsView来显示所有员工列表和某个列表的详细详细。GridView模板中显示为员工姓名的HyperLinkField的连接采用了什么定义在模板(employees/{name}/{id})中的模式。

<form id="form1" runat="server">
            <div id="page">
                    <asp:GridView ID="GridViewEmployees" runat="server" AutoGenerateColumns="false" Width="100%" CssClass="table table-bordered">
                    <Columns>
                        <asp:HyperLinkField HeaderText="姓名" DataTextField="Name" DataNavigateUrlFields="Name,Id" DataNavigateUrlFormatString="~/employees/{0}/{1}" />
                        <asp:BoundField DataField="Gender" HeaderText="性别" />
                        <asp:BoundField DataField="BirthDate" HeaderText="出生日期" DataFormatString="{0:dd/MM/yyyy}" />
                        <asp:BoundField DataField="Department" HeaderText="部门" />
                    </Columns>
                </asp:GridView>
                <asp:DetailsView ID="DetailsViewEmployee" runat="server" AutoGenerateRows="false"  Width="100%" CssClass="table table-bordered">
                     <Fields>
                          <asp:BoundField DataField="ID" HeaderText= "ID"  />
                          <asp:BoundField DataField="Name" HeaderText= "姓名"  />
                          <asp:BoundField DataField="Gender" HeaderText="性别" />
                          <asp:BoundField DataField="BirthDate" HeaderText="出生日期" DataFormatString="{0:dd/MM/yyyy}" />
                          <asp:BoundField DataField="Department" HeaderText="部门" />
                    </Fields>
                </asp:DetailsView>
            </div>
        </form>

由于所有员工列表和单一员工的详细信息均体现在这个页面中,所以我们需要根据具体的请求地址来判断应该呈现怎样的数据,这是通过代表当前页面的page对象的RouteData属性来实现的。Page类型的RouteData属性返回一个RouteData对象,他表示路由系统对当前请求进行解析得到的路由数据。RouteData的Value属性是一个存储路由变量的字典,其Key为变量名称。在如下所示的代码片段中,我们得到表示员工ID的路由变量(RouteData.Values[“id”]),如果它是默认值(*)就表示当前请求是针对员工列表的,反之则是针对指定的某个具体员工。

public partial class Default : System.Web.UI.Page
    {
        private EmployeeRepository repository;

        public EmployeeRepository Repository
        {
            get { return repository ?? (repository = new EmployeeRepository()); }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (this.IsPostBack)
            {
                return;
            }
            string employeeId = this.RouteData.Values["id"] as string;
            if (employeeId == "*" || string.IsNullOrEmpty(employeeId))
            {
                this.GridViewEmployees.DataSource = this.Repository.GetEmployees();
                this.GridViewEmployees.DataBind();
                this.DetailsViewEmployee.Visible = false;
            }
            else
            {
                var employees = this.Repository.GetEmployees(employeeId);
                this.DetailsViewEmployee.DataSource = employees;
                this.DetailsViewEmployee.DataBind();
                this.GridViewEmployees.Visible = false;
            }
        }
    }
时间: 2024-12-17 10:23:52

学习ASP.NET MVC5框架揭秘笔记-ASP.NET路由(二)的相关文章

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC是如何运行的(四)

Action的执行 作为Controller的基类ControllerBase,它的Execute方法主要作用在于执行目标Action方法.如果目标Action方法返回一个ActionResult对象,它还需要执行该对象来对当前请求予以响应.在ASP.NET MVC框架中,两者的执行是通过一个叫做ActionInvoker的对象来完成的. 1.ActionInvoker 我们同样为ActionInvoker定义了一个借口IActionInvoker.如下所示.该接口定义了唯一的方法InvokeA

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC是如何运行的(一)

ASP.NET MVC是如何运行的 ASP.NET由于采用了管道式设计,所以具有很好的扩展性,整个ASP.NET MVC应用框架就是通过扩展ASP.NET实现的.通过上面对ASP.NET管道设计的介绍我们知道,ASP.NET 的扩展点主要体现在HttpModule和HttpHandler这两个核心组件之上,整个ASP.NET MVC框架就是通过自定义的HttpModule和HttpHandler建立起来的. 接下来我们通过自定义组件来模拟ASP.NET MVC的运行原理. 1.4.1建立在迷你版

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC路由(五)

2.AreaRegistration的缓存 Area的注册(主要是基于Area的路由映射注册)通过具体的AreaRegistration来完成.在应用启动的时候,ASP.NET MVC会遍历通过调用BuildManager的静态方法GetReferencedAssemblies得到的程序集列表,并从中找到所有AreaRegistration类型.如果一个应用涉及太多的程序集,则这个过程可能会耗费很多时间.为了提高性能,ASP.NET MVC会对解析出来的所有AreaRegistration类型列

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC是如何运行的(三)

Controller的激活 ASP.NET MVC的路由系统通过注册的路由表对当前HTTP请求实施路由解析,从而得到一个用于封装路由数据的RouteData对象,这个过程是通过自定义的UrlRoutingModule对HttpApplication的PostResolveRequestCache事件进行注册实现的.由于得到的RouteData对象中已经包含了目标Controller的名称,我们需要根据该名称激活对应的Controller对象. 1.MvcRouteHandler 通过前面的介绍我

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC是如何运行的(五)

完整的流程 对于我们创建的这个迷你版的ASP.NET MVC框架来说,虽然很多细节被直接忽略掉,但是它基本上能够展现整个ASP.NET MVC框架的全貌,支持这个开发框架的核心对象可以说一个不少.接下来我们对通过这个模拟框架展现出来的ASP.NET MVC针对请求的处理流程作一个简单的概括. 由于UrlRoutingModule这个HttpModule被注册到Web应用中,所以对于每个抵达的请求来说,当代表当前应用的HttpApplication对象的PostResolveRequestCach

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC是如何运行的(二)

路由 对于一个ASP.NET MVC应用来说,针对HTTP请求的处理实现在目标Controller类型的某个Action,每个HTTP请求不在像ASP.NET Web Forms应用一样是针对一个物理文件,而是针对某个Controller的某个Action方法.目标Controller和Action的名称由HTTP请求的URL来决定,当ASP.NET MVC接收到抵达的请求后,其首要任务就是通过当前HTTP请求解析得到目标Controller和Action的名称,这个过程是通过ASP.NET M

学习ASP.NET MVC5框架揭秘笔记-ASP.NET路由(十一)

3.对现有物理文件的路由 在成功注册路由的情况下,如果我们按照传统的方式访问一个现存的物理文件,在请求地址满足某个Route的路由规则,ASP.NET是否还能正常实施路由呢?我们不妨通过实例来测试一下.为了让针对某个物理文件的访问地址也满足注册路由对象的路由模板采用的URL模式,我们需要按照如下的方式在进行路由注册时将表示约束的参数设置为Null. public class Global : System.Web.HttpApplication { protected void Applicat

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC路由(二)

2.2.2 路由注册 ASP.NET MVC通过调用代表全局路由表的RouteCollection对象的扩展方法MapRoute进行路由注册.我们来进行一个简单的实例演示.我们依然沿用之前关于获取天气信息的路由模板,看看通过这种方式注册的Route对象针对匹配的请求将返回怎样一个RouteData对象. 我们创建一个空的ASP.NET Web程序,并手动添加"System.Web.Mvc.dll"和"System.Web.WebPages.Razor.dll"的引用

学习ASP.NET MVC5框架揭秘笔记-ASP.NET MVC路由(三)

2.2.3缺省URL参数 当通过VisualStudio的ASP.NET MVC项目模板创建一个Web应用后,它会为我们注册如下一个模板为"{controller}/{action}/{id}"的默认Route对象.3个路由模板均有相应额默认值.但是变量名为id的默认值为URLParameter.Optional.按照字面的意思,我们将其称为可缺省URL参数.那么将路由变量的默认值进行如此设置与设置一个具体的默认值有什么区别呢? routes.MapRoute( name: "