Mike

导航

ASP.NET MVC Tip #15 – 传递浏览器Cookies和服务器变量作为Action参数


ASP.NET MVC Tip #15 – 传递浏览器Cookies和服务器变量作为Action参数
ASP.NET MVC Tip #15 – Pass Browser Cookies and Server Variables as Action Parameters

美语原文:http://weblogs.asp.net/stephenwalther/archive/2008/07/08/asp-net-mvc-tip-15-pass-browser-cookies-and-server-variables-as-action-parameters.aspx

国语翻译:http://www.cnblogs.com/mike108mvp

译者注:这是我第一次翻译,翻译内容若有错误或者不妥之处,请大家批评指正。谢谢。


在这篇小贴士中,我将演示如何传递浏览器Cookies和HTTP服务器变量给控制器(controller)的Action方法,用传递表单(form)及查询字符串(query string)参数的相同的方法。
In this tip, I demonstrate how you can pass browser cookies and HTTP server variables to controller action methods in the same way as you can pass form and query string parameters.

假设你对一个ASP.NET MVC Web应用程序进行下面的浏览器请求:
Imagine that you make the following browser request against an ASP.NET MVC web application:

http://localhost/Product/Index

当你进行这个请求时,默认情况下,ASP.NET MVC框架将会调用一个ProductController类中的Index() action方法。ASP.NET MVC框架中有一个ControllerActionInvoker类,它负责调用控制器(controller)的action来对浏览器的请求作出反应。
When you make this request, by default, the ASP.NET MVC framework will invoke an action named Index() exposed by a class named ProductController. There is a class in the ASP.NET MVC framework, named the ControllerActionInvoker class, which is responsible for invoking a controller action in response to a browser request.

ControllerActionInvoker类拥有一些职责。这个类必须找到和被调用方法相匹配的方法。此外,ControllerActionInvoker还负责构建参数列表传递给被调用的方法。
The ControllerActionInvoker class has several responsibilities. This class must find a method that matches the method being invoked. Furthermore, the ControllerActionInvoker is responsible for building the list of parameters that are passed to the invoked method.

假设,例如,在代码清单1中Details() controller action被调用:
Imagine, for example, that the Details() controller action in Listing 1 is being invoked:

