开发者

Mapping Header cookie string to CookieCollection and vice versa

Consider a web response with this header:

Set-Cookie: sample=testCookie; Domain=.sample.com; Expires=Tue, 25-Jan-2012 00:49:29 GMT; Path=/

this header would be mapped to CookieCollection in .NET. And also when we deal with a CookieCollection it will finally converted to such a header string.

I'm looking some way to purely do this conversions in two way. Surely .NET has it in it's internal library. I believe any class which constructs object model from text and vice versa should support two methods (here CookieCollection):

// Creating cookie collection from header text
CookieCollection.TryParse(cookieHeaderString, out myCookieCollection);
// and getting the final header which would be sent by request
String cookieHeaderString = myCookieCollection.GetCookieHeaderString();

How can I achieve that with Coo开发者_开发问答kieCollection ?


I know that this has already been answered, but you might like to use this code: http://snipplr.com/view/4427/

I'm posting it here in case the link goes down at some point:

public static CookieCollection GetAllCookiesFromHeader(string strHeader, string strHost)
{
    ArrayList al = new ArrayList();
    CookieCollection cc = new CookieCollection();
    if (strHeader != string.Empty)
    {
        al = ConvertCookieHeaderToArrayList(strHeader);
        cc = ConvertCookieArraysToCookieCollection(al, strHost);
    }
    return cc;
}


private static ArrayList ConvertCookieHeaderToArrayList(string strCookHeader)
{
    strCookHeader = strCookHeader.Replace("\r", "");
    strCookHeader = strCookHeader.Replace("\n", "");
    string[] strCookTemp = strCookHeader.Split(',');
    ArrayList al = new ArrayList();
    int i = 0;
    int n = strCookTemp.Length;
    while (i < n)
    {
        if (strCookTemp[i].IndexOf("expires=", StringComparison.OrdinalIgnoreCase) > 0)
        {
            al.Add(strCookTemp[i] + "," + strCookTemp[i + 1]);
            i = i + 1;
        }
        else
        {
            al.Add(strCookTemp[i]);
        }
        i = i + 1;
    }
    return al;
}


private static CookieCollection ConvertCookieArraysToCookieCollection(ArrayList al, string strHost)
{
    CookieCollection cc = new CookieCollection();

    int alcount = al.Count;
    string strEachCook;
    string[] strEachCookParts;
    for (int i = 0; i < alcount; i++)
    {
        strEachCook = al[i].ToString();
        strEachCookParts = strEachCook.Split(';');
        int intEachCookPartsCount = strEachCookParts.Length;
        string strCNameAndCValue = string.Empty;
        string strPNameAndPValue = string.Empty;
        string strDNameAndDValue = string.Empty;
        string[] NameValuePairTemp;
        Cookie cookTemp = new Cookie();

        for (int j = 0; j < intEachCookPartsCount; j++)
        {
            if (j == 0)
            {
                strCNameAndCValue = strEachCookParts[j];
                if (strCNameAndCValue != string.Empty)
                {
                    int firstEqual = strCNameAndCValue.IndexOf("=");
                    string firstName = strCNameAndCValue.Substring(0, firstEqual);
                    string allValue = strCNameAndCValue.Substring(firstEqual + 1, strCNameAndCValue.Length - (firstEqual + 1));
                    cookTemp.Name = firstName;
                    cookTemp.Value = allValue;
                }
                continue;
            }
            if (strEachCookParts[j].IndexOf("path", StringComparison.OrdinalIgnoreCase) >= 0)
            {
                strPNameAndPValue = strEachCookParts[j];
                if (strPNameAndPValue != string.Empty)
                {
                    NameValuePairTemp = strPNameAndPValue.Split('=');
                    if (NameValuePairTemp[1] != string.Empty)
                    {
                        cookTemp.Path = NameValuePairTemp[1];
                    }
                    else
                    {
                        cookTemp.Path = "/";
                    }
                }
                continue;
            }

            if (strEachCookParts[j].IndexOf("domain", StringComparison.OrdinalIgnoreCase) >= 0)
            {
                strDNameAndDValue = strEachCookParts[j];
                if (strDNameAndDValue != string.Empty)
                {
                    NameValuePairTemp = strDNameAndDValue.Split('=');

                    if (NameValuePairTemp[1] != string.Empty)
                    {
                        cookTemp.Domain = NameValuePairTemp[1];
                    }
                    else
                    {
                        cookTemp.Domain = strHost;
                    }
                }
                continue;
            }
        }

        if (cookTemp.Path == string.Empty)
        {
            cookTemp.Path = "/";
        }
        if (cookTemp.Domain == string.Empty)
        {
            cookTemp.Domain = strHost;
        }
        cc.Add(cookTemp);
    }
    return cc;
}

