1. Trang chủ
  2. » Công Nghệ Thông Tin

ASP.NET 4 Unleased - p 117 pptx

10 159 0
Tài liệu đã được kiểm tra trùng lặp

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Advanced Navigation
Trường học Standard University
Chuyên ngành Computer Science
Thể loại Thesis
Năm xuất bản 2023
Thành phố New York
Định dạng
Số trang 10
Dung lượng 577,17 KB

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

Nội dung

They still work in ASP.NET 4, but you might want to consider using the new Routing Engine if your goal is to provide powerful, flexible URL schemes that still invoke underlying ASPx page

Trang 1

CHAPTER 24 Advanced Navigation

Typically, you override the FileExists() and GetFile() methods to retrieve a file from

your data store If you want to represent directories, you also need to override the

DirectoryExists() and GetDirectory() methods

Several of these methods are related to caching The VirtualPathProvider needs to know

when a file has been modified so that it can retrieve the new version of the file and

compile it By default, the ASP.NET Framework uses a file dependency to determine when

a file has been modified on the hard drive However, in this situation a

SqlCacheDependency is used because the files will be stored in a database

The VirtualPathProvider also includes a useful property:

Previous—Returns the previously registered VirtualPathProvider

The Previous property enables you to use the default VirtualPathProvider For example,

if you want to store some files in the file system and other files in the database, you can

use the Previous property to avoid rewriting all the logic for working with files in the

file system

The GetFile() method returns an instance of the VirtualFile class When using the

VirtualPathProvider, you must create a new class that inherits from the VirtualFile

class This class contains the following properties:

IsDirectory—Always returns False

Name—Returns the name of the file

VirtualPath—Returns the virtual path of the file

The VirtualFile class also contains the following method:

Open()—Returns the contents of the file

Typically, when creating a class that inherits from the VirtualFile class, you override the

Open() method For example, we override this method to get the contents of a file from a

database table in the code sample built in this section

The GetDirectory() method returns an instance of the VirtualDirectory class This class

contains the following properties:

Children—Returns all the files and directories that are children of the current

directory

Directories—Returns all the directories that are children of the current directory

Files—Returns all the files that are children of the current directory

IsDirectory—Always returns True

Name—Returns the name of the directory

VirtualPath—Returns the virtual path of the directory

Trang 2

Using the VirtualPathProvider Class

There is another class in the ASP.NET Framework that you want to use when working with

the VirtualPathProvider class The VirtualPathUtility class contains several useful

methods for working with virtual paths:

AppendTrailingSlash()—Returns a path with at most one forward slash appended

to the end of the path

Combine()—Returns the combination of two virtual paths

GetDirectory()—Returns the directory portion of a path

GetExtension()—Returns the file extension of a path

GetFileName()—Returns the filename from a path

IsAbsolute()—Returns True when a path starts with a forward slash

IsAppRelative()—Returns True when a path starts with a tilde (~)

MakeRelative()—Returns a relative path from an application-relative path

RemoveTrailingSlash()—Removes trailing slash from the end of a path

ToAbsolute()—Returns a path that starts with a forward slash

ToAppRelative()—Returns a path that starts with a tilde (~)

By taking advantage of the VirtualPathUtility class, you can avoid doing a lot of tedious

string parsing on paths

Registering a VirtualPathProvider Class

Before you can use an instance of the VirtualPathProvider class, you must register it for

your application You can register a VirtualPathProvider instance with the

HostingEnvironment.RegisterVirtualPathProvider() method

You need to register the VirtualPathProvider when an application first initializes You

can do this by creating a shared method named AppInitialize() and adding the method

to any class contained in the App_Code folder The AppInitialize() method is

automati-cally called by the ASP.NET Framework when an application starts

For example, the following AppInitialize method registers a VirtualPathProvider

named MyVirtualPathProvider:

public static void AppInitialize()

{

MyVirtualPathProvider myProvider = new MyVirtualPathProvider();

HostingEnvironment.RegisterVirtualPathProvider(myProvider);

}

Trang 3

CHAPTER 24 Advanced Navigation

Summary

This chapter explored several advanced topics related to website navigation In the first

two sections, you learned how to map URLs from one path to another In the first section,

you learned how to configure remappings in the Web configuration file In the second

section, you learned how to build a custom HTTP module, which enables you to use

wild-card matches when remapping a URL

In the final section of this chapter, you learned how to abstract pages in your application

from the file system by using the VirtualPathProvider class The techniques described in

this chapter remain in this book mostly for backward compatibility with previous

