Vin*_*bbe 7 c# system.web httpcookiecollection
在HttpCookieCollection.Get MSDN文档中,声明:
如果指定的cookie不存在,则此方法将创建具有该名称的新cookie.
这是真的,在调用时HttpContext.Request.Cookies或HttpContext.Response.Cookies从"真正的"Web服务器运行良好.
但是,这段代码:
HttpCookieCollection foo = new HttpCookieCollection();
HttpCookie cookie = foo.Get("foo");
Console.WriteLine(cookie != null);
Run Code Online (Sandbox Code Playgroud)
显示False(cookie为空).
如果HttpCookieCollection从Request.CookiesHTTP处理程序中检索,则不是这种情况.
知道这里有什么问题/是否需要任何其他设置?
我问这个是因为我在模拟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;
}
Run Code Online (Sandbox Code Playgroud)
它永远不会创建cookie,因为_response将为null(查看第一个'if'语句).即没有响应对象将新cookie发回,因此不会创建它.
响应对象是一个HttpResponse对象,它被传递给内部构造函数(因此构造函数不可用).
我个人从不喜欢Get方法对HttpCookieCollection的作用方式; 它违反了Command-Query分离原则:提问不应该改变答案.
我建议您通过检查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;
}
}
Run Code Online (Sandbox Code Playgroud)