MVC 3 RTM。我有一个返回文件的动作(image / jpeg)。我试图为一个文件设置ETag没有成功(etag没有通过标题)。我已经尝试了Response.Cache.SetETag和Response.AppenderHeader。如果我添加自己的自定义标头标签,它按预期工作,它似乎是我无法设置的ETag。
这是来源。
[HttpGet, OutputCache(Location= OutputCacheLocation.Client, VaryByParam="userId", Duration=3600, NoStore=true)]
public ActionResult GetImage(string userId)
{
byte[] result;
using (var client = new WebClient())
{
client.Credentials = CredentialCache.DefaultCredentials;
result = client.DownloadData(string.Format(IntranetUrl, userId));
}
Response.Cache.SetETag("00amyWGct0y_ze4lIsj2Mw");
//or Response.AppendHeader("ETag", "00amyWGct0y_ze4lIsj2Mw");
Response.AppendHeader("MyHeader", "HelloWorld");
return File(result, "image/jpeg");
}
这是资源请求/响应:
> Request
> URL:http://localhost/MyApp/Employee.mvc/GetImage?userId=myUserId
> Request Method:GET Status Code:200 OK
> Request Headers Accept:*/*
> Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
> Accept-Encoding:gzip,deflate,sdch
> Accept-Language:en-US,en;q=0.8
> Cache-Control:max-age=0
> Connection:keep-alive
> Cookie:ASP.NET_SessionId=mySessionId
> Host:localhost
> Referer:http://localhost/MyApp/Employee/Review/24/Index
> User-Agent:Mozilla/5.0 (Windows; U;
> Windows NT 5.1; en-US)
> AppleWebKit/534.13 (KHTML, like Gecko)
> Chrome/9.0.597.98 Safari/534.13 Query
> String Parameters userId:myUserId
> Response Headers
> Cache-Control:private, no-store,
> max-age=3600 Content-Length:1428
> Content-Type:image/jpeg Date:Thu, 17
> Feb 2011 15:45:30 GMT Expires:Thu, 17
> Feb 2011 16:45:29 GMT
> Last-Modified:Thu, 17 Feb 2011
> 15:45:29 GMT MyHeader:HelloWorld
> Server:Microsoft-IIS/5.1
> X-AspNet-Version:4.0.30319
> X-AspNetMvc-Version:3.0
> X-Powered-By:ASP.NET
我已经删除了所有代码,但仍然没有...
动作:
public FileETagActionResult GetImage()
{
return new FileETagActionResult();
}
的ActionResult:
public class FileETagActionResult : ActionResult
{
public override void ExecuteResult(ControllerContext context)
{
byte[] result;
using (var client = new WebClient())
{
result = client.DownloadData("http://myintranet/images/logo.png");
}
var hash = MD5.Create().ComputeHash(result);
string etag = String.Format("\"{0}\"", Convert.ToBase64String(hash));
TimeSpan expireTs = TimeSpan.FromDays(5);
context.HttpContext.Response.Cache.SetCacheability(HttpCacheability.Private);
context.HttpContext.Response.Cache.SetETag(etag);
context.HttpContext.Response.Cache.SetExpires(DateTime.Now.AddDays(5));
context.HttpContext.Response.Cache.SetMaxAge(expireTs);
context.HttpContext.Response.ContentType = "image/png";
context.HttpContext.Response.BinaryWrite(result);
}
}
答案 0 :(得分:10)
如果您使用HttpCacheability.Private
,ETag将被禁止。
您可以找到有关此question
的更多信息如果您将其更改为HttpCacheability.ServerAndPrivate
,则应该
答案 1 :(得分:1)
BZ,
尝试在ExcecuteResult覆盖中执行此操作,因为在ActionResult被抛回时太晚了(我快速打开的项目示例,编辑以适应):
public override void ExecuteResult(ControllerContext context)
{
var textWriter = new StringWriter();
var viewResult = GetViewResult(textWriter);
viewResult.ExecuteResult(context);
var result = textWriter.ToString()
.RegexReplace("<script.*?>", string.Empty)
.Replace("</script>", string.Empty);
//#if RELEASE
//context.HttpContext.Response.CacheControl = "Public";
//context.HttpContext.Response.Expires = CacheDuration;
string version = "1.0"; //your dynamic version number
HttpCachePolicyBase cache = context.HttpContext.Response.Cache;
TimeSpan expireTs = TimeSpan.FromDays(CacheDuration);
cache.SetCacheability(HttpCacheability.Private);
cache.SetETag(version);
cache.SetExpires(DateTime.Now.Add(expireTs));
cache.SetMaxAge(expireTs);
//#endif
context.HttpContext.Response.ContentType = "text/javascript";
context.HttpContext.Response.Write(result);
}