versions of ASP.NET They still work in ASP.NET 4, but you might want to consider using

the new Routing Engine if your goal is to provide powerful, flexible URL schemes that

still invoke underlying ASPx pages If you are simply pointing one location to another, or

providing a URL scheme on top of nonexecutable content files, this chapter still applies

to your situation

Trang 4

Using the ASP.NET URL

Routing Engine

IN THIS CHAPTER

Introduction to URL Routing Basic URL Routing Scenarios Advanced URL Routing Summary

One of the many new features introduced in ASP.NET 4 is

the concept of URL routing This chapter provides you with

an introduction to URL routing and why it should concern

you as an ASP.NET Web Forms developer, then continues

with examples of various scenarios in which URL routing

truly shines, and finishes with coverage of a few advanced

usages of URL routing

When you finish with this chapter, you should have a firm

grasp on the technology that makes URL routing work as

well as when you might (or might not) want to utilize it in

your own applications

Introduction to URL Routing

URL routing, in general terms, is a system that enables the

developer to build in dynamism, flexibility, and (hopefully)

readability to the URLs that access the various parts of a

web application

We’ve all seen URLs like the following:

http://www.myapplication.com/server/client/apps/app2/

userdata.aspx?mode=1&system=22

&user=abc8341290c3120c1&sessionid=

2312cxjsfk3xj123&action=3123x31pb

&jibberish=continuing&urlcomplexity=needless

And we all know how ugly they are Not only are they

difficult to cut and paste, but they’re also not very

memo-rable or not clean, and users never know whether they can

feel free to copy them, Digg them, share them on

Facebook, or whatever The reason for this is that, to an

Trang 5

CHAPTER 25 Using the ASP.NET URL Routing Engine

end user, a complicated-looking URL is an unusable or unsharable URL They assume that

there’s so much cruft jammed into the URL that it couldn’t possibly be portable URL

routing enables us to simplify those URLs, up to and including giving us the ability to

build RESTful style URLs and even hide the aspx extension entirely We no longer even

need a 1:1 mapping between the URL and physical page on disk

The first and foremost reason why URL routing should matter to you is that simple URLs

make for calm users The simpler your URL, the simpler people are going to assume your

site is to use Sure, this is often a bad assumption on the user’s part, but if you’re given an

opportunity to make your users feel more welcome, shouldn’t you take it?

Secondly, simple and easy URLs make for better Search Engine Optimization (SEO) An

ASPx page that serves up a different product page when the query string varies by a

productid parameter might look something like this:

http://my.store.com/product_detail.aspx?productid=12

This is certainly more user-friendly than the previous URL, but is it search-engine friendly?

Can a search engine crawler tell that more products are available on this same filename?

There are all kinds of tricks you can do, including publishing a page that produces a

master list of links to all products, but even those links aren’t the best links

What if each product detail page URL could include the short name of the product and

the category to which it belonged? In this case, the URL carries information that might

help make that URL more discoverable via search engines:

http://my.store.com/products/dvdplayers/toshiba/sd1600

This URL, although simple, has packed a truckload of information into it that can not

only be used by end users (they immediately know they’re looking at the URL for a

Toshiba DVD player, model number SD-1600) but also provides search engine crawlers

with a lot of context Both human and web crawler alike can assume that if they use the

/products/dvdplayers URL they will get all DVD players, and the

/products/dvdplayers/toshiba URL should provide all Toshiba DVD players

Finally, dynamically routing between URL and physical page gives you the flexibility to

use URL parameters to do things that might otherwise be cumbersome, difficult, or even

impossible without routing For example, take the following two URLs:

http://my.app.com/blog/2010/08/12

and

http://my.app.com/products/tags/discount/new/black

The first one enables you to supply a date directly on the URL, but you don’t need to

worry about figuring out what the query string parameter names are for the

compo-nents—just put the date in the URL with slashes This reduces a lot of complexity for the

underlying blog page and for end users

Trang 6

Basic URL Routing Scenarios

The second URL enables you to supply an infinite list of tags directly on the URL This

enables power users to start adding tag after tag to the end of a URL to further limit their

list of products—functionality available to users without the developer even having to

provide a GUI for it

Basic URL Routing Scenarios

Now that you’ve had an introduction to what URL routing is and why you might want to

use it, let’s take a look at some of the basics of how to use URL routing in your Web Forms

application The ASP.NET MVC Framework also makes use of the URL routing engine, but

it does so in a slightly different way The MVC Framework uses the routing engine to map

routes to controllers and actions with parameters whereas ASP.NET Web Forms

