1. Trang chủ
  2. » Tất cả

15.Chuong 15

61 5 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 61
Dung lượng 1,19 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Trong chương này, tôi sẽ chỉ cho bạn cách sử dụng hệ thống định tuyến để tạo ra sự mạnh mẽ và linh hoạt trong xử lý URL cho các dự án của bạn.. Trong chương này, tôi sẽ tập trung vào việ

Trang 1

CHAPTER 15

URL Routing

Trước khi giới thiệu MVC Framework, ASP.NET đã giả định rằng có một mối quan hệ trực tiếp giữa các URL được yêu cầu và các tập tin trên đĩa cứng của máy chủ Công việc của các máy chủ là nhận yêu cầu từ trình duyệt và cung cấp những đầu ra từ các tập tin tương ứng

Cách tiếp cận này chỉ làm tốt ở các Web Form, trong đó mỗi trang ASPX là cả một tập tin và một phản hồi khép kín đến một yêu cầu Nó không có ý nghĩa đối với một ứng dụng MVC, nơi yêu cầu được xử lý bằng phương thức action trong lớp controller và không có

sự tương quan one-to-one với các tập tin trên đĩa

Để xử lý các URL MVC, nền tảng ASP.NET sử dụng hệ thống định tuyến Trong chương này, tôi sẽ chỉ cho bạn cách sử dụng hệ thống định tuyến để tạo ra sự mạnh mẽ và linh hoạt trong xử lý URL cho các dự án của bạn Như bạn sẽ thấy, các hệ thống định tuyến cho phép bạn tạo ra bất kỳ mô hình của các URL mà bạn mong muốn và diễn đạt chúng một cách rõ ràng và súc tích Các hệ thống định tuyến có hai chức năng:

 Kiểm tra URL gọi đến và tìm ra controller và action nào yêu cầu được chỉ định

 Tạo URL gửi đi Đây là các URL xuất hiện trong HTML được biểu diễn từ các View để một action cụ thể sẽ được gọi khi người dùng nhấp chuột vào liên kết (tại thời điểm đó, nó đã trở thành một URL đến một lần nữa)

Trong chương này, tôi sẽ tập trung vào việc xác định các định tuyến và sử dụng chúng

để xử lý các URL đến để người dùng có thể tiếp cận với các bộ điều khiển và hành động của bạn Có hai cách để tạo ra các định tuyến trong một ứng dụng MVC Framework: ước dựa trên định tuyến và thuộc tính định tuyến Bạn sẽ được làm quen với quy ước dựa trên định tuyến nếu bạn đã sử dụng phiên bản trước của MVC Framework, nhưng thuộc tính định tuyến mới để MVC 5 Tôi giải thích cả hai phương pháp trong chương này

Sau đó, trong các chương tiếp theo, tôi sẽ cho bạn thấy làm thế nào để sử dụng các định tuyến tương tự để tạo ra các URL đi bạn sẽ cần đưa vào quan điểm của bạn, cũng như cho bạn thấy làm thế nào để tùy chỉnh hệ thống định tuyến và sử dụng một tính năng liên quan gọi là khu vực Bảng 15-1 cung cấp bản tóm tắt cho chương này

Trang 2

Chuẩn bị một ví dụ

Để chứng minh các hệ thống định tuyến, tôi cần một dự án mà tôi có thể thêm các định tuyến Tôi tạo ra một ứng dụng MVC mới bằng cách sử dụng the Empty template, và tôi gọi là dự án UrlsAndRoutes Tôi đã thêm một dự án thử nghiệm đển the Visual Studio solution được gọi là UrlsAndRoutes Thử nghiệm bằng cách kiểm tra các tùy chọn the Add Unit Tests, như thể hiện trong hình 15-1

Trang 3

Hình 15-1 Tạo một dự án ứng dụng MVC Empty với các kỹ thuật kiểm nghiệm

Tôi chỉ cho bạn làm thế nào để tạo ra các kỹ thuật kiểm nghiệm bằng tay cho các chương SportsStore, nhưng điều này tạo ra kết quả và xử lý các tham chiếu giữa các dự án

tự động thì tương tự Bạn vẫn sẽ cần thêm Moq, và do đó, nhập vào lệnh sau đây trong giao diện điều khiển NuGet:

Install-Package Moq -version 4.1.1309.1617 -projectname

UrlsAndRoutes.Tests

Tạo các Controllers Ví dụ:

Để chứng minh tính năng định tuyến, tôi sẽ thêm một số controller đơn giản vào ứng dụng

ví dụ này Tôi chỉ quan tâm đến cách thức mà các URL được diễn giải để gọi các phương thức action, do đó, các mô hình view tôi sử dụng là giá trị chuỗi trong view bag có gọi controller và tên phương thức action Đầu tiên, tạo một Home controller và thiết lập nội dung của nó để phù hợp với những thứ trong Liệt kê 15-1

Bảng liệt kê 15-1 Nội dung của tập tin HomeController.cs

Trang 4

