ASP.NET Tutorial: REQUEST and RESPONSE (and cookies for Santa)


Okay, so this does not really have anything to do with Santa, but I wanted to be clever (and it is nearly Christmas). This entry stems off a conversation on one of the forums about whether the user should access Response.Cookies or Request.Cookies. In order to understand this better, we need to back up a bit and take a look at how the web works. From this basic understanding of REQUEST and RESPONSE, we can better understand how cookies work.

Web Site Mechanics (REQUEST and RESPONSE)

Unlike many other application types, the web is stateless. What this means is the server forgets everything about the client the moment it responds to a request. Before getting deeper into that, let’s take a look at the basic Request/Response mechanism. Here is the basic flow

  1. User types in a URL or clicks a link
  2. User’s browser asks for DNS information about the requested item (IP address)
  3. User’s browser creates a request. It will have the following
    1. Routing and Rendering information
      1. Where request is going (IP address of requested information) – URI or URL
      2. Where to respond to the request (user’s IP address)
      3. Browser information useful for rendering
    2. Verb – generally GET or POST (see next section)
    3. Query String Collection (optional – but part of URL)
    4. Form Collection (anything filled in on a page – also optional)
    5. Cookies found for this site – can be server cookies or client cookies
  4. Server receives request and breaks the request down
    1. Form collection
    2. Query String collection
    3. Cookie collection –  useful for state (esp. server cookie, which holds session token)
    4. Requested page information
    5. Browser information
  5. Server processes the information based on developer’s code
  6. Server responds back to the user’s browser
    1. Routing information
      1. Server IP
      2. User’s IP
      3. Server information
    2. Cookie collection (server and possibly client)
    3. Item(s) to render in the browser
  7. Browser receives response and processes it, showing the user the requested content

This is a basic “success” flow, as the server can send a number of error codes. Graphically, it looks like this:

Request_Response

From this we should learn:

  • REQUEST is something sent from the client
  • RESPONSE is something returned from the server

This is basic client server mechanics.

GET and PUT

There are two verbs you need to know to complete knowledge of how the web works, as there are two ways a REQUEST can be made. the create pretty much the same REQUEST package, but the verb GET or PUT is added to the Request. Here is general description of GET and PUT.

  • GET – REQUEST made by typing in an URI or clicking a link
    • Cookies Collection – optional
    • QueryString Collection – optional
    • Form Collection – Can be done, but default is no
  • POST – REQUEST made by clicking a control on a form
    • Cookies Collection – optional
    • QueryString Collection – optional
    • Form Collection – mandatory (will at least have the control that caused the PUT)

You say the web is stateless? I don’t believe you.

This is the first objection people have when I state “the web is stateless”. The answer is “of course it has state. I can log into a site and it remembers me.”

Actually, it doesn’t, or at least not with the basic mechanics. When the web was first invented by Al Gore (cheap shot), all we had was HTML. You typed in http://www.mysite.com/index.html and you got a page back. The only clue that you had visited was a log on the server. If you asked for the page again, the server did not say “hey, Greg, glad you are back.  I see you were viewing X.”

To solve the stateless nature a new mechanism was created, the cookie. Since the method is REQUEST>>RESPONSE, the cookie had to be sent as part of the RESPONSE package. The cookie would contain enough information so the server could know who the user was.

Over time, people got tired of cookies and turned them off, prompting two types of cookies in use today:

  1. Server cookie – a cookie that has a very limited scope that is used by the server to identify a session (state cookie, if you will)
  2. Client cookie (user cookie) – Additional information the site wants to track

The client cookie can be used to make it easier to log in (keep me logged in), to store preferences, or any number of good uses. It can also be used to track users across many sites. Today, some people turn off client cookies. You have to remember that if you are using a cookie based methodology. Even server cookies can technically be turned off, but they are not generally. If you have older browsers hitting your site, they do not distinguish between server and client cookies, so you may find sessions do not work with these clients.

The Question On Cookies

Here is the question that spurred this post:

I’m having a problem that stems from not be able to determin if I should use
Request.Cookies or Response.cookies.

I need to change a cookie in the code then later check it and also want it
to persist on the client.

So it seems to me that I should be using Response.cookie.add(mm)

and later to check use Response.cookie(mm)

But before I add I should remove the old cookie so the the Response.cookie()
will return the new value. Is that corrrect?

This will cause the cookie to be sent to the client for recording?

Do I ever need to check the Request.cookie collection?

Can I add to it or is it readonly?

When are the values copied from the Request to the Response?

Answers to these questions will help a lot.

We can answer most of the questions here. Request.Cookies come from the client request. This means Request.Cookies are a means by which a server can read a cookie returned from the client. If we look at the Request mechanism, there are a few different places I can get information from.:

  • Query String: http://mysite.com/a.aspx?id=1
    ‘ID == 1
    var id = Request.QueryString["id"];
  • Form Collection: assume form has a textbox called TextBox1, filled in with “Greg”
    ‘tb == "Greg"
    var tb = Request.Form["TextBox1"];
  • Cookies Colllection: Assume we have a cookie called "UserCookie" with a key called “UserName” set to the value “Joe”
    ‘cook1 == "Another"
    var cook1 = Request.Cookies["UserCookie"]["UserName"];