This code will read in cookies that are comma separated and correctly parse all parts of each cookie including name, expiration, path, value, and domain.


I think you are looking for CookieContainer. See SetCookies method.


Here is my extension class I use to do this.

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Net;
using System.Text.RegularExpressions;
using System.Web;

namespace YourProjectName.Extensions
{
     public static class HttpCookieExtension
    {
         static Regex rxCookieParts = new Regex(@"(?<name>.*?)\=(?<value>.*?)\;|(?<name>\bsecure\b|\bhttponly\b)", RegexOptions.Compiled |RegexOptions.Singleline|RegexOptions.IgnoreCase);
         static Regex rxRemoveCommaFromDate = new Regex(@"\bexpires\b\=.*?(\;|$)", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline);
         public static bool GetHttpCookies(this NameValueCollection collection, int index , out List<HttpCookie> cookies)
         {
             cookies = new List<HttpCookie>();

             if (collection.AllKeys[index].ToLower() != "set-cookie") return false;
             try
             {

                 string rawcookieString = rxRemoveCommaFromDate.Replace(collection[index],  new MatchEvaluator(RemoveComma));

                 string[] rawCookies = rawcookieString.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

                 foreach (var rawCookie in rawCookies)
                 {
                    cookies.Add(rawCookie.ToHttpCookie());
                 }
                 return true;
             }
             catch (Exception)
             {

                 return false;
             }
         }


         public static bool GetHttpCookiesFromHeader(this string cookieHeader, out CookieCollection cookies)
         {
             cookies = new CookieCollection();


             try
             {

                 string rawcookieString = rxRemoveCommaFromDate.Replace(cookieHeader, new MatchEvaluator(RemoveComma));

                 string[] rawCookies = rawcookieString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

                 if (rawCookies.Length == 0)
                 {
                     cookies.Add(rawcookieString.ToCookie());
                 }
                 else
                 {
                    foreach (var rawCookie in rawCookies)
                    {
                        cookies.Add(rawCookie.ToCookie());
                    }
                 }

                 return true;
             }
             catch (Exception)
             {
                 throw;
             }
         }




         public static Cookie ToCookie(this string rawCookie)
         {

             if (!rawCookie.EndsWith(";")) rawCookie += ";";

             MatchCollection maches = rxCookieParts.Matches(rawCookie);

             Cookie cookie = new Cookie(maches[0].Groups["name"].Value.Trim(), maches[0].Groups["value"].Value.Trim());

             for (int i = 1; i < maches.Count; i++)
             {
                 switch (maches[i].Groups["name"].Value.ToLower().Trim())
                 {
                     case "domain":
                         cookie.Domain = maches[i].Groups["value"].Value;
                         break;
                     case "expires":

                         DateTime dt;

                         if (DateTime.TryParse(maches[i].Groups["value"].Value, out dt))
                         {
                             cookie.Expires = dt;
                         }
                         else
                         {
                             cookie.Expires = DateTime.Now.AddDays(2);
                         }
                         break;
                     case "path":
                         cookie.Path = maches[i].Groups["value"].Value;
                         break;
                     case "secure":
                         cookie.Secure = true;
                         break;
                     case "httponly":
                         cookie.HttpOnly = true;
                         break;
                 }
             }
             return cookie;


         }

         public static HttpCookie ToHttpCookie(this string rawCookie)
         {
             MatchCollection maches = rxCookieParts.Matches(rawCookie);

             HttpCookie cookie = new HttpCookie(maches[0].Groups["name"].Value, maches[0].Groups["value"].Value);

             for (int i = 1; i < maches.Count; i++)
             {
                 switch (maches[i].Groups["name"].Value.ToLower().Trim())
                 {
                     case "domain":
                         cookie.Domain = maches[i].Groups["value"].Value;
                         break;
                     case "expires":

                         DateTime dt;

                         if (DateTime.TryParse(maches[i].Groups["value"].Value, out dt))
                         {
                             cookie.Expires = dt;
                         }
                         else
                         {
                             cookie.Expires = DateTime.Now.AddDays(2);
                         }
                         break;
                     case "path":
                         cookie.Path = maches[i].Groups["value"].Value;
                         break;
                     case "secure":
                         cookie.Secure = true;
                         break;
                     case "httponly":
                         cookie.HttpOnly = true;
                         break;
                 }
             }
             return cookie;
         }

         private static KeyValuePair<string, string> SplitToPair(this string input)
         {
            string[]  parts= input.Split(new char[] {'='},StringSplitOptions.RemoveEmptyEntries);
            return new KeyValuePair<string, string>(parts[0],parts[1]);
         }

         private static string RemoveComma(Match match)
         {
             return match.Value.Replace(',', ' ');
         }
    }

}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