为什么HttpCookieCollection.当从手动实例化的对象(而不是从当前HttpContext)调用时,Get
本文关键字:HttpContext Get 调用 HttpCookieCollection 实例化 为什么 对象 | 更新日期: 2023-09-27 18:12:30
在HttpCookieCollection中。获取MSDN文档,说明:
如果指定的cookie不存在,这个方法创建一个新的cookie用那个名字。
这是真的,并且在从"真实的"web服务器调用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,因为_response将为null(查看第一个'if'语句)。也就是说,没有响应对象来发送新的cookie,所以它不会创建它。
响应对象是一个HttpResponse对象,它被传递给内部构造函数(所以构造函数对你来说是不可用的)。
我个人从来不喜欢Get方法在HttpCookieCollection上的行为方式;它违反了命令-查询分离原则:提出问题不应该改变答案。
我建议你通过检查AllKeys属性来检查cookie是否存在;如果不存在,则显式地创建该cookie并将其添加到集合中。否则,如果知道键存在,则继续获取现有条目。然后你的产品代码和单元测试应该正常运行。
这可能是一个好主意,创建一个助手或扩展方法来代替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;
}
}