Listing 1 – ProductController.cs (C#)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Tip15.Controllers
{
    
public class ProductController : Controller
    
{
        
public ActionResult Details(int productId)
        
{
            
return View();
        }

    }

}

Details() controller action只有一个productId参数。ControllerActionInvoker尝试从三个地方取得这个参数的值。
The Details() controller action has a single parameter named productId. The ControllerActionInvoker attempts to retrieve the value of this parameter from 3 places:

1、传递给InvokeAction()的显式的额外参数
2、从Route数据中得到的值
3、请求的值
1. Explicit Extra Parameters Passed to InvokeAction()
2. Values from the Route Data
3. Request Values

首先,尝试从传递给ControllerActionInvoker.InvokeAction()方法的参数中获取productId参数的值。这个方法是被Controller.Execute()方法调用的。默认的controller不会传递任何额外的参数。如果你创建了你自己的controller,那么你就可以传递任何你喜欢的参数。
First, an attempt is made to retrieve the value of the productId parameter from the parameters passed to the ControllerActionInvoker.InvokeAction() method. This method is called by the Controller.Execute() method. The default controller does not pass any additional parameters. If you create your own controller, then you can pass any parameters that you please.

第二,尝试从route data中获取productId参数的值。route data可能包含一个productId的默认值。或者,你自己的route table可能将url地址的一部分与productId参数的值进行映射。默认的route table不会映射任何值给productId参数。
Second, an attempt is made to retrieve the value of the productId parameter from the route data. The route data might contain a default value for productId. Or, your route table might map a segment of a URL to the productId. The default route table does not map anything to the productId parameter.

最后,尝试从HttpRequest对象(HttpContext.Request)中获取productId参数的值。HttpRequest对象代表了查询字符串(Query String)、表单(Form)、Cookie以及服务器变量项目(按这个顺序)。这意味着将尝试从所有的这些来源中获取productId参数的值。
Finally, an attempt is made to retrieve the value of productId from the HttpRequest object (HttpContext.Request). The HttpRequest object represents Query String, Form, Cookie, and Server Variable items (in that order). This means that an attempt will be made to retrieve the value of productId from all of these sources.

如果ControllerActionInvoker不能从上面的三个地方获得一个参数的值,那么ControllerActionInvoker将会检测该参数值是否允许为空。如果一个参数允许为空,那么ActionInvoker将传递一个空值。否则ControllerActionInvoker将抛出一个非法操作异常(InvalidOperationException )。(见图1)
If the ControllerActionInvoker cannot retrieve the value of a parameter from these three places then the ControllerActionInvoker checks whether or not the parameter can be null. If a parameter can be null, then the ActionInvoker passes a null value. Otherwise, the ControllerActionInvoker throws an InvalidOperationException (see Figure 1).

图1-无法匹配参数
Figure 1 – Can’t Match Parameters



直到我审查ControllerActionInvoker类,我才知道controller action方法的参数能够从浏览器cookies和HTTP服务器变量中获得。在代码清单2中,让我们看看HomeController类中的Index() action方法。
Until I investigated the ControllerActionInvoker class, I did not realize that controller action parameters could be retrieved from browser cookies and HTTP server variables. Consider the Index() action exposed by the HomeController in Listing 2.

Listing 2 – HomeController.cs (C#)

namespace Tip15.Controllers
{
    
public class HomeController : Controller
    
{
        
public ActionResult Index(string HTTP_USER_AGENT, string myCookie)
        
{
            ViewData[
"HTTP_USER_AGENT"= HTTP_USER_AGENT;
            ViewData[
"myCookie"= myCookie; 
            
return View();
        }


        
public ActionResult CreateCookie(string cookieValue)
        
{
            var newCookie 
= new HttpCookie("myCookie", cookieValue);
            newCookie.Expires 
= DateTime.Now.AddDays(10);
            Response.AppendCookie(newCookie);
            
return RedirectToAction("Index");
        }

    }

}


 

Index()方法接收两个参数:HTTP_USER_AGENT和myCookie。因为HTTP_USER_AGENT参数与一个服务器变量是一致的,所以它能够自动获得一个值。因为myCookie与浏览器cookie是一致的,所以它拥有一个值(如果cookie已经被设置)。当Index()方法被调用时,你可以看到图2的视图。
The Index() method accepts two parameters named HTTP_USER_AGENT and myCookie. Because the parameter name HTTP_USER_AGENT corresponds to a server variable, this parameter gets a value automatically. Because myCookie corresponds to a browser cookie, this parameter also has a value (if the cookie is set). When the Index() method is invoked, you get the view in Figure 2.

Figure 2 – The Index View

事实上,你能够传递服务器变量和cookies给controller,在各种各样不同的场景中是非常有用的。例如,你可能想在浏览器请求时,根据当前使用的浏览器类型返回不同的内容。你能够利用HTTP_USER_AGENT服务器变量在你自己的action方法中浏览器的类型并返回不同的内容,或者你可以根据浏览器的语言设置来返回不同语言版本的内容。
The fact that you can pass server variables and cookies to controller actions can be useful in a variety of different scenarios. For example, you might want to return different content depending on the type of browser being used to make the request. You can take advantage of the HTTP_USER_AGENT server variable in your action method to detect the type of browser and return different content. Or, you might want to return messages in different spoken languages depending on the user's browser language settings.

传递cookie参数也是很有用的。你能够在cookie中存储一个用户的个性化偏好,并且从action方法中取出这些数据。例如,你能够将一个用户的昵称存在浏览器cookie中,并且在每一个controller的action方法中自动取出用户的昵称。
Passing cookie parameters also can be useful. You could store a user’s preferences in a cookie and retrieve those preferences in an action method automatically. For example, you could store a user’s nick name in a browser cookie and retrieve that nick name in every controller action automatically.

下载演示代码
Download the Code

posted on 2008-07-16 14:15  mike108mvp  阅读(2909)  评论(8编辑  收藏  举报