首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CookieContainer错误?

CookieContainer错误?
EN

Stack Overflow用户
提问于 2009-06-26 06:41:42
回答 6查看 10.8K关注 0票数 17

我对CookieContainer如何处理域感到困惑,所以我创建了这个测试。这个测试显示cookieContainer不会为"example.com“返回任何cookie,但根据RFC的说法,它应该至少返回2个cookie。

这不是个bug吗?

如何让它工作?

下面是关于这个bug的讨论:

http://social.msdn.microsoft.com/Forums/en-US/ncl/thread/c4edc965-2dc2-4724-8f08-68815cf1dce6

代码语言:javascript
复制
<%@ Page Language="C#" %>

<%@ Import Namespace="System.Net" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
    CookieContainer getContainer()
    {
        CookieContainer result = new CookieContainer();

        Uri uri = new Uri("http://sub.example.com");
        string cookieH = @"Test1=val; domain=sub.example.com; path=/";
        result.SetCookies(uri, cookieH);

        cookieH = @"Test2=val; domain=.example.com; path=/";
        result.SetCookies(uri, cookieH);

        cookieH = @"Test3=val; domain=example.com; path=/";
        result.SetCookies(uri, cookieH);

        return result;
    }

    void Test()
    {
        CookieContainer cookie = getContainer();
        lblResult.Text += "<br>Total cookies count: " + cookie.Count + " &nbsp;&nbsp; expected: 3";

        Uri uri = new Uri("http://sub.example.com");
        CookieCollection coll = cookie.GetCookies(uri);
        lblResult.Text += "<br>For " + uri + " Cookie count: " + coll.Count + " &nbsp;&nbsp; expected: 2";

        uri = new Uri("http://other.example.com");
        coll = cookie.GetCookies(uri);
        lblResult.Text += "<br>For " + uri + " Cookie count: " + coll.Count + " &nbsp;&nbsp; expected: 2";

        uri = new Uri("http://example.com");
        coll = cookie.GetCookies(uri);
        lblResult.Text += "<br>For " + uri + " Cookie count: " + coll.Count + " &nbsp;&nbsp; expected: 2";

    }

    protected void Page_Load(object sender, EventArgs e)
    {
        Test();
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>CookieContainer Test Page</title>
</head>
<body>
    <form id="frmTest" runat="server">
    <asp:Label ID="lblResult" EnableViewState="false" runat="server"></asp:Label>
    </form>
</body>
</html>
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2009-10-08 12:24:51

我刚刚找到了这个bug的修复方法,并在这里讨论:http://dot-net-expertise.blogspot.com/2009/10/cookiecontainer-domain-handling-bug-fix.html

以下是解决方案:

  1. 不要使用.Add( Cookie),只使用.Add(Uri,cookie )方法。每次将cookie添加到容器时,或者在使用.GetCookie之前或系统使用容器之前,
  2. 都会调用BugFix_CookieDomain。

private void BugFix_CookieDomain(CookieContainer cookieContainer) { System.Type _ContainerType = typeof(CookieContainer);哈希表= (Hashtable)_ContainerType.InvokeMember("m_domainTable",System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance,null,cookieContainer,new object[] { });新密钥= ArrayList ArrayList(table.Keys);foreach (string keyObj in key ){ string key= (keyObj as string);if (key ==‘.){ string newKey = key.Remove(0,1);tablenewKey = tablekeyObj;}

票数 26
EN

Stack Overflow用户

发布于 2016-09-17 01:05:03

我已经为这个问题创建了一个修复程序,可以在Windows10/ UWP / .NET核心应用程序上运行。问题是CookieContainer的内部结构是不同的,但就像在.NET框架中一样糟糕。因此,被接受的解决方案不再有效。

但是,我并没有“修复”CookieContainer,而是编写了一个版本的GetCookies(),它通过一个字符串获取特定域的所有cookie,而不管它们的“安全”状态如何,也不管它们是否以点为前缀。您可以根据自己的需要对其进行修改,我会在将来的.NET核心发行版中实现它的版本。

代码语言:javascript
复制
using System.Collections.Generic;
using System.Reflection;

namespace System.Net
{

    /// <summary>
    /// Contains extensions for the <see cref="CookieContaner"/> class.
    /// </summary>
    public static class CookieContainerExtensions
    {

        /// <summary>
        /// Uses Reflection to get ALL of the <see cref="Cookie">Cookies</see> where <see cref="Cookie.Domain"/> 
        /// contains part of the specified string. Will return cookies for any subdomain, as well as dotted-prefix cookies. 
        /// </summary>
        /// <param name="cookieContainer">The <see cref="CookieContainer"/> to extract the <see cref="Cookie">Cookies</see> from.</param>
        /// <param name="domain">The string that contains part of the domain you want to extract cookies for.</param>
        /// <returns></returns>
        public static IEnumerable<Cookie> GetCookies(this CookieContainer cookieContainer, string domain)
        {
            var domainTable = GetFieldValue<dynamic>(cookieContainer, "_domainTable");
            foreach (var entry in domainTable)
            {
                string key = GetPropertyValue<string>(entry, "Key");

                if (key.Contains(domain))
                {
                    var value = GetPropertyValue<dynamic>(entry, "Value");

                    var internalList = GetFieldValue<SortedList<string, CookieCollection>>(value, "_list");
                    foreach (var li in internalList)
                    {
                        foreach (Cookie cookie in li.Value)
                        {
                            yield return cookie;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Gets the value of a Field for a given object instance.
        /// </summary>
        /// <typeparam name="T">The <see cref="Type"/> you want the value to be converted to when returned.</typeparam>
        /// <param name="instance">The Type instance to extract the Field's data from.</param>
        /// <param name="fieldName">The name of the Field to extract the data from.</param>
        /// <returns></returns>
        internal static T GetFieldValue<T>(object instance, string fieldName)
        {
            BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
            FieldInfo fi = instance.GetType().GetField(fieldName, bindFlags);
            return (T)fi.GetValue(instance);
        }

        /// <summary>
        /// Gets the value of a Property for a given object instance.
        /// </summary>
        /// <typeparam name="T">The <see cref="Type"/> you want the value to be converted to when returned.</typeparam>
        /// <param name="instance">The Type instance to extract the Property's data from.</param>
        /// <param name="propertyName">The name of the Property to extract the data from.</param>
        /// <returns></returns>
        internal static T GetPropertyValue<T>(object instance, string propertyName)
        {
            var pi = instance.GetType().GetProperty(propertyName);
            return (T)pi.GetValue(instance, null);
        }

    }

}
票数 1
EN

Stack Overflow用户

发布于 2009-07-31 19:23:39

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1047669

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档