最近用ActionFilter给REST Api加入本地缓存功能,在OnActionExecutedAsync重写中,需要将缓存对象的内容以byte[]的形式存入缓存,并缓存Etag、ContentType信息。

而在该方法中以

var content = await responseContent.ReadAsByteArrayAsync().ConfigureAwait(false);

获取byte[]形式的响应内容时,提示Cannot access a closed Stream.即认为响应流已关闭,但其实上下文中并未显示关闭Stream对象或以using操作流对象。

 

为了验证,同样的代码在一个新建的web api2项目中使用,则能够正常获取响应内容,查了很久未果。。。。

以下是上下文代码:

 1 public override async Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
 2         {
 3             if (actionExecutedContext.ActionContext.Response == null
 4                 || !actionExecutedContext.ActionContext.Response.IsSuccessStatusCode)
 5                 return;
 6             if (!IsCachingAllowed(actionExecutedContext.ActionContext))
 7                 return;
 8             var cacheTime = CacheTimeQuery.Execute(DateTime.Now);
 9             if (cacheTime.AbsoluteExpiration > DateTime.Now)
10             {
11                 var httpConfig = actionExecutedContext.Request.GetConfiguration();
12                 var config = httpConfig.RestCacheConfiguration();
13                 var cacheKeyGenerator = config.GetCacheKeyGenerator(CacheKeyGenerator);
14                 var responseMediaType = actionExecutedContext.Request.Properties[CurrentRequestMediaType] as MediaTypeHeaderValue
15                     ?? GetExpectedMediaType(httpConfig, actionExecutedContext.ActionContext);
16                 var cachekey = cacheKeyGenerator.MakeCacheKey(actionExecutedContext.ActionContext, responseMediaType);
17                 if (!string.IsNullOrWhiteSpace(cachekey) && !(_restCache.Contains(cachekey)))
18                 {
19                     SetEtag(actionExecutedContext.Response, CreateEtag(actionExecutedContext, cachekey, cacheTime));
20                     var responseContent = actionExecutedContext.Response.Content;
21                     if (responseContent != null)
22                     {
23                         var baseKey = config.MakeBaseCachekey(actionExecutedContext.ActionContext.ControllerContext.ControllerDescriptor.ControllerType.FullName, actionExecutedContext.ActionContext.ActionDescriptor.ActionName);
24                         var contentType = responseContent.Headers.ContentType;
25                         string etag = actionExecutedContext.Response.Headers.ETag.Tag;
26                         try
27                         {
28                             var content = await responseContent.ReadAsByteArrayAsync().ConfigureAwait(false);
29                             responseContent.Headers.Remove("Content-Length");
30                             _restCache.Add(baseKey, string.Empty, cacheTime.AbsoluteExpiration);
31                             _restCache.Add(cachekey, content, cacheTime.AbsoluteExpiration, baseKey);
32                             _restCache.Add(cachekey + Constants.ContentTypeKey,
33                                 contentType,
34                                 cacheTime.AbsoluteExpiration, baseKey);
35                             _restCache.Add(cachekey + Constants.EtagKey,
36                                 etag,
37                                 cacheTime.AbsoluteExpiration, baseKey);
38                         }
39                         catch (Exception exp)
40                         {
41                             //捕捉到Cannot access a closed Stream.
42                             throw;
43                         }
44                     }
45                 }
46             }
47             ApplyCacheHeaders(actionExecutedContext.ActionContext.Response, cacheTime);
48         }
View Code

相关文章:

  • 2022-12-23
  • 2021-06-07
  • 2021-10-29
  • 2021-06-08
  • 2022-12-23
  • 2021-09-26
  • 2022-02-19
猜你喜欢
  • 2021-12-01
  • 2022-12-23
  • 2022-12-23
  • 2022-01-07
  • 2022-12-23
  • 2022-12-23
  • 2021-09-15
相关资源
相似解决方案