applica-tions use the routing engine to map routes to physical files on disk and supply parameters

to those pages

Mapping Basic URLs

The first thing that needs to be done to use the URL routing engine is to register your

route maps A route map is just a mapping from a route expression to a physical file on disk

(or a controller/action combination in the case of ASP.NET MVC Framework)

These routes are registered at application startup time and the registration is typically

wrapped in its own method, as shown in the following code snippet taken from a

Global.asax.cs file:

void Application_Start(object sender, EventArgs e)

{

// Code that runs on application startup

InitializeRoutes(RouteTable.Routes);

}

private void InitializeRoutes(RouteCollection routes)

{

// perform route registration

routes.MapPageRoute( );

}

The simplest and most basic type of route is one in which you map a static route directly

to an ASPx page without any parameters You typically see this when the target page takes

no parameters and has fairly simple functionality such as a login, logout, or about page

The following code shows how to use the MapPageRoute method of the RouteCollection

class to add basic route mappings:

routes.MapPageRoute(““, “about”, “~/About.aspx”); // anonymous route

routes.MapPageRoute(“login”, “login”, “~/Login.aspx”); // named route (login)

routes.MapPageRoute(““, “logout”, “~/Logoff.aspx”);

Trang 7

CHAPTER 25 Using the ASP.NET URL Routing Engine

The effect of these simple route mappings is that users can now use the URL

http://server/about, and they will be given the content from the About.aspx page The

URL in the browser appears as “/about” If that page were to post back to itself as many

ASP.NET Web Forms pages do, the post back would be sent to the “/about” URL, but the

About.aspx page would still be invoked

NOTE

No matter what you have in a route rule, if the URL requested by the user corresponds

to a physical file on disk, the routing rule will be ignored This means any constraints

and defaults defined by that rule will also be ignored As a matter of practice (and good

style), you should avoid writing route rules and contain the “.aspx” file extension to

avoid accidental conflicts between physical files and routes

Mapping URLs with Parameters

Static route mappings come in handy, but any application that has any kind of dynamic

nature or is driven by an underlying data source is, at some point, going to need

parame-ters passed on the query string Mapping parameparame-ters within a route expression and

making those parameters available to the target page is actually quite simple Thankfully

we don’t (yet) need to worry about regular expressions!

Let’s assume that you’re creating a web application that has blogging functionality Rather

than force users to create (or look at) some horribly complicated URL syntax that might

even include the GUID of the blog post, you can use URL routing to simplify that URL

syntax

NOTE

You may be thinking that no one would ever throw the GUID of a blog post entry in the

blog URL, but we have actually seen it multiple times Never underestimate the

capabil-ity of the Internet to breed bad user experience, and take every opportuncapabil-ity you can to

rid the Internet of such!

A common convention used by many blogging platforms is to embed a date directly in

the URL, enabling end users, GUIs, and crawlers to easily select the content they want To

do this, we need to direct traffic to URLs like this:

http://my.app.com/blog/2010/05/12

to our blog rendering page (Blog.aspx) We’ve seen how to send static (never changing)

URLs to individual ASPx pages, but how do we send dynamic URLs to those pages?

To do this without the routing engine, we’d have to create a low-level HttpHandler to

inspect the URLs, parse them, convert them into query string parameters, and then finally

load up the appropriate page Thankfully it’s much easier to just use the following code in

Trang 8

Basic URL Routing Scenarios

// URL pattern: blog/2010/05/12 routes to blog.aspx

routes.MapPageRoute(“blog”, “blog/{year}/{month}/{day}”, “~/Blog.aspx”);

The words inside the curly braces are now named parameters within the routing engine

and, when captured, will be made available to the Blog.aspx page At this point you

might be tempted to try and access these parameters as part of the Request.QueryString

object Don’t! Parameters passed through the URL routing engine are made available

inside the Page.RouteData property and not as part of the query string, as shown in the

following code:

protected void Page_Load(object sender, EventArgs e)

{

string year = RouteData.Values[“year”] as string;

string month = RouteData.Values[“month”] as string;

string day = RouteData.Values[“day”] as string;

// Perform blog processing based on date parameter

}

As you see as you progress through the chapter, this is just the beginning of what can be

done with route expressions

NOTE

Parameters captured by the routing engine that show up in the RouteData dictionary

are always stored as strings when used with ASP.NET Web Forms, even if you have

con-strained their data types via regular expressions (shown later in the chapter) As a

result, it is up to you to convert them to their final destination types after getting them

from the RouteData dictionary ASP.NET MVC does a little extra work on your behalf to