We will stick to cookies now. If the user corrects his name and states it is Joseph, I merely overwrite the cookie sent back to the user:

Response.Cookies["UserCookie"]["UserName"] = "Joseph";

What is happening here? Let’s run through a few trips to the server. NOTE: This is a oversimplified on purpose.

  1. Trip 1
    1. User fills in form with name “Joe”
    2. User hits the submit button
    3. User’s browser makes a REQUEST
      1. Routing information
      2. Browser information
    4. Server gets REQUEST
    5. Server breaks down REQUEST
      1. No cookies
      2. Form collection
      3. No Query String arguments
    6. Server pulls user name “Joe” from form collection
    7. Server creates a cookie using Response.Cookies to “save” the name “Joe” on the client side
    8. Server creates RESPONSE with name “Joe”
    9. Server sends RESPONSE
      1. Routing Information
      2. HTML for page (includes name Joe)
      3. Cookie with “Joe”
    10. Browser renders page
    11. Browser saves cookie with name Joe
  2. Trip 2
    1. User notices name “Joe” and decides it is wrong
    2. User clicks to return to the form
    3. User’s browser makes a REQUEST
      1. Routing information
      2. Browser information
      3. Cookie with name “Joe”
    4. Server breaks down REQUEST
      1. Cookie with name “Joe”
      2. No Form collection
      3. No Query String arguments
    5. Server creates RESPONSE using name “Joe”
    6. Server sends RESPONSE
      1. Routing Information
      2. HTML for page (includes name Joe)
    7. Browser renders page
    8. Browser has NO cookie to save this time, so it leaves the old cookie
  3. Trip 3
    1. User fills in form with name “Joseph”
    2. User hits the submit button
    3. User’s browser makes a REQUEST
      1. Routing information
      2. Browser information
    4. Server gets REQUEST
    5. Server breaks down REQUEST
      1. Cookie with name ”Joe”
      2. Form collection
      3. No Query String arguments
    6. Server pulls user name “Joseph” from form collection
    7. Server creates a cookie using Response.Cookies to “save” the name “Joseph” on the client side
    8. Server creates RESPONSE with name “Joseph”
    9. Server sends RESPONSE
      1. Routing Information
      2. HTML for page (includes name Joe)
      3. Cookie with “Joseph”
    10. Browser renders page
    11. Browser sees a new cookie with the name “Joseph” and overwrites the cookie with the name :”Joe”

What we see is the following:

  • Client browser saves cookies, unless it is set to ignore them
  • Client browser will overwrite cookies with the same cookie name if new information is sent

Now back to the user’s questions:

I’m having a problem that stems from not be able to determin if I should use
Request.Cookies or Response.cookies.

Reponse.Cookies >> to the client
Request.Cookies >> from the client

REQUEST is the client asking for something, REPONSE is what you are sending back in “response” to the “request”.

I need to change a cookie in the code then later check it and also want it
to persist on the client.

As long as the client has cookies turned on (ie, allows cookies), it will write the cookie.

So it seems to me that I should be using Response.cookie.add(mm)

To write a cookie on the client side, this is correct.

and later to check use Response.cookie(mm)

This is the point of disconnect. You can read Response.Cookies at the point when you are writing, but once it has been sent to the client, you need to use Request.Cookies.

But before I add I should remove the old cookie so the the Response.cookie()
will return the new value. Is that corrrect?

If you Response.Cookies["CookieName"] to a client and the cookie is already there, it will be overwritten.

This will cause the cookie to be sent to the client for recording?

Do I ever need to check the Request.cookie collection?

When you are reading a Request from the client.

Can I add to it or is it readonly?

Request.Cookies may be able to be written to, but it gets destroyed once you are done processing the Request, so the changes are NEVER saved to the client unless you use Reponse.Cookies.

When are the values copied from the Request to the Response?

Never. You have to do this yourself.

Final Notes

I will have to expand this at some time to relate this information to the Request model used by ASP.NET and how the different event handlers are fired. As it stands now, you should remember the following:

  • A REQUEST comes from the client to a server
  • A REPONSE is sent from a server to a client in “response” to a “request”
  • Cookies are additional information sent that you wish to store on the client side
  • To read a cookie from a client, you use Request.Cookies
  • To send a cookie to a client, you use Response.Cookies
  • Cookies sent to the client with a name already used on the client will overwrite the old cookie(s)

Hope this helps y’all.

Peace and Grace,
Greg

Twitter: @gbworld

Advertisements

One Response to ASP.NET Tutorial: REQUEST and RESPONSE (and cookies for Santa)

  1. Pingback: Sharing Sessions in ASP.NET | Stop Making Sense

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: