C# 为什么从手动实例化的对象(而不是当前HttpContext)调用HttpCookieCollection.Get时返回null
报告中指出: 如果命名cookie不存在,此方法将创建一个新cookie 用那个名字 这是正确的,在从“真实”web服务器调用C# 为什么从手动实例化的对象(而不是当前HttpContext)调用HttpCookieCollection.Get时返回null,c#,system.web,httpcookiecollection,C#,System.web,Httpcookiecollection,报告中指出: 如果命名cookie不存在,此方法将创建一个新cookie 用那个名字 这是正确的,在从“真实”web服务器调用HttpContext.Request.Cookies或HttpContext.Response.Cookies时效果良好 但是,该代码: HttpCookieCollection foo = new HttpCookieCollection(); HttpCookie cookie = foo.Get("foo"); Console.WriteL
HttpContext.Request.Cookies
或HttpContext.Response.Cookies
时效果良好
但是,该代码:
HttpCookieCollection foo = new HttpCookieCollection();
HttpCookie cookie = foo.Get("foo");
Console.WriteLine(cookie != null);
显示False
(cookie
为空)
如果从HTTP处理程序中的Request.Cookies
检索HttpCookieCollection
,则情况并非如此
你知道这里出了什么问题/是否需要其他设置吗
我这样问是因为我在编写单元测试时模拟了HttpContextBase,所以没有提供“真实”的上下文
感谢您的帮助如果查看HttpCookieCollection.Get(string)的代码,您将看到如下内容:
public HttpCookie Get(string name)
{
HttpCookie cookie = (HttpCookie) this.BaseGet(name);
if (cookie == null && this._response != null)
{
cookie = new HttpCookie(name);
this.AddCookie(cookie, true);
this._response.OnCookieAdd(cookie);
}
if (cookie != null)
this.EnsureKeyValidated(name, cookie.Value);
return cookie;
}
它从不创建cookie,因为_响应将为null(请看第一条“if”语句)。i、 e.没有可将新cookie发送回的响应对象,因此它不会创建新cookie
响应对象是一个HttpResponse对象,它被传递给内部构造函数(因此构造函数对您不可用)
我个人从来不喜欢Get方法对HttpCookieCollection的作用方式;这违反了原则:提出问题不应改变答案
我建议您通过检查AllKeys属性来检查cookie是否存在;如果不存在,则显式创建cookie并将其添加到集合中。否则,如果您知道密钥存在,请继续获取现有条目。然后,您的生产代码和单元测试应该正常运行
创建一个helper或extension方法来代替Get,以确保无论是单元测试还是正常运行,它的行为都符合您的预期,这可能是一个好主意:
public static class HttpCookieCollectionExtensions
{
public static HttpCookie GetOrCreateCookie(this HttpCookieCollection collection, string name)
{
// Check if the key exists in the cookie collection. We check manually so that the Get
// method doesn't implicitly add the cookie for us if it's not found.
var keyExists = collection.AllKeys.Any(key => string.Equals(name, key, StringComparison.OrdinalIgnoreCase));
if (keyExists) return collection.Get(name);
// The cookie doesn't exist, so add it to the collection.
var cookie = new HttpCookie(name);
collection.Add(cookie);
return cookie;
}
}