Siêu thị PDFTải ngay đi em, trời tối mất

Thư viện tri thức trực tuyến

Kho tài liệu với 50,000+ tài liệu học thuật

© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

Pro ASP.NET MVC Framework phần 6 pps
PREMIUM
Số trang
63
Kích thước
16.4 MB
Định dạng
PDF
Lượt xem
722

Pro ASP.NET MVC Framework phần 6 pps

Nội dung xem thử

Mô tả chi tiết

public class PermanentRedirectToRouteResult : ActionResult

{

public RedirectToRouteResult Redirection { get; private set; }

public PermanentRedirectToRouteResult(RedirectToRouteResult redirection)

{

this.Redirection = redirection;

}

public override void ExecuteResult(ControllerContext context)

{

// After setting up a normal redirection, switch it to a 301

Redirection.ExecuteResult(context);

context.HttpContext.Response.StatusCode = 301;

}

}

}

Whenever you’ve imported this class’s namespace, you can simply add

.AsMovedPermanently() to the end of any redirection:

public ActionResult MyActionMethod()

{

return RedirectToAction("AnotherAction").AsMovedPermanently();

}

Search Engine Optimization

You’ve just considered URL design in terms of maximizing usability and compliance with

HTTP conventions. Let’s now consider specifically how URL design is likely to affect search

engine rankings.

Here are some techniques that can improve your chances of being ranked highly:

• Use relevant keywords in your URLs: /products/dvd/simpsons will score more points

than /products/293484.

• As discussed, minimize your use of query string parameters and don’t use underscores

as word separators. Both can have adverse effects on search engine placement.

• Give each piece of content one single URL: its canonical URL. Google rankings are

largely determined by the number of inbound links reaching a single index entry, so

if you allow the same content to be indexed under multiple URLs, you risk spreading

out the “weight” of incoming links between them. It’s far better to have a single high￾ranking index entry than several low-ranking ones.

If you need to display the same content on multiple URLs (e.g., to avoid breaking old

links), then redirect visitors from the old URLs to the current canonical URL via an

HTTP 301 (moved permanently) redirect.

• Obviously, your content has to be addressable, otherwise it can’t be indexed at all. That

means it must be reachable via a GET request, not depending on a POST request or any

sort of JavaScript-, Flash-, or Silverlight-powered navigation.

CHAPTER 8 ■ URLS AND ROUTING 257

10078ch08.qxd 3/16/09 12:40 PM Page 257

SEO is a dark and mysterious art, because Google (and the other search engines, as if any￾one cares about them) will never reveal the inner details of their ranking algorithms. URL

design is only part of it—link placement and getting inbound links from other popular sites is

more critical. Focus on making your URLs work well for humans, and those URLs will tend to

do well with search engines, too.

Summary

You’ve now had a close look at the routing system—how to use it, and how it works internally.

This means you can now implement almost any URL schema, producing human-friendly

and search engine–optimized URLs, without having to hard-code a URL anywhere in your

application.

In the next chapter, you’ll explore the heart of the MVC Framework itself, gaining

advanced knowledge of controllers and actions.

258 CHAPTER 8 ■ URLS AND ROUTING

10078ch08.qxd 3/16/09 12:40 PM Page 258

Controllers and Actions

Each time a request comes in to your ASP.NET MVC application, it’s dealt with by a con￾troller. The controller is the boss: it can do anything it likes to service that request. It can issue

any set of commands to the underlying model tier or database, and it can choose to render

any view template back to the visitor. It’s a C# class into which you can add any logic needed

to handle the request.

In this chapter, you’ll learn in detail how this centerpiece of the MVC Framework oper￾ates, and what facilities it offers. We’ll start with a quick discussion of the relevant architectural

principles, and then look at your options for receiving input, producing output, and injecting

extra logic. Next, you’ll see how as an advanced user you can customize the mechanisms for

locating and instantiating controllers and invoking their action methods. Finally, you’ll see

how all of this design fits neatly with unit testing.

An Overview

Let’s recap exactly what role controllers play in MVC architecture. MVC is all about keeping

things simple and organized via separation of concerns. In particular, MVC aims to keep sepa￾rate three main areas of responsibility:

• Business or domain logic and data storage (model)

• Application logic (controller)

• Presentation logic (view)

This particular arrangement is chosen because it works very well for the kind of business

applications that most of us are building today.

Controllers are responsible for application logic, which includes receiving user input,

issuing commands to and retrieving data from the domain model, and moving the user

around between different UIs. You can think of controllers as a bridge between the Web and

your domain model, since the whole purpose of your application is to let end users interact

with your domain model.

Domain model logic—the processes and rules that represent your business—is a separate

concern, so don’t mix model logic into your controllers. If you do, you’ll lose track of which

code is supposed to model the true reality of your business, and which is just the design of the

259

CHAPTER 9

10078ch09.qxd 3/26/09 12:11 PM Page 259

web application feature you’re building today. You might get away with that in a small applica￾tion, but to scale up in complexity, separation of concerns is the key.

Comparisons with ASP.NET WebForms

There are some similarities between ASP.NET MVC’s controllers and the ASPX pages in tradi￾tional WebForms. For example, both are the point of interaction with the end user, and both

hold application logic. In other ways, they are conceptually quite different—for example,

You can’t separate a WebForms ASPX page from its code-behind class—the two only work

together, cooperating to implement both application logic and presentation logic (e.g.,

when data-binding), both being concerned with every single button and label. ASP.NET

