ASP.netMVC Cookie使用

http://stephenwalther.com/archive/2008/07/08/asp-net-mvc-tip-15-pass-browser-cookies-and-server-variables-as-action-parameters(转)

ASP.NET MVC Tip #15 – Pass Browser Cookies and Server Variables as Action Parameters

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.

Imagine that you make the following browser request against an ASP.NET MVC web application:

http://localhost/Product/Index

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.

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.

Imagine, for example, that the Details() controller action in Listing 1 is being invoked:

Listing 1 – ProductController.vb (VB.NET)

Public Class ProductController
    Inherits System.Web.Mvc.Controller

    Function Details(ByVal productId As Integer)
        Return View()
    End Function
End Class

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();
        }
    }
}

The Details() controller action has a single parameter named productId. The ControllerActionInvoker attempts to retrieve the value of this parameter from 3 places:

1. Explicit Extra Parameters Passed to InvokeAction()

2. Values from the Route Data

3. Request Values

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.

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.

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.

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).

Figure 1 – Can’t Match Parameters

image

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.vb (VB.NET)

Public Class HomeController
    Inherits System.Web.Mvc.Controller

    Public Function Index(ByVal HTTP_USER_AGENT As String, ByVal myCookie As String)
        ViewData("HTTP_USER_AGENT") = HTTP_USER_AGENT
        ViewData("myCookie") = myCookie
        Return View()
    End Function

    Public Function CreateCookie(ByVal cookieValue As String)
        Dim newCookie As New HttpCookie("myCookie", cookieValue)
        newCookie.Expires = DateTime.Now.AddDays(10)
        Response.AppendCookie(newCookie)
        Return RedirectToAction("Index")
    End Function



End Class

Listing 2 – HomeController.cs (C#)

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

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");
        }


    }
}

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

image

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.

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 @ 2015-03-24 11:19  ip8888  阅读(907)  评论(0编辑  收藏  举报