namespace UrlsAndRoutes.Controllers { public

class CustomerController : Controller {

public ActionResult Index() {

Trang 5

Bảng liệt kê 15-3 Nội dung của tập tin AdminController.cs

using System.Web.Mvc;

namespace UrlsAndRoutes.Controllers {

public class AdminController : Controller {

public ActionResult Index() {

ActionName.cshtml vào nó, thiết lập các nội dung của quan điểm để phù hợp với Liệt kê 15-4

Bảng liệt kê 15-4 Nội dung của File ActionName.cshtml

<div>The controller is: @ViewBag.Controller</div>

<div>The action is: @ViewBag.Action</div>

</body>

</html>

Trang 6

Thiết lập các URL bắt đầu và kiểm thử các ứng dụng

Như tôi đã giải thích trong phần 1 trong cuốn sách này, Visual Studio sẽ cố gắng tìm ra các URL mà bạn muốn trình duyệt yêu cầu dựa trên các tập tin bạn đang chỉnh sửa khi bạn bắt đầu debugger Đây là một ý tưởng tốt mà nhanh chóng trở nên khó chịu và là một tính năng

mà tôi luôn luôn vô hiệu hóa Chọn UrlsAndRoutes Properties từ menu Project Studio Visual, chuyển sang tab Web và kiểm tra các tùy chọn Specific Page trong phần Start Action Bạn không cần phải cung cấp một giá trị chỉ kiểm tra các tùy chọn là đủ Nếu bạn bắt đầu ứng dụng ví dụ, bạn sẽ thấy câu trả lời thể hiện trong hình 15-2

Hình 15-2 Chạy các ứng dụng ví dụ

Giới thiệu Mẫu URL

Các hệ thống định tuyến làm nó kỳ diệu bằng cách sử dụng một tập hợp các định tuyến Những bộ định tuyến đó bao gồm các lược đồ URL hoặc lược đồ cho một ứng dụng, trong

đó là tập hợp các URL mà ứng dụng của bạn sẽ nhận ra và đáp ứng

Tôi không cần phải tự loại ra tất cả các URL riêng biệt tôi sẵn sàng để hỗ trợ trong các ứng dụng của tôi Thay vào đó, mỗi định tuyến có chứa một mẫu URL, được so sánh với các URL đến Nếu một URL phù hợp với mô hình, sau đó nó được sử dụng bởi các hệ thống định tuyến để xử lý URL đó Hãy bắt đầu với một URL cho các ứng dụng ví dụ: http://mysite.com/Admin/Index

URL có thể được chia thành phân đoạn Đây là những bộ phận của URL, không bao gồm hostname và chuỗi truy vấn, được phân cách bởi các ký tự / Trong URL ví dụ, có hai phân đoạn, như thể hiện trong hình 15-3

Hình 15-3 Những đoạn trong một URL ví dụ

Trang 7

Phân đoạn đầu tiên chứa từ Admin, và phân đoạn thứ hai chứa từ Index Tinh mắt hơn,

rõ ràng là phân đoạn đầu tiên liên quan đến controller và phân đoạn thứ hai liên quan đến action Nhưng, tất nhiên, tôi cần phải thể hiện mối quan hệ này trong một cách mà các hệ thống định tuyến có thể hiểu được Dưới đây là một mẫu URL mà thực hiện điều này: {controller}/{action}

Khi xử lý một yêu cầu gửi đến, công việc của các hệ thống định tuyến là kết hợp các URL đã được yêu cầu đến một mô hình và giải nén các giá trị từ các URL cho các biến mảng được xác định trong mô hình Các biến mảng được biểu diễn bằng cách sử dụng dấu ngoặc (các ký tự { và } ) Các mẫu ví dụ có hai biến mảng với tên controller và action, và

do đó giá trị của biến mảng controller sẽ là Admin và các giá trị của biến mảng action sẽ

là Index

Tôi nói phù hợp với một mô hình, vì một ứng dụng MVC thường sẽ có một số định tuyến và hệ thống định tuyến sẽ so sánh URL gọi đến đến các mẫu URL của từng định tuyến cho đến khi nó tìm thấy một sự phù hợp

Lưu ý Các hệ thống định tuyến không có bất kỳ kiến thức đặc biệt của các controller

và action Nó chỉ trích các giá trị cho các biến mảng Đó là sau này trong quá trình giải quyết yêu cầu, khi yêu cầu đến được MVC Framework thích hợp, có nghĩa là được gán cho các biến số controller và action Đây là lý do tại sao các hệ thống định tuyến có thể được sử dụng với Web Forms và các API Web (Tôi giới thiệu các API Web trong Chương

27 và tôi mô tả các yêu cầu quá trình xử lý ASP.NET trong chi tiết trong cuốn sách Pro ASP.NET MVC 5 Platform của tôi.)

Theo mặc định, một mẫu URL sẽ phù hợp với bất kỳ URL mà có số lượng chính xác của phân đoạn Ví dụ, mô hình {controller} / {action} sẽ phù hợp với bất kỳ URL mà có hai phân đoạn, được minh họa bằng Bảng 15-2

Bảng 15-2 URL Phù hợp

http://mysite.com/Admin/Index controller = Adminaction =

Index http://mysite.com/Index/Admin controller = Indexaction =

Admin http://mysite.com/Apples/Oranges controller = Applesaction =

Oranges http://mysite.com/Admin No match—too few segments

http://mysite.com/Admin/Index/Soccer No match—too many segments

Bảng 15-2 nhấn mạnh hai hành vi quan trọng của các mẫu URL:

Trang 8

 Mô hình URL rất bảo thủ, và chỉ sẽ phù hợp với URL có cùng số phân đoạn như mô hình Bạn có thể thấy điều này trong các ví dụ thứ tư và thứ năm trong bảng

 Mô hình URL là tự do Nếu một URL không có con số chính xác của phân đoạn,

mô hình sẽ trích xuất các giá trị cho các biến mảng, bất cứ điều gì có thể được Đây là những hành vi mặc định, trong đó là chìa khóa để hiểu được như thế nào là Mô hình URL chức năng Tôi chỉ cho bạn làm thế nào để thay đổi mặc định sau trong chương này

Như đã đề cập, các hệ thống định tuyến không biết bất cứ điều gì về một ứng dụng MVC, và do đó Mô hình URL sẽ phù hợp ngay cả khi không có controllerhoặc action tương ứng với giá trị chiết xuất từ một URL Bạn có thể thấy điều này được chứng minh trong ví dụ thứ hai trong Bảng 15-2 Tôi hoán Admin và phân đoạn Index trong URL, và

do đó, các giá trị chiết xuất từ các URL cũng đã được hoán đổi, mặc dù không có controller Index trong dự án ví dụ

Tạo và Đăng ký Định tuyến đơn giản

Một khi bạn có một mẫu URL trong tâm trí, bạn có thể sử dụng nó để xác định một định tuyến Định tuyến được định nghĩa trong file RouteConfig.cs, đó là trong thư mục dự án App_Start Bạn có thể xem các nội dung ban đầu mà Visual Studio xác định cho tập tin này trong Liệt kê 15-5

Bảng liệt kê 15-5 Nội dung mặc định của tập tin RouteConfig.cs

Trang 9

Phương thức RegisterRoutes tĩnh được định nghĩa trong file RouteConfig.cs được gọi

là từ các tập tin Global.asax.cs, trong đó thiết lập một số các tính năng cốt lõi MVC khi ứng dụng được bắt đầu chạy Bạn có thể xem nội dung mặc định của tập tin Global.asax.cs trong Liệt kê 15-6, và tôi đã làm nổi bật lời gọi đến phương thức RouteConfig.RegisterRoutes, được làm từ các phương thức Application_Start

Bảng liệt kê 15-6 Nội dung mặc định của File Global.asax.cs

public class MvcApplication : System.Web.HttpApplication { protected

void Application_Start() { AreaRegistration.RegisterAllAreas();

tả ngay

Trang 10

Bảng liệt kê 15-7 cho thấy làm thế nào để tạo ra một định tuyến sử dụng các mẫu ví

dụ URL từ phần trước trong phương thức RegisterRoutes của tập tin RouteConfig.cs (Tôi

đã gỡ bỏ các báo cáo khác trong phương thức này để tôi có thể tập trung vào các ví dụ.)

Bảng liệt kê 15-7 Đăng ký một Route trong RouteConfig.cs file

public static void RegisterRoutes(RouteCollection routes) { Route myRoute

= new Route("{controller}/{action}", new MvcRouteHandler());

vi định tuyến, và đây là các lớp được sử dụng cho các ứng dụng ASP.NET MVC Một khi tôi đã tạo ra các định tuyến, tôi thêm vào các đối tượng RouteCollection sử dụng phương thức Add, truyền vào tên tôi muốn route được biết đến bởi các định tuyến của chính nó

Mẹo: đặt tên định tuyến của bạn là không bắt buộc và có một cuộc tranh luận triết học

mà làm như vậy sẽ hi sinh một số phân chia ngắn gọn của các mối lo ngại mà nếu không xuất phát từ định tuyến Tôi thoải mái về việc đặt tên, nhưng tôi sẽ giải thích tại sao điều này có thể là một vấn đề trong các "Tạo ra một URL từ một cụ Route" trong Chương 16 Một cách thuận tiện hơn trong việc đăng ký các định tuyến là sử dụng phương thức MapRoute xác định bởi lớp RouteCollection Liệt kê 15-8 cho thấy làm thế nào tôi có thể

sử dụng phương pháp này để đăng ký một định tuyến, trong đó có tác dụng tương tự như

ví dụ trước, nhưng có một cú pháp ngắn gọn hơn

Trang 11

Bảng liệt kê 15-8 Đăng ký một Route Sử dụng phương thức MapRoute trong RouteConfig.cs file

có thể sử dụng phương thức MapPageRoute, cũng được định nghĩa trong lớp RouteCollection

Sử dụng các Route đơn giản

Bạn có thể xem hiệu quả của những thay đổi tôi thực hiện cho định tuyến bằng cách khởi động ứng dụng ví dụ Bạn sẽ thấy một lỗi khi trình duyệt cố gắng điều hướng đến các URL gốc cho ứng dụng, nhưng nếu bạn điều hướng đến một định tuyến phù hợp với {controller} / {action} mô hình, bạn sẽ thấy một kết quả giống như thể hiện trong hình 15 -4, minh họa ảnh hưởng của điều hướng đến / Admin / Index

Trang 12

Hình 15-4 Điều hướng bằng một con đường đơn giản

Route đơn giản của tôi trong Liệt kê 15-8 không nói MVC Framework đến cách đáp ứng yêu cầu cho các URL gốc như thế nào và chỉ hỗ trợ đơn lẻ, cụ thể, mẫu URL Tôi đã tạm thời đưa một bước trở lại từ các chức năng mà Visual Studio thêm vào các tập tin RouteConfig.cs khi nó tạo ra dự án, nhưng tôi sẽ cho bạn thấy làm thế nào để xây dựng các

mô hình phức tạp hơn và các định tuyến trong suốt phần còn lại của chương này

Tôi đã tạm thời đưa một bước lùi lại từ các chức năng mà Visual Studio thêm vào các tập tin RouteConfig.cs khi nó tạo ra dự án, nhưng tôi sẽ cho bạn thấy làm thế nào để xây dựng các mô hình và các định tuyến phức tạp hơn trong suốt phần còn lại của chương này

UNIT TEST: Thử nghiệm các URL gửi đến

Tôi khuyên bạn nên kiểm tra đơn vị định tuyến của bạn để chắc chắn rằng họ xử lý các URL gửi đến như mong đợi, thậm chí nếu bạn không chọn đến đơn vị kiểm tra phần còn lại của ứng dụng của bạn Các schema URL có thể trở nên khá phức tạp trong các ứng dụng lớn, và nó rất dễ dàng để tạo ra một kết quả bất ngờ

Trong chương trước, tôi đã tránh tạo ra phương thức hổ trợ phổ biến để được chia sẻ giữa các thử nghiệm để giữ cho mỗi đơn vị thử nghiệm mô tả khép kín Trong chương này, tôi đang tiếp cận khác nhau Kiểm tra sơ đồ định tuyến cho một ứng dụng thì làm

dễ dàng nhất khi bạn có thể trộn một số thử nghiệm trong một phương thức duy nhất,

và đây trở nên dễ dàng hơn nhiều với một số phương thức hỗ trợ

Để kiểm tra các định tuyến, tôi cần phải thử ba lớp từ MVC Framework:

HttpRequestBase, HttpContextBase, và HttpResponseBase (Lớp cuối cùng này là cần

thiết để kiểm tra các URL gửi đi, mà tôi giới thiệu trong chương tiếp theo.) Dù sao, các lớp này tạo đủ cơ sở hạ tầng MVC để hỗ trợ hệ thống định tuyến Tôi đã thêm một file

mới đơn vị thử nghiệm được gọi là RouteTests.cs để các dự án thử nghiệm UrlsAndRoutes.Các đơn vị thử nghiệm kiểm tra dự án và bổ sung đầu tiên của tôi là các phương thức trợ giúp tạo ra các đối tượng HttpContextBase giả, như sau:

Trang 13

using Microsoft.VisualStudio.TestTools.UnitTesting;

using Moq; using System; using System.Reflection;

using System.Web; using System.Web.Routing;

namespace UrlsAndRoutes.Tests {

[TestClass]

public class

RouteTests {

private HttpContextBase CreateHttpContext(string targetUrl = null,

string httpMethod = "GET") {

// create the mock request

Mock<HttpRequestBase> mockRequest = new Mock<HttpRequestBase>(); mockRequest.Setup(m => m.AppRelativeCurrentExecutionFilePath)

Returns(targetUrl);

mockRequest.Setup(m => m.HttpMethod).Returns(httpMethod);

// create the mock response

Mock<HttpResponseBase> mockResponse = new

Mock<HttpResponseBase>

();

mockResponse.Setup(m => m.ApplyAppPathModifier(

It.IsAny<string>())).Returns<string>(s => s);

// create the mock context, using the request and response

Mock<HttpContextBase> mockContext = new Mock<HttpContextBase>(); mockContext.Setup(m => m.Request).Returns(mockRequest.Object);

theo của tôi cho phép tôi thử nghiệm một định tuyến:

private void TestRouteMatch(string url, string controller, string action,

Trang 14

object routeProperties = null, string httpMethod = "GET") {

Các tham số của phương thức này cho phép tôi chỉ định URL để kiểm tra, giá trị dự

kiến cho controller và action biến mảng, và một đối tượng có chứa các giá trị dự kiến

cho bất kỳ biến số bổ sung tôi đã xác định Tôi sẽ chỉ cho bạn cách để tạo ra các biến như sau trong chương này và trong các chương tiếp theo Tôi cũng xác định một tham

số cho phương thức HTTP, mà tôi sẽ giải thích trong phần "Ràng buộc định tuyến " Phương thức TestRouteMatch dựa vào một phương thức khác,

TestIncomingRouteResult, để so sánh các kết quả thu được từ hệ thống định tuyến với

các giá trị biến mảng mà tôi mong đợi Phương thức này sử dụng NET phản ánh để tôi

có thể sử dụng một loại nặc danh để trình bày bất kỳ biến mảng bổ sung Đừng lo lắng nếu phương thức này không có ý nghĩa, vì đây chỉ là để làm cho thử nghiệm thuận tiện hơn; nó không phải là một yêu cầu cho sự tìm hiểu MVC Đây là phương pháp

TestIncomingRouteResult:

private bool TestIncomingRouteResult(RouteData routeResult, string

controller, string action, object propertySet = null) {

Func<object, object, bool> valCompare = (v1, v2) => {

return StringComparer.InvariantCultureIgnoreCase

Compare(v1, v2) == 0;

};

Trang 15

bool result = valCompare(routeResult.Values["controller"], controller)

&& valCompare(routeResult.Values["action"], action);

if (propertySet != null) {

PropertyInfo[] propInfo = propertySet.GetType().GetProperties();

foreach (PropertyInfo pi in propInfo) { if

// Act - process the route

RouteData result = routes.GetRouteData(CreateHttpContext(url));

// Assert

Assert.IsTrue(result == null || result.Route == null); }

TestRouteMatch và TestRouteFail chứa các lệnh gọi đến các phương thức Assert, mà

chuyển vào một ngoại lệ nếu khẳng định thất bại Bởi vì trường hợp ngoại lệ trong C

# được truyền lên các lệnh gọi stack, tôi có thể tạo ra phương thức thử nghiệm đơn giản để thử nghiệm một tập hợp các URL và nhận được những hành vi kiểm thử tôi yêu cầu Dưới đây là một phương thức kiểm thử định tuyến mà tôi định nghĩa trong

Liệt kê 15-8:

Trang 16

[TestMethod]

public void TestIncomingRoutes() {

// check for the URL that is hoped for

TestRouteMatch("/Admin/Index", "Admin", "Index");

// check that the values are being obtained from the segments

TestRouteMatch("/One/Two", "One", "Two");

// ensure that too many or too few segments fails to match

Kiểm thử này sử dụng các phương thức TestRouteMatch để kiểm tra các URL Tôi đang

mong đợi và cũng kiểm tra một URL trong các dạng tương tự để đảm bảo rằng các giá

trị controller và action đang nhận được cách sử dụng thích hợp phân đoạn URL Tôi

sử dụng phương thức TestRouteFail để đảm bảo rằng các ứng dụng sẽ không chấp

nhận các URL có một số lượng khác nhau của phân đoạn Khi kiểm thử , tôi phải thêm tiền tố URL với ký tự dấu ngã (~), bởi vì đây là cách Framework ASP.NET trình bày các URL đến hệ thống định tuyến

Chú ý là tôi không cần phải xác định các định tuyến trong các phương thức kiểm thử Điều này là bởi vì tôi đang tải chúng trực tiếp bằng cách sử dụng phương thức

RegisterRoutes trong lớp RouteConfig

Xác định giá trị mặc định

Lý do mà tôi đã nhận ra lỗi khi tôi yêu cầu các URL mặc định cho các ứng dụng là do nó không phù hợp với định tuyến tôi đã xác định

Các URL mặc định được biểu diễn theo ~ / đến các hệ thống định tuyến và không có

phân đoạn trong chuỗi này có thể được kết hợp với các giá trị controller và action được

xác định bởi mô hình định tuyến đơn giản

Tôi đã giải thích rằng các mẫu URL là bảo thủ, trong đó chúng sẽ phù hợp với URL duy nhất với số quy định của phân đoạn Tôi cũng cho rằng, đây là hành vi mặc định và một cách để thay đổi hành vi này là sử dụng các giá trị mặc định Một giá trị mặc định

Trang 17

được áp dụng khi các URL không chứa một phân khúc có thể được kết hợp với các giá trị

Bảng liệt kê 15-9 cung cấp một ví dụ về một định tuyến có chứa một giá trị mặc định

Bảng liệt kê 15-9 Cung cấp một giá trị mặc định trong các tập tin RouteConfig.cs

public static void RegisterRoutes(RouteCollection routes) {

routes.MapRoute("MyRoute", "{controller}/{action}", new {

hợp với tất cả các URL hai phân khúc, như nó đã làm trước đây Ví dụ, nếu

http://mydomain.com/Home/Index URL được yêu cầu, định tuyến này sẽ giải nén Home như là biến cho các controller và Index như biến cho các action

Bây giờ tôi đã cung cấp một giá trị mặc định cho phân đoạn action, các định tuyến

cũng sẽ kết hợp các URL đơn phân khúc Khi xử lý một URL đơn phân khúc, các hệ thống

định tuyến sẽ trích xuất các giá trị controller từ phân khúc URL đơn, và sử dụng các giá trị mặc định cho biến action Bằng cách này, tôi có thể yêu cầu các URL

http://mydomain.com/Home và gọi phương thức action Index trên controller Home

Tôi có thể đi xa hơn và xác định các URL không chứa bất kỳ biến ở tất cả phân đoạn,

chỉ dựa trên là những giá trị mặc định để xác định các action và controller Và như là một

ví dụ, Liệt kê 15-10 cho thấy làm thế nào tôi đã ánh xạ URL gốc cho ứng dụng bằng cách cung cấp các giá trị mặc định cho cả hai phân đoạn

Bảng liệt 15-10 Cung cấp các Action và controller giá trị mặc định trong file RouteConfig.cs

using System;

Trang 18

public static void RegisterRoutes(RouteCollection routes) {

routes.MapRoute("MyRoute", "{controller}/{action}", new {

controller = "Home", action = "Index" });

}

}

}

Bằng cách cung cấp các giá trị mặc định cho cả biến controller và Action, tôi đã tạo ra

một định tuyến sẽ phù hợp với URL có không, một, hoặc hai đoạn, như thể hiện trong

Bảng 15-3

Bảng 15-3 URL Matching

0 mydomain.com controller = Homeaction = Index

1 mydomain.com/Customer controller = Customeraction =

Framework đến lời gọi phương thức action Index trên controller Home, như thể hiện trong

hình 15 -5

Trang 19

Hình 15-5 Sử dụng các giá trị mặc định để mở rộng phạm vi của một định tuyến

ĐƠN VỊ KIỂM ĐỊNH: GIÁ TRỊ MẶC ĐỊNH

Tôi không cần phải thực hiện bất kỳ action đặc biệt để sử dụng các phương thức hỗ trợ để kiểm thử định tuyến mà xác định các giá trị mặc định Dưới đây là các phiên

bản tôi đã thực hiện các phương thử kiểm thử TestIncomingRoutes trong file RouteTests.cs cho định tuyến mà tôi định nghĩa trong Liệt kê 15-10:

Sử dụng phân đoạn URL tĩnh

Trang 20

Không phải tất cả phân đoạn trong một mẫu URL cần các biến số Bạn cũng có thể tạo ra các mẫu có phân đoạn tĩnh Giả sử rằng tôi muốn kết hợp một URL như thế này để hỗ trợ

các URL được bắt đầu với Public:

new { controller = "Home", action = "Index" });

routes.MapRoute("", "Public/{controller}/{action}", new

{ controller = "Home", action = "Index" });

}

}

}

Mô hình mới này sẽ phù hợp với URL duy nhất có chứa ba phân đoạn, phần đầu tiên

trong số đó phải là Public Hai phân đoạn khác có thể chứa bất kỳ giá trị nào, và sẽ được

sử dụng cho các giá trị controller và action Nếu hai phân đoạn cuối cùng bị bỏ qua, sau

Trang 21

routes.MapRoute("MyRoute", "{controller}/{action}", new

{ controller = "Home", action = "Index" });

routes.MapRoute("", "Public/{controller}/{action}", new {

controller = "Home", action = "Index" });

}

}

}

Các mô hình trong định tuyến này kết hợp với bất kỳ hai phân khúc URL mà phân

đoạn đầu tiên bắt đầu bằng chữ X Giá trị của controller được lấy từ phân đoạn đầu tiên, không bao gồm giá trị X Các action được lấy từ phân đoạn thứ hai Bạn có thể xem hiệu quả của định tuyến này nếu bạn khởi động ứng dụng và điều hướng đến / XHome / Index,

và kết quả là được minh họa bằng hình 15-6

Hình 15-6 Trộn thành phần tĩnh và biến trong một phân khúc duy nhất

Trang 22

ĐỊNH TUYẾN ĐẶT HÀNG

Trong Liệt kê 15-12, tôi xác định một định tuyến mới và đặt nó trước tất cả những

định tuyến khác trong các phương thức RegisterRoutes Tôi đã làm điều này bởi vì

các định tuyến được áp dụng trong thứ tự mà chúng xuất hiện trong các đối tượng

RouteCollection Phương thức MapRoute thêm một định tuyến đến cuối của bộ sưu

tập, có nghĩa là định tuyến thường được áp dụng trong thứ tự mà chúng được định nghĩa Tôi nói "thường" vì có những phương thức chèn các định tuyến tại các vị trí

cụ thể Tôi có xu hướng không sử dụng những phương thức này, bởi vì có định tuyến áp dụng thứ tự mà chúng được xác định làm cho sự hiểu biết định tuyến về một ứng dụng đơn giản hơn

Hệ thống định tuyến cố gắng để kết hợp với một URL đến với mẫu URL của định tuyến đã được xác định từ trước, và tiến tới định tuyến duy nhất tiếp theo nếu không phù hợp Định tuyến này được thử nghiệm theo trình tự đến khi định tuyến phù hợp được tìm thấy hoặc tập hợp các định tuyến đã hết Kết quả của việc này là định tuyến

cụ thể nhất phải được xác định trước tiên Định tuyến tôi thêm vào trong Listing

15-12 đặc trưng hơn là định tuyến theo sau Giả sử rằng tôi đảo ngược thứ tự của các định tuyến, như thế này:

routes.MapRoute("MyRoute",

"{controller}/{action}", new { controller =

"Home", action = "Index" }); routes.MapRoute("",

để bất kỳ URL ưa thích, macro hoặc các scripts mà người dùng đã tạo ra để tiếp tục làm

Trang 23

việc Hãy tưởng tượng rằng tôi đã từng có controller được gọi là Shop, mà bây giờ đã được thay thế bằng controller Home Liệt kê 15-13 cho thấy làm thế nào tôi có thể tạo ra một con đường để bảo tồn các schema URL cũ

Bảng liệt 15-13 Trộn đoạn URL tĩnh và giá trị mặc định trong File RouteConfig.cs

routes.MapRoute("MyRoute", "{controller}/{action}", new

{ controller = "Home", action = "Index" });

routes.MapRoute("", "Public/{controller}/{action}",

new { controller = "Home", action = "Index" }); }

}

}

Định tuyến tôi thêm kết hợp với bất kỳ URL hai phân khúc mà các phân đoạn đầu tiên

là Shop Các giá trị action được lấy từ đoạn URL thứ hai Các mẫu URL không chứa một biến mảng controller, do đó, các giá trị mặc định tôi đã cung cấp thì được sử dụng Điều này có nghĩa rằng một yêu cầu cho một action trên controller Shop được chuyển sang một yêu cầu cho controller Home Bạn có thể xem tác dụng của định tuyến này bằng cách khởi động ứng dụng và điều hướng đến URL / Shop / Index Như Hình 15-7 cho thấy, định tuyến mới khiến MVC Framework nhắm mục tiêu đến phương thức action Index trong controller Home

Trang 24

Hình 15-7 Tạo một bí danh để bảo tồn schemas URL

Tôi có thể đi một bước xa hơn và tạo các bí danh cho các phương thức action đó đã

được tái cấu trúc lại tốt hơn và không còn hiện diện trong controller Để làm điều này, tôi tạo ra một URL tĩnh và cung cấp các giá trị controller và action như mặc định, như trong

routes.MapRoute("MyRoute", "{controller}/{action}", new

{ controller = "Home", action = "Index" });

Trang 25

routes.MapRoute("", "Public/{controller}/{action}", new {

controller = "Home", action = "Index" });

}

}

}

Chú ý rằng, một lần nữa, tôi đã đặt định tuyến mới để nó được xác định đầu tiên Điều

này là bởi vì nó có đặc trưng hơn các định tuyến theo sau Nếu một yêu cầu cho Shop / OldAction đã được xử lý bởi định tuyến được xác định tiếp theo, ví dụ, tôi sẽ có được một

kết quả khác nhau từ một trong những thứ tôi muốn Các yêu cầu này sẽ được xử lý bằng

cách sử dụng một lỗi 404—Not Found, chứ không phải được dịch để bảo toàn một hợp

đồng với khách hàng của tôi

UNIT TEST: KIỂM THỬ PHẬN ĐOẠN TĨNH

Một lần nữa, tôi có thể sử dụng phương thức hỗ trợ của tôi để các định tuyến có các mẫu URL có chứa phân đoạn tĩnh Đây là sự bổ sung tôi đã thực hiện phương thức đơn vị kiểm thử TestIncomingRoutes để kiểm tra định tuyến được thêm vào trong liệt kê 15-14:

TestRouteMatch("/Customer", "Customer", "Index");

TestRouteMatch("/Customer/List", "Customer", "List");

Định nghĩa biến mảng Tuỳ chỉnh

Các biến mảng controller và action có ý nghĩa đặc biệt với MVC Framework và, rõ

ràng, chúng tương ứng với phương thức controller và action sẽ được sử dụng để phục vụ yêu cầu Nhưng đây chỉ là được xây dựng trong các giá trị phân khúc Tôi cũng có thể định

Trang 26

nghĩa các biến riêng của tôi, như thể hiện trong Liệt kê 15-15 (Tôi đã gỡ bỏ định tuyến hiện có từ các phần đoạn trước để tôi có thể bắt đầu lại.)

Bảng liệt 15-15 Định nghĩa biến bổ sung trong một mẫu URL trong RouteConfig.cs file

public static void RegisterRoutes(RouteCollection routes) {

routes.MapRoute("MyRoute", "{controller}/{action}/{id}", new {

controller = "Home", action = "Index", id = "DefaultId" });

ba, giá trị mặc định sẽ được sử dụng

Cảnh cáo :Một số tên được dành riêng và không có sẵn cho các phân đoạn tùy chỉnh

tên biến Đây là controller, action, và area Ý nghĩa của hai phần đầu tiên là hiển nhiên,

và tôi sẽ giải thích area trong chương tiếp theo

Tôi có thể truy cập vào bất kỳ của các biến mảng trong một phương thức action bằng

cách sử dụng thuộc tính RouteData.Values Để chứng minh điều này, tôi đã thêm một phương thức action đến controller Home được gọi là CustomVariable, như thể hiện trong

Trang 27

` public ActionResult Index() {

Phương thức này có được các giá trị của biến tùy chỉnh trong mô hình định tuyến URL

và truyền qua nó đến view bằng cách sử dụng ViewBag

Để tạo view cho các phương thức action, tạo ra các thư mục Views / Home, nhấn chuột phải vào nó, chọn Add MVC 5 View Page (Razor)từ trình đơn pop-up và đặt tên là CustomVariable.cshtml Nhấp vào nút OK để tạo view và chỉnh sửa nội dung kết hợp liệt

<div>The controller is: @ViewBag.Controller</div>

<div>The action is: @ViewBag.Action</div>

<div>The custom variable is: @ViewBag.CustomVariable</div>

Trang 28

</body>

</html>

Để xem ảnh hưởng của các biến mảng tùy chỉnh, khởi động ứng dụng và điều hướng

đến URL / Home / CustomVariable / Hello Phương thức hành động CustomVariable trong controller Home được gọi, và giá trị của các biến mảng tùy chỉnh được lấy từ ViewBag và

truyền đến view Bạn có thể xem kết quả trong hình 15-8

Hình 15-8 Hiển thị các giá trị của một biến mảng tùy chỉnh

Tôi đã cung cấp một giá trị mặc định cho biến mảng id trong định tuyến, có nghĩa là

bạn sẽ thấy những kết quả thể hiện trong hình 15-9 nếu bạn điều hướng đến / Home / CustomVariable

Hình 15-9 Giá trị mặc định cho một biến mảng tùy chỉnh

UNIT TEST: KIỂM THỬ BIẾN PHẬN ĐOẠN TUỲ CHỈNH

Tôi giới thiệu cách hỗ trợ để kiểm thử các biến số phân đoạn tùy chỉnh trong các

phương thức trợ giúp kiểm thử Phương thức TestRouteMatch có một tham số tùy

chọn mà có thể chấp nhận một loại nặc danh có chứa tên của các thuộc mà tôi muốn kiểm thử cho các giá trị mà tôi mong đợi Dưới đây là những thay đổi mà tôi đã thực

Trang 29

hiện phương thức kiểm thử TestIncomingRoutes để kiểm thử định tuyến được xác

định trong Liệt kê 15-15:

[Testmethod]

public void TestIncomingRoutes() {

TestRouteMatch("/", "Home", "Index", new {

id = "DefaultId" });

TestRouteMatch("/Customer", "Customer",

"index", new { id = "DefaultId" });

TestRouteMatch("/Customer/List", "Customer",

"List", new { id = "DefaultId" });

Sử dụng biến tùy chỉnh như các tham số phương thức Action

Sử dụng thuộc tính RouteData.Values là chỉ có một cách để truy cập các biến định tuyến

Một cách khác là rõ ràng hơn nhiều Nếu tôi xác định các tham số cho phương thức action với những cái tên kết hơp với các giá trị mẫu URL, MVC Framework sẽ truyền qua các giá trị thu được từ các URL như tham số cho phương thức action Ví dụ, các biến tùy chỉnh tôi quy định tại định tuyến trong Listing 15-15 được gọi là id Tôi có thể sửa đổi phương thức action CustomVariable trong controller Home để nó có một tham số phù hợp, như

trong Liệt kê 15-18

Bảng liệt 15-18 Thêm một tham số phương thức Action trong tập tin HomeController.cs

Trang 30

public ActionResult Index() {

Tôi đã xác định các tham số id như là string, nhưng MVC Framework sẽ cố gắng để

chuyển đổi các giá trị URL đế bất cứ kiểu tham số tôi định nghĩa Nếu tôi khởi tạo tham số

id là một int hoặc một DateTime, sau đó tôi sẽ nhận được giá trị từ URL đã phân tích một

thực thể của loại đó Đây là một tính năng đơn giản và hữu ích mà loại bỏ sự cần thiết cho tôi để xử lý các chuyển đổi bản thân mình

Chú ý: MVC Framework sử dụng các tính năng ràng buộc mô hình để chuyển đổi các

giá trị chứa trong URL đến loại NET và có thể xử lý các tình huống phức tạp hơn nhiều

so với trình bày trong ví dụ này Tôi bao hàm mô hình ràng buộc trong Chương 24

Định nghĩa phân đoạn Tùy chọn URL

Một phân đoạn tùy chọn URL là một trong những người dùng không cần phải xác định,

nhưng mà không có giá trị mặc định là cụ thể Bảng liệt kê 15-19 cho thấy một ví dụ, và bạn có thể thấy rằng tôi xác định rằng một biến mảng là tùy chọn bằng cách thiết lập các

Ngày đăng: 23/10/2019, 21:15

TỪ KHÓA LIÊN QUAN

w