MVC controllers, however, are cleanly separated from any particular UI (i.e., view)—they

are abstract representations of a set of user interactions, purely holding application logic.

This abstraction helps you to keep controller code simple, so your application logic stays

easier to understand and test in isolation.

WebForms ASPX pages (and their code-behind classes) have a one-to-one association

with a particular UI screen. In ASP.NET MVC, a controller isn’t tied to a particular view,

so it can deal with a request by returning any one of several different UIs—whatever is

required by your application logic.

Of course, the real test of the MVC Framework is how well it actually helps you to get your

job done and build great software. Let’s now explore the technical details, considering exactly

how controllers are implemented and what you can do with one.

All Controllers Implement IController

In ASP.NET MVC, controllers are .NET classes. The only requirement on them is that they must

implement the IController interface. It’s not much to ask—here’s the full interface definition:

public interface IController

{

void Execute(RequestContext requestContext);

}

The “hello world” controller example is therefore

public class HelloWorldController : IController

{

public void Execute(RequestContext requestContext)

{

requestContext.HttpContext.Response.Write("Hello, world!");

}

}

If your routing configuration includes the default Route entry (i.e., the one matching

{controller}/{action}/{id}), then you can invoke this controller by starting up your applica￾tion (press F5) and then visiting /HelloWorld, as shown in Figure 9-1.

260 CHAPTER 9 ■ CONTROLLERS AND ACTIONS

10078ch09.qxd 3/26/09 12:11 PM Page 260

Figure 9-1. Output from HelloWorldController

Hardly impressive, but of course you could put any application logic into that Execute()

method.

The Controller Base Class

In practice, you’ll very rarely implement IController directly, or write an Execute() method.

That’s because the MVC Framework comes with a standard base class for controllers,

System.Web.Mvc.Controller (which implements IController on your behalf). This is much

more powerful than a bare-metal IController—it introduces the following facilities:

Action methods: Your controller’s behavior is partitioned into multiple methods (instead

of having just one single Execute() method). Each action method is exposed on a differ￾ent URL, and is invoked with parameters extracted from the incoming request.

Action results: You have the option to return an object describing the intended result of an

action (e.g., rendering a view, or redirecting to a different URL or action method), which is

then carried out on your behalf. The separation between specifying results and executing

them simplifies automated testing considerably.

Filters: You can encapsulate reusable behaviors (e.g., authentication or output caching) as

filters, and then tag each behavior onto one or more controllers or action methods by

putting an [Attribute] in your source code.

This chapter covers all of these features in more detail. Of course, you’ve already seen and

worked with many controllers and action methods in earlier chapters, but to illustrate the pre￾ceding points, consider this:

[OutputCache(Duration=600, VaryByParam="*")]

public class DemoController : Controller

{

public ViewResult ShowGreeting()

{

ViewData["Greeting"] = "Hello, world!";

return View("MyView");

}

}

CHAPTER 9 ■ CONTROLLERS AND ACTIONS 261

10078ch09.qxd 3/26/09 12:11 PM Page 261

This simple controller class, DemoController, makes use of all three features mentioned

previously.

Since it’s derived from the standard Controller base class, all its public methods are

action methods, so they can be invoked from the Web. The URL for each action method is

determined by your routing configuration. With the default routing configuration, you

can invoke ShowGreeting() by requesting /Demo/ShowGreeting.

ShowGreeting() generates and returns an action result object by calling View(). This par￾ticular ViewResult object instructs the framework to render the view template stored at

/Views/Demo/MyView.aspx, supplying it with values from the ViewData collection. The view

will merge those values into its template, producing and delivering a finished page of HTML.

It has a filter attribute, [OutputCache]. This caches and reuses the controller’s output

for a specified duration (in this example, 600 seconds, or 10 minutes). Since the attribute

is attached to the DemoController class itself, it applies to all action methods on

DemoController. Alternatively, you can attach filters to individual action methods, as

you’ll learn later in the chapter.

■Note When you create a controller class by right-clicking your project name or the /Controllers

folder and choosing Add ➤ Controller, Visual Studio creates a class that inherits from the System.Web.

Mvc.Controller base class. If you prefer, you can just manually create a class and make it inherit from

System.Web.Mvc.Controller.

As with so many programming technologies, controller code tends to follow a basic pattern

of input ➤ process ➤ output. The next part of this chapter examines your options for receiving

input data, processing and managing state, and sending output back to the web browser.

Receiving Input

Controllers frequently need to access incoming data, such as query string values, form values,

and parameters parsed from the incoming URL by the routing system. There are three main

ways to access that data. You can extract it from a set of context objects, or you can have the

data passed as parameters to your action method, or you can directly invoke the framework’s

model binding feature. We’ll now consider each of these techniques.

Getting Data from Context Objects

The most direct way to get hold of incoming data is to fetch it yourself. When your controllers are

derived from the framework’s Controller base class, you can use its properties, including Request,

Response, RouteData, HttpContext, and Server, to access GET and POST values, HTTP headers,

cookie information, and basically everything else that the framework knows about the request.1

1. All these properties are merely shortcuts into the ControllerContext property. For example, Request is

equivalent to ControllerContext.HttpContext.Request.

262 CHAPTER 9 ■ CONTROLLERS AND ACTIONS

10078ch09.qxd 3/26/09 12:11 PM Page 262

Tải ngay đi em, còn do dự, trời tối mất!