convert parameters into the data types the controllers expect

Mapping URLs with Multiple Segments

The technique in the preceding section is great if you know ahead of time exactly which

parameters are going to be in the URL and how many of them there are going to be But

what do you do if you don’t know how many parameters you’re going to have, or you

want people to pass a list of data on the URL without using cumbersome query string

syntax?

For example, let’s say that you have an application that exposes data that can have a

deeply nested hierarchy and you want users to drill into that hierarchy directly from the

URL Thankfully, the URL routing engine gives us the ability to map a list of parameters

An example of such a URL might enable the user to drill down to a location

geographi-cally, such as

http://my.app.com/location/Earth/USA/NY/NYC/TimesSquare

Trang 9

CHAPTER 25 Using the ASP.NET URL Routing Engine

or as we’ll see in the next code sample, we can supply a list of tags to filter data in a flat

hierarchy:

http://my.app.com/tags/free/ammo/guns

(should return everything tagged with free, ammo, and guns, though we might be a little

scared to see those results)

Multiple parameters can be supplied to a mapping by putting an asterisk in front of the

named parameter:

// URL pattern with variable segments

routes.MapPageRoute(“products-by-tag”,

“products/tags/{*tagnames}”,

“~/ProductsByTag.aspx”);

And then in the ProductsByTag.aspx.cs we can obtain the list of values passed on the

URL as a slash-delimited list:

string tagNames = RouteData.Values[“tagnames”] as string;

string[] tagList = tagNames.Split(‘/’);

Response.Write(string.Format(

“You wanted products that have the following tags: {0}”,

string.Join(“ : “, tagList)));

Linking to Other Pages with Routes

So far we’ve looked at a bunch of ways we can get a user from a URL to a page, but what

about going the other way? When the user is on an ASP.NET Web Form, how do we create

links to other pages in a way that respects the URL routing scheme without giving each

page “magic” knowledge of how the URLs are formatted?

Basically what we want is to keep all the URL routing logic inside the single initialization

method at application startup We never want individual Web Forms to be creating links

with hard-coded strings or string concatenation because those pages would cease to work

properly if the URL route maps changed

Ideally, we want to create URLs dynamically by supplying parameters and, optionally, the

name of the route map We can do this either declaratively in the ASPx markup or we can

build the URL programmatically in the code behind

First, let’s take a look at how we can link to another page using the asp:HyperLink server

control tag:

<asp:HyperLink ID=”testLink” runat=”server”

NavigateUrl=

“<%$ RouteUrl:RouteName=products-by-tag,tagnames=new/discounted %>”>New and

DiscountedProducts

Trang 10

Advanced URL Routing

This markup relies on the RouteUrlExpressionBuilder class to perform the appropriate

route map lookup, apply the supplied parameters to the expression, and return a virtual

path that respects the route In the preceding code, the link returned will be for the

/prod-ucts/tags/new/discounted relative path We supplied the tagnames parameter directly; we

did not manually construct the URL fragments This insulates the Web Form from changes

to the URL mapping If one day we get tired of using “products/tags” and decide to

change the mapping to “products/list/bytags” as the prefix, we won’t have to change any

of this code—it will just work

If we want to generate a route-aware URL programmatically, we can do so using the

following code (the codeGeneratedLink object is just a hyperlink control):

RouteValueDictionary parameters = new RouteValueDictionary()

{

{ “tagnames”, “new/discounted” }

};

VirtualPathData vpd = RouteTable.Routes.GetVirtualPath(

null, “products-by-tag”, parameters);

codeGeneratedLink.NavigateUrl = vpd.VirtualPath;

NOTE

Although these techniques make working with the routing engine seamless, they also

have an added benefit: the removal of hard-coded URLs Hard-coded URLs are the bane

of many a website, and by the very act of adopting the use of URL routing in your

web-site, your team will be forced to work without hard-coded URLs A great functional test

would be to add a random word to all the route paths to see if your site continues to

function As we all know, every time you remove a magic string from your code, an

angel gets its wings

Advanced URL Routing

So far you’ve seen examples of how to use URL routing to deal with static routes, routes

with known parameters, and even routes with lists of parameters of unknown sizes In this

next section we examine several other advanced scenarios that truly show off the power

and flexibility of the ASP.NET URL routing system

Using Routes with Default Parameters

Another powerful feature of the URL routing system is the capability to supply some

meaningful defaults for route parameters For example, you might have a product category

page that displays products within that category If the user doesn’t specify a category, you

might want to pick a default one

Ngày đăng: 06/07/2014, 18:20