学习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; } } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。